diff --git a/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java b/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java index 5e49e908..6a12ea02 100644 --- a/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java +++ b/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java @@ -28,6 +28,8 @@ public class InterproceduralOverrideAssignment extends SceneTransformer implemen private final AbstractMergeConflictDefinition definition; private final FlowSet left; private final FlowSet right; + private FlowSet abstraction; + private final Logger logger; public InterproceduralOverrideAssignment(AbstractMergeConflictDefinition definition) { @@ -36,6 +38,7 @@ public InterproceduralOverrideAssignment(AbstractMergeConflictDefinition definit this.conflicts = new HashSet<>(); this.left = new ArraySparseSet<>(); this.right = new ArraySparseSet<>(); + this.abstraction = new ArraySparseSet<>(); this.traversedMethods = new ArrayList<>(); this.pointsToAnalysis = Scene.v().getPointsToAnalysis(); @@ -70,12 +73,11 @@ public void configureEntryPoints() { protected void internalTransform(String s, Map map) { List methods = Scene.v().getEntryPoints(); - methods.forEach(sootMethod -> traverse(sootMethod, Statement.Type.IN_BETWEEN)); + methods.forEach(sootMethod -> traverse(this.abstraction, sootMethod, Statement.Type.IN_BETWEEN)); - //logger.log(Level.INFO, () -> String.format("%s", "traversedMethods: " + this.traversedMethods)); logger.log(Level.INFO, () -> String.format("%s", "CONFLICTS: " + getConflicts())); - /* left.forEach(dataFlowAbstraction -> { + /*left.forEach(dataFlowAbstraction -> { String leftStmt = String.format("%s", "LEFT: " + dataFlowAbstraction.getStmt()); logger.log(Level.INFO, leftStmt); }); @@ -94,10 +96,10 @@ protected void internalTransform(String s, Map map) { * Initially it receives the value IN_BETWEEN but changes if the call to the current method (sootMethod) has been marked as SOURCE or SINK. * The remaining statements of the current method that have no markup will be marked according to the flowChangeTag. */ - private void traverse(SootMethod sootMethod, Statement.Type flowChangeTag) { - System.out.println(sootMethod); + private FlowSet traverse(FlowSet in, SootMethod sootMethod, Statement.Type flowChangeTag) { + //System.out.println(sootMethod); if (this.traversedMethods.contains(sootMethod) || sootMethod.isPhantom()) { - return; + return null; } this.traversedMethods.add(sootMethod); @@ -105,18 +107,19 @@ private void traverse(SootMethod sootMethod, Statement.Type flowChangeTag) { Body body = retrieveActiveBodySafely(sootMethod); if (body != null) { + body.getUnits().forEach(unit -> { if (isTagged(flowChangeTag, unit)) { - runAnalysisWithTaggedUnit(sootMethod, flowChangeTag, unit); + runAnalysisWithTaggedUnit(in, sootMethod, flowChangeTag, unit); } else { - runAnalysisWithBaseUnit(sootMethod, flowChangeTag, unit); + runAnalysisWithBaseUnit(in, sootMethod, flowChangeTag, unit); } }); } this.traversedMethods.remove(sootMethod); - + return in; } private Body retrieveActiveBodySafely(SootMethod sootMethod) { @@ -127,12 +130,14 @@ private Body retrieveActiveBodySafely(SootMethod sootMethod) { } } - private void runAnalysisWithTaggedUnit(SootMethod sootMethod, Statement.Type flowChangeTag, Unit unit) { - runAnalysis(sootMethod, flowChangeTag, unit, true); + private FlowSet runAnalysisWithTaggedUnit(FlowSet in, SootMethod sootMethod, + Statement.Type flowChangeTag, Unit unit) { + return runAnalysis(in, sootMethod, flowChangeTag, unit, true); } - private void runAnalysisWithBaseUnit(SootMethod sootMethod, Statement.Type flowChangeTag, Unit unit) { - runAnalysis(sootMethod, flowChangeTag, unit, false); + private FlowSet runAnalysisWithBaseUnit(FlowSet in, SootMethod sootMethod, + Statement.Type flowChangeTag, Unit unit) { + return runAnalysis(in, sootMethod, flowChangeTag, unit, false); } /** @@ -144,7 +149,8 @@ private void runAnalysisWithBaseUnit(SootMethod sootMethod, Statement.Type flowC * The remaining statements of the current method that have no markup will be marked according to the flowChangeTag. * @param tagged Identifies whether the unit to be analyzed has been tagged. If false the unit is base, if true the unit is left or right. */ - private void runAnalysis(SootMethod sootMethod, Statement.Type flowChangeTag, Unit unit, boolean tagged) { + private FlowSet runAnalysis(FlowSet in, SootMethod sootMethod, Statement.Type flowChangeTag, + Unit unit, boolean tagged) { /* Are there other possible cases? Yes, see follow links: https://soot-build.cs.uni-paderborn.de/public/origin/develop/soot/soot-develop/jdoc/soot/jimple/Stmt.html https://github.com/PAMunb/JimpleFramework/blob/d585caefa8d5f967bfdbeb877346e0ff316e0b5e/src/main/rascal/lang/jimple/core/Syntax.rsc#L77-L95 @@ -157,15 +163,15 @@ private void runAnalysis(SootMethod sootMethod, Statement.Type flowChangeTag, Un AssignStmt assignStmt = (AssignStmt) unit; if (assignStmt.containsInvokeExpr()) { - executeCallGraph(flowChangeTag, unit); + return executeCallGraph(in.clone(), flowChangeTag, unit); } if (tagged) { Statement stmt = getStatementAssociatedWithUnit(sootMethod, unit, flowChangeTag); // logger.log(Level.INFO, () -> String.format("%s", "stmt: " + stmt.toString())); - gen(stmt); + gen(in, stmt); } else { - kill(unit); + kill(in, unit); } /* Check case: x = foo() + bar() @@ -186,19 +192,41 @@ In this case, this condition will be executed for the call to the foo() method a For builders, InvokeExpression is an instance of InvokeSpecial */ } else if (unit instanceof InvokeStmt) { - executeCallGraph(flowChangeTag, unit); + return executeCallGraph(in, flowChangeTag, unit); } + + return in; } - private void executeCallGraph(Statement.Type flowChangeTag, Unit unit) { + private FlowSet executeCallGraph(FlowSet in, Statement.Type flowChangeTag, Unit unit) { CallGraph callGraph = Scene.v().getCallGraph(); Iterator edges = callGraph.edgesOutOf(unit); + List> flowSetList = new ArrayList>(); + FlowSet flowSetUnion = new ArraySparseSet<>(); + while (edges.hasNext()) { Edge e = edges.next(); Statement stmt = getStatementAssociatedWithUnit(e.getTgt().method(), unit, flowChangeTag); - traverse(e.getTgt().method(), stmt.getType()); + + FlowSet traverseResult = traverse(in.clone(), e.getTgt().method(), stmt.getType()); + flowSetList.add(traverseResult); + + /* System.out.println("------traverseResult--------"); + System.out.println("METHOD: " + e.getTgt().method()); + traverseResult.forEach(item -> System.out.println(item.getStmt())); + System.out.println("------traverseResult--------");*/ } + + flowSetList.forEach(flowSet -> flowSetUnion.union(flowSet)); + + System.out.println("--------------flowSetUnion--------------"); + flowSetUnion.forEach(item -> System.out.println(item.getStmt())); + System.out.println("--------------in--------------"); + in.forEach(item -> System.out.println(item.getStmt())); + + return flowSetUnion; + } private boolean isTagged(Statement.Type flowChangeTag, Unit unit) { @@ -219,21 +247,20 @@ private boolean isInLeftAndRightStatementFlow(Statement.Type flowChangeTag) { // TODO add depth to InstanceFieldRef and StaticFieldRef... // TODO rename Statement. (UnitWithExtraInformations) - private void gen(Statement stmt) { + private void gen(FlowSet in, Statement stmt) { if (isLeftStatement(stmt)) { checkConflict(stmt, right); - addStmtToList(stmt, left); } else if (isRightStatement(stmt)) { checkConflict(stmt, left); - addStmtToList(stmt, right); } else if (isLefAndRightStatement(stmt)) { addConflict(stmt, stmt); - addStmtToList(stmt, left); - addStmtToList(stmt, right); + //addStmtToList(stmt, left); + } + addStmtToList(stmt, in); } private void addStmtToList(Statement stmt, FlowSet rightOrLeftList) { @@ -266,9 +293,9 @@ private void addConflict(Statement left, Statement right) { } - private void kill(Unit unit) { - unit.getDefBoxes().forEach(valueBox -> removeAll(valueBox, left)); - unit.getDefBoxes().forEach(valueBox -> removeAll(valueBox, right)); + private void kill(FlowSet in, Unit unit) { + unit.getDefBoxes().forEach(valueBox -> removeAll(valueBox, in)); + //unit.getDefBoxes().forEach(valueBox -> removeAll(valueBox, right)); } private void removeAll(ValueBox valueBox, FlowSet rightOrLeftList) {