Commit 8bad6135 authored by Carlos Galindo's avatar Carlos Galindo
Browse files

Generate total definition dependencies.

parent 6ce682af
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -70,6 +70,10 @@ public class JSysCFG extends ESCFG {
        return findLastVarActionsFrom(usage, VariableAction::isDefinition);
    }

    public List<VariableAction> findLastTotalDefinitionOf(VariableAction action, String member) {
        return findLastVarActionsFrom(action, def -> def.isDefinition() && def.asDefinition().isTotallyDefinedMember(member));
    }

    /** Given a definition of a given member, locate all definitions of the same object until a definition
     *  containing the given member is found (not including that last one). If the member is found in the
     *  given definition, it will return a list with only the given definition. */
+32 −7
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ package es.upv.mist.slicing.graphs.jsysdg;

import es.upv.mist.slicing.arcs.pdg.FlowDependencyArc;
import es.upv.mist.slicing.arcs.pdg.ObjectFlowDependencyArc;
import es.upv.mist.slicing.arcs.pdg.TotalDefinitionDependenceArc;
import es.upv.mist.slicing.graphs.exceptionsensitive.ESPDG;
import es.upv.mist.slicing.graphs.pdg.PDG;
import es.upv.mist.slicing.nodes.GraphNode;
@@ -54,6 +55,12 @@ public class JSysPDG extends ESPDG {
        addEdge(usage.getObjectTree().getNodeFor(member), statement, new FlowDependencyArc(member));
    }

    protected void addTotalDefinitionDependencyArc(VariableAction totalDefinition, VariableAction target, String member) {
        addEdge(totalDefinition.getObjectTree().getNodeFor(member),
                target.getObjectTree().getNodeFor(member),
                new TotalDefinitionDependenceArc());
    }

    protected GraphNode<?> graphNodeOf(VariableAction action) {
        if (action instanceof VariableAction.Movable)
            return ((VariableAction.Movable) action).getRealNode();
@@ -74,8 +81,18 @@ public class JSysPDG extends ESPDG {
        protected void buildDataDependency() {
            addSyntheticNodesToPDG();
            JSysCFG jSysCFG = (JSysCFG) cfg;
            for (GraphNode<?> node : vertexSet())
                for (VariableAction varAct : node.getVariableActions())
            for (GraphNode<?> node : vertexSet()) {
                for (VariableAction varAct : node.getVariableActions()) {
                    // Total definition dependence
                    if (varAct.isUsage() || varAct.isDefinition()) {
                        // root
                        jSysCFG.findLastTotalDefinitionOf(varAct, "-root-").forEach(totalDef -> addTotalDefinitionDependencyArc(totalDef, varAct, "-root-"));
                        // members
                        for (String member : varAct.getObjectTree().nameIterable()) {
                            jSysCFG.findLastTotalDefinitionOf(varAct, member).forEach(totalDef -> addTotalDefinitionDependencyArc(totalDef, varAct, member));
                        }
                    }
                    // Object flow, flow and declaration-definition dependencies
                    if (varAct.isUsage()) {
                        if (varAct.isPrimitive())
                            jSysCFG.findLastDefinitionOfPrimitive(varAct).forEach(def -> addFlowDependencyArc(def, varAct));
@@ -94,6 +111,8 @@ public class JSysPDG extends ESPDG {
                                jSysCFG.findNextObjectDefinitionsFor(varAct, member).forEach(def -> addObjectFlowDependencyArc(varAct, member, def));
                    }
                }
            }
        }

        @Override
        protected void expandCalls() {}
@@ -133,12 +152,10 @@ public class JSysPDG extends ESPDG {
                        addControlDependencyArc(node, parentNode);
                    }
                    // Extract the member nodes contained within the object tree
                    if (va.getObjectTree().getMemberNode() != null)
                        insertMemberNode(va.getObjectTree().getMemberNode(), parentNode);
                    for (MemberNode memberNode : va.getObjectTree().nodeIterable()) {
                        if (memberNode.getParent() == null)
                            memberNode.setParent(parentNode);
                        assert containsVertex(memberNode.getParent());
                        addVertex(memberNode);
                        addControlDependencyArc(memberNode.getParent(), memberNode);
                        insertMemberNode(memberNode, parentNode);
                    }
                }
                assert callNodeStack.isEmpty();
@@ -148,5 +165,13 @@ public class JSysPDG extends ESPDG {
                    .flatMap(node -> node.getVariableActions().stream())
                    .forEach(va -> va.applyPDGTreeConnections(JSysPDG.this));
        }

        protected void insertMemberNode(MemberNode memberNode, GraphNode<?> parentNode) {
            if (memberNode.getParent() == null)
                memberNode.setParent(parentNode);
            assert containsVertex(memberNode.getParent());
            addVertex(memberNode);
            addControlDependencyArc(memberNode.getParent(), memberNode);
        }
    }
}
+18 −3
Original line number Diff line number Diff line
@@ -376,6 +376,8 @@ public abstract class VariableAction {
    public static class Definition extends VariableAction {
        /** The value to which the variable has been defined. */
        protected final Expression expression;
        /** The members of the object tree that are total definitions. */
        protected String totallyDefinedMember;

        public Definition(Expression variable, String realName, GraphNode<?> graphNode) {
            this(variable, realName, graphNode, (Expression) null);
@@ -395,6 +397,17 @@ public abstract class VariableAction {
            this.expression = expression;
        }

        public void setTotallyDefinedMember(String totallyDefinedMember) {
            this.totallyDefinedMember = Objects.requireNonNull(totallyDefinedMember);
        }

        public boolean isTotallyDefinedMember(String member) {
            if (totallyDefinedMember == null)
                return false;
            return totallyDefinedMember.equals(member) || totallyDefinedMember.startsWith(member)
                    || ObjectTree.removeRoot(totallyDefinedMember).startsWith(ObjectTree.removeRoot(member));
        }

        /** @see #expression */
        public Expression getExpression() {
            return expression;
@@ -658,7 +671,9 @@ public abstract class VariableAction {
        }

        private MemberNode getNodeForNonRoot(String members) {
            if (members.contains(".")) {
            if (members.isEmpty()) {
                return memberNode;
            } else if (members.contains(".")) {
                int firstDot = members.indexOf('.');
                String first = members.substring(0, firstDot);
                String rest = members.substring(firstDot + 1);
@@ -766,8 +781,8 @@ public abstract class VariableAction {

        public static String removeRoot(String fieldWithRoot) {
            Matcher matcher = FIELD_SPLIT.matcher(fieldWithRoot);
            if (matcher.matches() && matcher.group("fields") != null)
                return matcher.group("fields");
            if (matcher.matches())
                return matcher.group("fields") != null ? matcher.group("fields") : "";
            throw new IllegalArgumentException("Field should be of the form <obj>.<field>, <Type>.this.<field>, where <obj> may not contain dots.");
        }

+20 −8
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act
        acceptAction(ACTIVE_EXCEPTION_VARIABLE, DEFINITION);
        definitionStack.pop();
        var fields = ClassGraph.getInstance().generateObjectTreeFor(n.getExpression().calculateResolvedType().asReferenceType());
        graphNode.getVariableActions().get(graphNode.getVariableActions().size() - 1).getObjectTree().addAll(fields);
        getLastDefinition().getObjectTree().addAll(fields);
        new ExpressionObjectTreeFinder(graphNode).locateAndMarkTransferenceToRoot(n.getExpression(), -1);
    }

@@ -236,13 +236,15 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act
                    definitionStack.push(n.getValue());
                    if (!realName.contains(".")) {
                        acceptAction(nameExpr, realName, DEFINITION);
                        VariableAction.Definition def = getLastDefinition();
                        def.setTotallyDefinedMember(realName);
                        realNameWithoutRootList.add("");
                    } else {
                        String root = ObjectTree.removeFields(realName);
                        acceptAction(root, DEFINITION);
                        List<VariableAction> list = graphNode.getVariableActions();
                        VariableAction def = list.get(graphNode.getVariableActions().size() - 1);
                        VariableAction.Definition def = getLastDefinition();
                        def.getObjectTree().addField(realName);
                        def.setTotallyDefinedMember(realName);
                        realNameWithoutRootList.add(realName);
                    }
                    definitionStack.pop();
@@ -269,8 +271,8 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act
                    definitionStack.push(n.getValue());
                    acceptAction(root, DEFINITION);
                    definitionStack.pop();
                    List<VariableAction> list = graphNode.getVariableActions();
                    VariableAction def = list.get(graphNode.getVariableActions().size() - 1);
                    VariableAction.Definition def = getLastDefinition();
                    def.setTotallyDefinedMember(realName);
                    def.getObjectTree().addField(realName);
                    realNameWithoutRootList.add(ObjectTree.removeRoot(realName));
                }
@@ -281,9 +283,8 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act
                }
            }, null);
            assert realNameWithoutRootList.size() == 1;
            List<VariableAction> list = graphNode.getVariableActions();
            ExpressionObjectTreeFinder finder = new ExpressionObjectTreeFinder(graphNode);
            finder.handleAssignExpr(n, list.get(graphNode.getVariableActions().size() - 1), realNameWithoutRootList.get(0));
            finder.handleAssignExpr(n, getLastDefinition(), realNameWithoutRootList.get(0));
        }
    }

@@ -314,7 +315,11 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act
            acceptAction(v.getNameAsString(), DECLARATION);
            v.getInitializer().ifPresent(init -> {
                init.accept(this, action);
                acceptActionNullDefinition(v.getNameAsString());
                definitionStack.push(init);
                acceptAction(v.getNameAsString(), DEFINITION);
                definitionStack.pop();
                if (v.getType().isClassOrInterfaceType())
                    getLastDefinition().setTotallyDefinedMember(v.getNameAsString());
            });
            v.accept(this, action);
        }
@@ -330,6 +335,8 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act
            definitionStack.push(init);
            acceptAction(realName, DEFINITION);
            definitionStack.pop();
            if (v.getType().isClassOrInterfaceType())
                getLastDefinition().setTotallyDefinedMember(realName);
            v.accept(this, action);
        }
    }
@@ -542,4 +549,9 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act
        if (lastRootAction != null)
            graphNode.variableActions.add(lastRootAction);
    }

    protected VariableAction.Definition getLastDefinition() {
        List<VariableAction> list = graphNode.getVariableActions();
        return ((VariableAction.Definition) list.get(list.size() - 1));
    }
}