X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FAnalysis%2FSSJava%2FLocationInference.java;h=1294cf85604dc57a6de25f6de0671198f722db13;hb=78a14d01d4b27a3e6e5f42c3bdb382a708426e96;hp=7d7ad44ed3e7a60f4c9981c4fb71a77e229f970a;hpb=817946aa52410328fc358fd438115b06cbe4e1db;p=IRC.git diff --git a/Robust/src/Analysis/SSJava/LocationInference.java b/Robust/src/Analysis/SSJava/LocationInference.java index 7d7ad44e..1294cf85 100644 --- a/Robust/src/Analysis/SSJava/LocationInference.java +++ b/Robust/src/Analysis/SSJava/LocationInference.java @@ -46,6 +46,7 @@ import IR.Tree.SubBlockNode; import IR.Tree.SwitchStatementNode; import IR.Tree.TertiaryNode; import IR.Tree.TreeNode; +import Util.Pair; public class LocationInference { @@ -88,6 +89,8 @@ public class LocationInference { public static final Descriptor TOPDESC = new NameDescriptor(TOPLOC); + LocationInfo curMethodInfo; + boolean debug = true; public LocationInference(SSJavaAnalysis ssjava, State state) { @@ -271,7 +274,7 @@ public class LocationInference { // dependency in the call graph methodDescriptorsToVisitStack.clear(); - descriptorListToAnalyze.removeFirst(); + // descriptorListToAnalyze.removeFirst(); Set methodDescriptorToVistSet = new HashSet(); methodDescriptorToVistSet.addAll(descriptorListToAnalyze); @@ -290,6 +293,7 @@ public class LocationInference { new SSJavaLattice(SSJavaAnalysis.TOP, SSJavaAnalysis.BOTTOM); MethodLocationInfo methodInfo = new MethodLocationInfo(md); + curMethodInfo = methodInfo; System.out.println(); System.out.println("SSJAVA: Inferencing the lattice from " + md); @@ -474,28 +478,36 @@ public class LocationInference { VarDescriptor varDesc = (VarDescriptor) srcNodeTuple.get(0); classDesc = varDesc.getType().getClassDesc(); } - extractRelationFromFieldFlows(classDesc, srcNode, dstNode, 1); - } else if (srcNodeTuple.size() == 1 || dstNodeTuple.size() == 1) { - // for the method lattice, we need to look at the first element of - // NTuple - // in this case, take a look at connected nodes at the local level - addRelationToLattice(md, methodLattice, methodInfo, srcNode, dstNode); } else { - - if (!srcNode.getDescTuple().get(0).equals(dstNode.getDescTuple().get(0))) { - // in this case, take a look at connected nodes at the local level - addRelationToLattice(md, methodLattice, methodInfo, srcNode, dstNode); - } else { - Descriptor srcDesc = srcNode.getDescTuple().get(0); - Descriptor dstDesc = dstNode.getDescTuple().get(0); - recursivelyAddCompositeRelation(md, fg, methodInfo, srcNode, dstNode, srcDesc, - dstDesc); - // recursiveAddRelationToLattice(1, md, srcNode, dstNode); - } + // value flow between local var - local var or local var - field + addRelationToLattice(md, methodLattice, methodInfo, srcNode, dstNode); } + // else if (srcNodeTuple.size() == 1 || dstNodeTuple.size() == 1) { + // // for the method lattice, we need to look at the first element of + // // NTuple + // // in this case, take a look at connected nodes at the local level + // addRelationToLattice(md, methodLattice, methodInfo, srcNode, + // dstNode); + // } else { + // if + // (!srcNode.getDescTuple().get(0).equals(dstNode.getDescTuple().get(0))) + // { + // // in this case, take a look at connected nodes at the local level + // addRelationToLattice(md, methodLattice, methodInfo, srcNode, + // dstNode); + // } else { + // Descriptor srcDesc = srcNode.getDescTuple().get(0); + // Descriptor dstDesc = dstNode.getDescTuple().get(0); + // recursivelyAddCompositeRelation(md, fg, methodInfo, srcNode, + // dstNode, srcDesc, + // dstDesc); + // // recursiveAddRelationToLattice(1, md, srcNode, dstNode); + // } + // } + } } } @@ -686,7 +698,9 @@ public class LocationInference { CompositeLocation inferLoc1 = generateInferredCompositeLocation(methodInfo, tuple1); CompositeLocation inferLoc2 = generateInferredCompositeLocation(methodInfo, tuple2); - addRelation(methodLattice, methodInfo, inferLoc1, inferLoc2); + // addRelation(methodLattice, methodInfo, inferLoc1, inferLoc2); + + addFlowGraphEdge(mdCaller, argDescTuple1, argDescTuple2); } @@ -702,35 +716,52 @@ public class LocationInference { private CompositeLocation generateInferredCompositeLocation(MethodLocationInfo methodInfo, NTuple tuple) { + // System.out.println("@@@@@generateInferredCompositeLocation=" + tuple); + // System.out.println("generateInferredCompositeLocation=" + tuple + " 0=" + // + tuple.get(0).getLocDescriptor()); // first, retrieve inferred location by the local var descriptor CompositeLocation inferLoc = new CompositeLocation(); CompositeLocation localVarInferLoc = methodInfo.getInferLocation(tuple.get(0).getLocDescriptor()); + localVarInferLoc.get(0).setLocDescriptor(tuple.get(0).getLocDescriptor()); + for (int i = 0; i < localVarInferLoc.getSize(); i++) { inferLoc.addLocation(localVarInferLoc.get(i)); } + // System.out.println("@@@@@localVarInferLoc=" + localVarInferLoc); for (int i = 1; i < tuple.size(); i++) { Location cur = tuple.get(i); Descriptor enclosingDesc = cur.getDescriptor(); Descriptor curDesc = cur.getLocDescriptor(); - String fieldLocSymbol = - getLocationInfo(enclosingDesc).getInferLocation(curDesc).get(0).getLocIdentifier(); - Location inferLocElement = new Location(enclosingDesc, fieldLocSymbol); + Location inferLocElement; + if (curDesc == null) { + // in this case, we have a newly generated location. + // System.out.println("!!! generated location=" + + // cur.getLocIdentifier()); + inferLocElement = new Location(enclosingDesc, cur.getLocIdentifier()); + } else { + String fieldLocSymbol = + getLocationInfo(enclosingDesc).getInferLocation(curDesc).get(0).getLocIdentifier(); + inferLocElement = new Location(enclosingDesc, fieldLocSymbol); + inferLocElement.setLocDescriptor(curDesc); + } inferLoc.addLocation(inferLocElement); } - + // System.out.println("@@@@@inferLoc=" + inferLoc); return inferLoc; } private void addRelation(SSJavaLattice methodLattice, MethodLocationInfo methodInfo, CompositeLocation srcInferLoc, CompositeLocation dstInferLoc) throws CyclicFlowException { + System.out.println("addRelation --- srcInferLoc=" + srcInferLoc + " dstInferLoc=" + + dstInferLoc); String srcLocalLocSymbol = srcInferLoc.get(0).getLocIdentifier(); String dstLocalLocSymbol = dstInferLoc.get(0).getLocIdentifier(); @@ -752,9 +783,11 @@ public class LocationInference { } } + System.out.println(); + } - private LocationInfo getLocationInfo(Descriptor d) { + public LocationInfo getLocationInfo(Descriptor d) { if (d instanceof MethodDescriptor) { return getMethodLocationInfo((MethodDescriptor) d); } else { @@ -790,21 +823,23 @@ public class LocationInference { // add a new binary relation of dstNode < srcNode FlowGraph flowGraph = getFlowGraph(md); - - calculateCompositeLocation(flowGraph, methodLattice, methodInfo, srcNode); - - CompositeLocation srcInferLoc = - generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(srcNode)); - CompositeLocation dstInferLoc = - generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(dstNode)); - try { + System.out.println("***** src composite case::"); + calculateCompositeLocation(flowGraph, methodLattice, methodInfo, srcNode); + + CompositeLocation srcInferLoc = + generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(srcNode)); + CompositeLocation dstInferLoc = + generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(dstNode)); addRelation(methodLattice, methodInfo, srcInferLoc, dstInferLoc); } catch (CyclicFlowException e) { // there is a cyclic value flow... try to calculate a composite location // for the destination node + System.out.println("***** dst composite case::"); calculateCompositeLocation(flowGraph, methodLattice, methodInfo, dstNode); - dstInferLoc = + CompositeLocation srcInferLoc = + generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(srcNode)); + CompositeLocation dstInferLoc = generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(dstNode)); try { addRelation(methodLattice, methodInfo, srcInferLoc, dstInferLoc); @@ -827,6 +862,7 @@ public class LocationInference { // check if it is the case of shared location if (srcInferLoc.getSize() == (idx + 1) && dstInferLoc.getSize() == (idx + 1)) { Location inferLocElement = srcInferLoc.get(idx); + System.out.println("SET SHARED LOCATION=" + inferLocElement); getLattice(inferLocElement.getDescriptor()) .addSharedLoc(inferLocElement.getLocIdentifier()); } else if (srcInferLoc.getSize() > (idx + 1) && dstInferLoc.getSize() > (idx + 1)) { @@ -888,6 +924,11 @@ public class LocationInference { throws CyclicFlowException { Descriptor localVarDesc = flowNode.getDescTuple().get(0); + NTuple flowNodelocTuple = flowGraph.getLocationTuple(flowNode); + + if (localVarDesc.equals(methodInfo.getMethodDesc())) { + return false; + } Set inNodeSet = flowGraph.getIncomingFlowNodeSet(flowNode); Set reachableNodeSet = flowGraph.getReachableFlowNodeSet(flowNode); @@ -905,15 +946,20 @@ public class LocationInference { for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) { FlowNode inNode = (FlowNode) iterator.next(); - NTuple inTuple = flowGraph.getLocationTuple(inNode); + NTuple inNodeTuple = flowGraph.getLocationTuple(inNode); + + CompositeLocation inNodeInferredLoc = + generateInferredCompositeLocation(methodInfo, inNodeTuple); - if (inTuple.size() > 1) { - for (int i = 1; i < inTuple.size(); i++) { - NTuple prefix = inTuple.subList(0, i); + NTuple inNodeInferredLocTuple = inNodeInferredLoc.getTuple(); + + if (inNodeTuple.size() > 1) { + for (int i = 1; i < inNodeInferredLocTuple.size(); i++) { + NTuple prefix = inNodeInferredLocTuple.subList(0, i); if (!prefixList.contains(prefix)) { prefixList.add(prefix); } - addPrefixMapping(mapPrefixToIncomingLocTupleSet, prefix, inTuple); + addPrefixMapping(mapPrefixToIncomingLocTupleSet, prefix, inNodeInferredLocTuple); } } else { localInNodeSet.add(inNode); @@ -949,7 +995,9 @@ public class LocationInference { for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) { FlowNode reachableNode = (FlowNode) iterator2.next(); NTuple reachLocTuple = flowGraph.getLocationTuple(reachableNode); - if (reachLocTuple.startsWith(curPrefix)) { + CompositeLocation reachLocInferLoc = + generateInferredCompositeLocation(methodInfo, reachLocTuple); + if (reachLocInferLoc.getTuple().startsWith(curPrefix)) { reachableCommonPrefixSet.add(reachLocTuple); } } @@ -980,52 +1028,91 @@ public class LocationInference { SSJavaLattice lattice = getLattice(desc); LocationInfo locInfo = getLocationInfo(desc); - // CompositeLocation inferLocation = - // methodInfo.getInferLocation(flowNode); - CompositeLocation inferLocation = methodInfo.getInferLocation(localVarDesc); + CompositeLocation inferLocation = + generateInferredCompositeLocation(methodInfo, flowNodelocTuple); - String newlyInsertedLocName; - if (inferLocation.getSize() == 1) { - // need to replace the old local location with a new composite - // location + // methodInfo.getInferLocation(localVarDesc); + CompositeLocation newInferLocation = new CompositeLocation(); - String oldMethodLocationSymbol = inferLocation.get(0).getLocIdentifier(); + System.out.println("PREV INFER LOCATION=" + inferLocation + " curPrefix=" + + curPrefix); + if (inferLocation.getTuple().startsWith(curPrefix)) { + // the same infer location is already existed. no need to do + // anything + return true; + } else { + // assign a new composite location + // String oldMethodLocationSymbol = + // inferLocation.get(0).getLocIdentifier(); String newLocSymbol = "Loc" + (SSJavaLattice.seed++); - inferLocation = new CompositeLocation(); for (int locIdx = 0; locIdx < curPrefix.size(); locIdx++) { - inferLocation.addLocation(curPrefix.get(locIdx)); + newInferLocation.addLocation(curPrefix.get(locIdx)); } - Location fieldLoc = new Location(desc, newLocSymbol); - inferLocation.addLocation(fieldLoc); - - methodInfo.mapDescriptorToLocation(localVarDesc, inferLocation); - methodInfo.removeMaplocalVarToLocSet(localVarDesc); - - String newMethodLocationSymbol = curPrefix.get(0).getLocIdentifier(); + Location newLocationElement = new Location(desc, newLocSymbol); + newInferLocation.addLocation(newLocationElement); - replaceOldLocWithNewLoc(methodLattice, oldMethodLocationSymbol, newMethodLocationSymbol); + // if (flowNode.getDescTuple().size() == 1) { + // maps local variable to location types of the common prefix + methodInfo.mapDescriptorToLocation(localVarDesc, newInferLocation.clone()); + // } - } else { + // methodInfo.mapDescriptorToLocation(localVarDesc, newInferLocation); + addMapLocSymbolToInferredLocation(methodInfo.getMethodDesc(), localVarDesc, + newInferLocation); + methodInfo.removeMaplocalVarToLocSet(localVarDesc); - String localLocName = methodInfo.getInferLocation(localVarDesc).get(0).getLocIdentifier(); - return true; + // add the field/var descriptor to the set of the location symbol + int flowNodeTupleSize = flowNode.getDescTuple().size(); + Descriptor lastFlowNodeDesc = flowNode.getDescTuple().get(flowNodeTupleSize - 1); + int inferLocSize = newInferLocation.getSize(); + Location lastLoc = newInferLocation.get(inferLocSize - 1); + Descriptor enclosingDesc = lastLoc.getDescriptor(); + getLocationInfo(enclosingDesc).addMapLocSymbolToDescSet(lastLoc.getLocIdentifier(), + lastFlowNodeDesc); + + // clean up the previous location + // Location prevInferLocElement = + // inferLocation.get(inferLocation.getSize() - 1); + // Descriptor prevEnclosingDesc = prevInferLocElement.getDescriptor(); + // + // SSJavaLattice targetLattice; + // LocationInfo targetInfo; + // if (prevEnclosingDesc.equals(methodInfo.getMethodDesc())) { + // targetLattice = methodLattice; + // targetInfo = methodInfo; + // } else { + // targetLattice = getLattice(prevInferLocElement.getDescriptor()); + // targetInfo = getLocationInfo(prevInferLocElement.getDescriptor()); + // } + // + // Set> associstedDescSet = + // targetInfo.getRelatedInferLocSet(prevInferLocElement.getLocIdentifier()); + // + // if (associstedDescSet.size() == 1) { + // targetLattice.remove(prevInferLocElement.getLocIdentifier()); + // } else { + // associstedDescSet.remove(lastFlowNodeDesc); + // } } - newlyInsertedLocName = inferLocation.get(inferLocation.getSize() - 1).getLocIdentifier(); + System.out.println("ASSIGN NEW COMPOSITE LOCATION =" + newInferLocation + " to " + + flowNode); + String newlyInsertedLocName = + newInferLocation.get(newInferLocation.getSize() - 1).getLocIdentifier(); + + System.out.println("-- add in-flow"); for (Iterator iterator = incomingCommonPrefixSet.iterator(); iterator.hasNext();) { NTuple tuple = (NTuple) iterator.next(); - + System.out.println("--in-flow tuple=" + tuple); Location loc = tuple.get(idx); String higher = locInfo.getFieldInferLocation(loc.getLocDescriptor()).getLocIdentifier(); - System.out.println("--"); - System.out.println("add in-flow relation:"); addRelationHigherToLower(lattice, locInfo, higher, newlyInsertedLocName); } - System.out.println("end of add-inflow relation"); + System.out.println("-- add local in-flow"); for (Iterator iterator = localInNodeSet.iterator(); iterator.hasNext();) { FlowNode localNode = (FlowNode) iterator.next(); @@ -1039,25 +1126,25 @@ public class LocationInference { if (isCompositeLocation(inNodeInferLoc)) { // need to make sure that newLocSymbol is lower than the infernode // location in the field lattice - - addRelation(methodLattice, methodInfo, inNodeInferLoc, inferLocation); + System.out.println("----srcNode=" + localNode + " dstNode=" + flowNode); + addRelationToLattice(methodInfo.getMethodDesc(), methodLattice, methodInfo, localNode, + flowNode); } } + System.out.println("-- add out flow"); for (Iterator iterator = reachableCommonPrefixSet.iterator(); iterator.hasNext();) { NTuple tuple = (NTuple) iterator.next(); if (tuple.size() > idx) { Location loc = tuple.get(idx); String lower = locInfo.getFieldInferLocation(loc.getLocDescriptor()).getLocIdentifier(); - // lattice.addRelationHigherToLower(newlyInsertedLocName, lower); - System.out.println("add out-flow relation:"); addRelationHigherToLower(lattice, locInfo, newlyInsertedLocName, lower); } } - System.out.println("end of add out-flow relation"); + System.out.println("-- add local out flow"); for (Iterator iterator = localOutNodeSet.iterator(); iterator.hasNext();) { FlowNode localOutNode = (FlowNode) iterator.next(); @@ -1065,17 +1152,18 @@ public class LocationInference { continue; } - - CompositeLocation outNodeInferLoc= generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(localOutNode)); + CompositeLocation outNodeInferLoc = + generateInferredCompositeLocation(methodInfo, + flowGraph.getLocationTuple(localOutNode)); if (isCompositeLocation(outNodeInferLoc)) { - // need to make sure that newLocSymbol is higher than the infernode - // location - - addRelation(methodLattice, methodInfo, inferLocation, outNodeInferLoc); + System.out.println("--- srcNode=" + flowNode + " dstNode=" + localOutNode); + addRelationToLattice(methodInfo.getMethodDesc(), methodLattice, methodInfo, flowNode, + localOutNode); } } + System.out.println("-- end of add local out flow"); return true; } @@ -1086,6 +1174,15 @@ public class LocationInference { } + private void addMapLocSymbolToInferredLocation(MethodDescriptor md, Descriptor localVar, + CompositeLocation inferLoc) { + + Location locElement = inferLoc.get((inferLoc.getSize() - 1)); + Descriptor enclosingDesc = locElement.getDescriptor(); + LocationInfo locInfo = getLocationInfo(enclosingDesc); + locInfo.addMapLocSymbolToRelatedInferLoc(locElement.getLocIdentifier(), md, localVar); + } + private boolean isCompositeLocation(CompositeLocation cl) { return cl.getSize() > 1; } @@ -1113,12 +1210,12 @@ public class LocationInference { private void addRelationHigherToLower(SSJavaLattice lattice, LocationInfo locInfo, String higher, String lower) throws CyclicFlowException { + System.out.println("---addRelationHigherToLower " + higher + " -> " + lower + + " to the lattice of " + locInfo.getDescIdentifier()); // if (higher.equals(lower) && lattice.isSharedLoc(higher)) { // return; // } Set cycleElementSet = lattice.getPossibleCycleElements(higher, lower); - System.out.println("#Check cycle=" + lower + " < " + higher); - System.out.println("#cycleElementSet=" + cycleElementSet); boolean hasNonPrimitiveElement = false; for (Iterator iterator = cycleElementSet.iterator(); iterator.hasNext();) { @@ -1132,19 +1229,52 @@ public class LocationInference { } if (hasNonPrimitiveElement) { + System.out.println("#Check cycle= " + lower + " < " + higher + " cycleElementSet=" + + cycleElementSet); // if there is non-primitive element in the cycle, no way to merge cyclic // elements into the shared location throw new CyclicFlowException(); } if (cycleElementSet.size() > 0) { + String newSharedLoc = "SharedLoc" + (SSJavaLattice.seed++); + System.out.println("---ASSIGN NEW SHARED LOC=" + newSharedLoc + " to " + cycleElementSet); lattice.mergeIntoSharedLocation(cycleElementSet, newSharedLoc); for (Iterator iterator = cycleElementSet.iterator(); iterator.hasNext();) { String oldLocSymbol = (String) iterator.next(); - locInfo.mergeMapping(oldLocSymbol, newSharedLoc); + + Set> inferLocSet = locInfo.getRelatedInferLocSet(oldLocSymbol); + System.out.println("---update related locations=" + inferLocSet); + for (Iterator iterator2 = inferLocSet.iterator(); iterator2.hasNext();) { + Pair pair = (Pair) iterator2.next(); + Descriptor enclosingDesc = pair.getFirst(); + Descriptor desc = pair.getSecond(); + + CompositeLocation inferLoc; + if (curMethodInfo.md.equals(enclosingDesc)) { + inferLoc = curMethodInfo.getInferLocation(desc); + } else { + inferLoc = getLocationInfo(enclosingDesc).getInferLocation(desc); + } + + Location locElement = inferLoc.get(inferLoc.getSize() - 1); + + locElement.setLocIdentifier(newSharedLoc); + locInfo.addMapLocSymbolToRelatedInferLoc(newSharedLoc, enclosingDesc, desc); + + if (curMethodInfo.md.equals(enclosingDesc)) { + inferLoc = curMethodInfo.getInferLocation(desc); + } else { + inferLoc = getLocationInfo(enclosingDesc).getInferLocation(desc); + } + System.out.println("---New Infer Loc=" + inferLoc); + + } + locInfo.removeRelatedInferLocSet(oldLocSymbol, newSharedLoc); + } lattice.addSharedLoc(newSharedLoc); @@ -1511,13 +1641,14 @@ public class LocationInference { switch (en.kind()) { case Kind.AssignmentNode: - analyzeFlowAssignmentNode(md, nametable, (AssignmentNode) en, base, implicitFlowTupleSet); + analyzeFlowAssignmentNode(md, nametable, (AssignmentNode) en, nodeSet, base, + implicitFlowTupleSet); break; case Kind.FieldAccessNode: flowTuple = analyzeFlowFieldAccessNode(md, nametable, (FieldAccessNode) en, nodeSet, base, - implicitFlowTupleSet); + implicitFlowTupleSet, isLHS); if (flowTuple != null) { nodeSet.addTuple(flowTuple); } @@ -1753,7 +1884,6 @@ public class LocationInference { if (isLHS) { // need to create an edge from idx to array - for (Iterator> idxIter = idxNodeTupleSet.iterator(); idxIter.hasNext();) { NTuple idxTuple = idxIter.next(); for (Iterator> arrIter = expNodeTupleSet.iterator(); arrIter.hasNext();) { @@ -1918,7 +2048,7 @@ public class LocationInference { private NTuple analyzeFlowFieldAccessNode(MethodDescriptor md, SymbolTable nametable, FieldAccessNode fan, NodeTupleSet nodeSet, NTuple base, - NodeTupleSet implicitFlowTupleSet) { + NodeTupleSet implicitFlowTupleSet, boolean isLHS) { ExpressionNode left = fan.getExpression(); TypeDescriptor ltd = left.getType(); @@ -1937,30 +2067,44 @@ public class LocationInference { } } + NodeTupleSet idxNodeTupleSet = new NodeTupleSet(); if (left instanceof ArrayAccessNode) { + ArrayAccessNode aan = (ArrayAccessNode) left; left = aan.getExpression(); + analyzeFlowExpressionNode(md, nametable, aan.getIndex(), idxNodeTupleSet, base, + implicitFlowTupleSet, isLHS); + nodeSet.addTupleSet(idxNodeTupleSet); } - // fanNodeSet base = - analyzeFlowExpressionNode(md, nametable, left, nodeSet, base, implicitFlowTupleSet, false); + analyzeFlowExpressionNode(md, nametable, left, nodeSet, base, implicitFlowTupleSet, isLHS); + if (base == null) { // in this case, field is TOP location return null; } else { + NTuple flowFieldTuple = new NTuple(base.toList()); + if (!left.getType().isPrimitive()) { - if (fd.getSymbol().equals("length")) { + if (!fd.getSymbol().equals("length")) { // array.length access, just have the location of the array - } else { - base.add(fd); + flowFieldTuple.add(fd); + nodeSet.removeTuple(base); } } + getFlowGraph(md).createNewFlowNode(flowFieldTuple); - getFlowGraph(md).createNewFlowNode(base); - return base; + if (isLHS) { + for (Iterator> idxIter = idxNodeTupleSet.iterator(); idxIter.hasNext();) { + NTuple idxTuple = idxIter.next(); + getFlowGraph(md).addValueFlowEdge(idxTuple, flowFieldTuple); + } + } + + return flowFieldTuple; } @@ -1973,7 +2117,8 @@ public class LocationInference { } private void analyzeFlowAssignmentNode(MethodDescriptor md, SymbolTable nametable, - AssignmentNode an, NTuple base, NodeTupleSet implicitFlowTupleSet) { + AssignmentNode an, NodeTupleSet nodeSet, NTuple base, + NodeTupleSet implicitFlowTupleSet) { NodeTupleSet nodeSetRHS = new NodeTupleSet(); NodeTupleSet nodeSetLHS = new NodeTupleSet(); @@ -2036,8 +2181,20 @@ public class LocationInference { addFlowGraphEdge(md, tuple, tuple); } + // creates edges from implicitFlowTupleSet to LHS + for (Iterator> iter = implicitFlowTupleSet.iterator(); iter.hasNext();) { + NTuple fromTuple = iter.next(); + for (Iterator> iter2 = nodeSetLHS.iterator(); iter2.hasNext();) { + NTuple toTuple = iter2.next(); + addFlowGraphEdge(md, fromTuple, toTuple); + } + } + } + if (nodeSet != null) { + nodeSet.addTupleSet(nodeSetLHS); + } } public FlowGraph getFlowGraph(MethodDescriptor md) {