changes.
[IRC.git] / Robust / src / Analysis / SSJava / LocationInference.java
index 3ae2d94dca264bccd7f958b3e2c22dc6f6112ab5..ed44790338a728bd8dd34eb3a511a62304a3d751 100644 (file)
@@ -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) {
@@ -290,6 +293,7 @@ public class LocationInference {
           new SSJavaLattice<String>(SSJavaAnalysis.TOP, SSJavaAnalysis.BOTTOM);
 
       MethodLocationInfo methodInfo = new MethodLocationInfo(md);
+      curMethodInfo = methodInfo;
 
       System.out.println();
       System.out.println("SSJAVA: Inferencing the lattice from " + md);
@@ -438,6 +442,8 @@ public class LocationInference {
 
     // set the global location
     methodInfo.setGlobalLocName(LocationInference.GLOBALLOC);
+    methodInfo.mapDescriptorToLocation(GLOBALDESC, new CompositeLocation(
+        new Location(md, GLOBALLOC)));
 
     // visit each node of method flow graph
     FlowGraph fg = getFlowGraph(md);
@@ -463,9 +469,17 @@ public class LocationInference {
               && srcNodeTuple.get(0).equals(dstNodeTuple.get(0))) {
 
             // value flows between fields
-            VarDescriptor varDesc = (VarDescriptor) srcNodeTuple.get(0);
-            ClassDescriptor varClassDesc = varDesc.getType().getClassDesc();
-            extractRelationFromFieldFlows(varClassDesc, srcNode, dstNode, 1);
+            Descriptor desc = srcNodeTuple.get(0);
+            ClassDescriptor classDesc;
+
+            if (desc.equals(GLOBALDESC)) {
+              classDesc = md.getClassDesc();
+            } else {
+              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
@@ -673,10 +687,8 @@ public class LocationInference {
                 // CompositeLocation lowerInferLoc =
                 // methodInfo.getInferLocation(argTuple2.get(0));
 
-                CompositeLocation inferLoc1 =
-                    calcualteInferredCompositeLocation(methodInfo, tuple1);
-                CompositeLocation inferLoc2 =
-                    calcualteInferredCompositeLocation(methodInfo, tuple2);
+                CompositeLocation inferLoc1 = generateInferredCompositeLocation(methodInfo, tuple1);
+                CompositeLocation inferLoc2 = generateInferredCompositeLocation(methodInfo, tuple2);
 
                 addRelation(methodLattice, methodInfo, inferLoc1, inferLoc2);
 
@@ -691,38 +703,54 @@ public class LocationInference {
 
   }
 
-  private CompositeLocation calcualteInferredCompositeLocation(MethodLocationInfo methodInfo,
+  private CompositeLocation generateInferredCompositeLocation(MethodLocationInfo methodInfo,
       NTuple<Location> 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<String> methodLattice, MethodLocationInfo methodInfo,
       CompositeLocation srcInferLoc, CompositeLocation dstInferLoc) throws CyclicFlowException {
 
+    System.out.println("--- srcInferLoc=" + srcInferLoc + "  dstInferLoc=" + dstInferLoc);
     String srcLocalLocSymbol = srcInferLoc.get(0).getLocIdentifier();
     String dstLocalLocSymbol = dstInferLoc.get(0).getLocIdentifier();
 
@@ -744,9 +772,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 {
@@ -782,22 +812,25 @@ public class LocationInference {
 
     // add a new binary relation of dstNode < srcNode
     FlowGraph flowGraph = getFlowGraph(md);
+    try {
+      System.out.println("***** src composite case::");
+      calculateCompositeLocation(flowGraph, methodLattice, methodInfo, srcNode);
 
-    calculateCompositeLocation(flowGraph, methodLattice, methodInfo, srcNode);
-
-    CompositeLocation srcInferLoc =
-        calcualteInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(srcNode));
-    CompositeLocation dstInferLoc =
-        calcualteInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(dstNode));
+      CompositeLocation srcInferLoc =
+          generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(srcNode));
+      CompositeLocation dstInferLoc =
+          generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(dstNode));
 
-    try {
       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 =
-          calcualteInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(dstNode));
+      CompositeLocation srcInferLoc =
+          generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(srcNode));
+      CompositeLocation dstInferLoc =
+          generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(dstNode));
       try {
         addRelation(methodLattice, methodInfo, srcInferLoc, dstInferLoc);
       } catch (CyclicFlowException e1) {
@@ -819,6 +852,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)) {
@@ -881,6 +915,10 @@ public class LocationInference {
 
     Descriptor localVarDesc = flowNode.getDescTuple().get(0);
 
+    if (localVarDesc.equals(methodInfo.getMethodDesc())) {
+      return false;
+    }
+
     Set<FlowNode> inNodeSet = flowGraph.getIncomingFlowNodeSet(flowNode);
     Set<FlowNode> reachableNodeSet = flowGraph.getReachableFlowNodeSet(flowNode);
 
@@ -891,21 +929,26 @@ public class LocationInference {
     Set<FlowNode> localOutNodeSet = new HashSet<FlowNode>();
 
     CompositeLocation flowNodeInferLoc =
-        calcualteInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(flowNode));
+        generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(flowNode));
 
     List<NTuple<Location>> prefixList = new ArrayList<NTuple<Location>>();
 
     for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) {
       FlowNode inNode = (FlowNode) iterator.next();
-      NTuple<Location> inTuple = flowGraph.getLocationTuple(inNode);
+      NTuple<Location> inNodeTuple = flowGraph.getLocationTuple(inNode);
+
+      CompositeLocation inNodeInferredLoc =
+          generateInferredCompositeLocation(methodInfo, inNodeTuple);
 
-      if (inTuple.size() > 1) {
-        for (int i = 1; i < inTuple.size(); i++) {
-          NTuple<Location> prefix = inTuple.subList(0, i);
+      NTuple<Location> inNodeInferredLocTuple = inNodeInferredLoc.getTuple();
+
+      if (inNodeTuple.size() > 1) {
+        for (int i = 1; i < inNodeInferredLocTuple.size(); i++) {
+          NTuple<Location> prefix = inNodeInferredLocTuple.subList(0, i);
           if (!prefixList.contains(prefix)) {
             prefixList.add(prefix);
           }
-          addPrefixMapping(mapPrefixToIncomingLocTupleSet, prefix, inTuple);
+          addPrefixMapping(mapPrefixToIncomingLocTupleSet, prefix, inNodeInferredLocTuple);
         }
       } else {
         localInNodeSet.add(inNode);
@@ -941,14 +984,16 @@ public class LocationInference {
       for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) {
         FlowNode reachableNode = (FlowNode) iterator2.next();
         NTuple<Location> reachLocTuple = flowGraph.getLocationTuple(reachableNode);
-        if (reachLocTuple.startsWith(curPrefix)) {
+        CompositeLocation reachLocInferLoc =
+            generateInferredCompositeLocation(methodInfo, reachLocTuple);
+        if (reachLocInferLoc.getTuple().startsWith(curPrefix)) {
           reachableCommonPrefixSet.add(reachLocTuple);
         }
       }
 
       // check if the lattice has the relation in which higher prefix is
       // actually lower than the current node
-      CompositeLocation prefixInferLoc = calcualteInferredCompositeLocation(methodInfo, curPrefix);
+      CompositeLocation prefixInferLoc = generateInferredCompositeLocation(methodInfo, curPrefix);
       if (isGreaterThan(methodLattice, flowNodeInferLoc, prefixInferLoc)) {
         reachableCommonPrefixSet.add(curPrefix);
       }
@@ -972,51 +1017,60 @@ public class LocationInference {
         SSJavaLattice<String> lattice = getLattice(desc);
         LocationInfo locInfo = getLocationInfo(desc);
 
-        // CompositeLocation inferLocation =
-        // methodInfo.getInferLocation(flowNode);
         CompositeLocation inferLocation = methodInfo.getInferLocation(localVarDesc);
+        CompositeLocation newInferLocation = new CompositeLocation();
 
-        String newlyInsertedLocName;
-        if (inferLocation.getSize() == 1) {
-          // need to replace the old local location with a new composite
-          // location
-
-          String oldMethodLocationSymbol = inferLocation.get(0).getLocIdentifier();
+        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);
+          newInferLocation.addLocation(fieldLoc);
+
+          NTuple<Location> locTuple = flowGraph.getLocationTuple(flowNode);
+          for (int tidx = 1; tidx < locTuple.size(); tidx++) {
+            Location cur = locTuple.get(tidx);
+            Descriptor enclosingDesc = cur.getDescriptor();
+            Descriptor curDesc = cur.getLocDescriptor();
+            Location inferLocElement;
+            if (curDesc == null) {
+              // in this case, we have a newly generated location.
+              inferLocElement = new Location(enclosingDesc, cur.getLocIdentifier());
+            } else {
+              String fieldLocSymbol =
+                  getLocationInfo(enclosingDesc).getInferLocation(curDesc).get(0)
+                      .getLocIdentifier();
+              inferLocElement = new Location(enclosingDesc, fieldLocSymbol);
+              inferLocElement.setLocDescriptor(curDesc);
+            }
+            newInferLocation.addLocation(inferLocElement);
+          }
 
-          methodInfo.mapDescriptorToLocation(localVarDesc, inferLocation);
+          methodInfo.mapDescriptorToLocation(localVarDesc, newInferLocation);
+          addMapLocSymbolToInferredLocation(methodInfo.getMethodDesc(), localVarDesc,
+              newInferLocation);
           methodInfo.removeMaplocalVarToLocSet(localVarDesc);
 
-          String newMethodLocationSymbol = curPrefix.get(0).getLocIdentifier();
-
-          replaceOldLocWithNewLoc(methodLattice, oldMethodLocationSymbol, newMethodLocationSymbol);
-
-        } else {
-
-          String localLocName = methodInfo.getInferLocation(localVarDesc).get(0).getLocIdentifier();
-          return true;
-
         }
 
-        newlyInsertedLocName = inferLocation.get(inferLocation.getSize() - 1).getLocIdentifier();
+        String newlyInsertedLocName =
+            newInferLocation.get(inferLocation.getSize() - 1).getLocIdentifier();
 
         for (Iterator iterator = incomingCommonPrefixSet.iterator(); iterator.hasNext();) {
           NTuple<Location> tuple = (NTuple<Location>) iterator.next();
-
           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");
 
         for (Iterator iterator = localInNodeSet.iterator(); iterator.hasNext();) {
           FlowNode localNode = (FlowNode) iterator.next();
@@ -1025,23 +1079,15 @@ public class LocationInference {
             continue;
           }
 
-          Descriptor localInVarDesc = localNode.getDescTuple().get(0);
-          CompositeLocation inNodeInferLoc = methodInfo.getInferLocation(localInVarDesc);
+          CompositeLocation inNodeInferLoc =
+              generateInferredCompositeLocation(methodInfo, flowGraph.getLocationTuple(localNode));
 
           if (isCompositeLocation(inNodeInferLoc)) {
             // need to make sure that newLocSymbol is lower than the infernode
             // location in the field lattice
-
-            if (inNodeInferLoc.getTuple().startsWith(curPrefix)
-                && inNodeInferLoc.getSize() == (curPrefix.size() + 1)) {
-              String higher = inNodeInferLoc.get(inNodeInferLoc.getSize() - 1).getLocIdentifier();
-              if (!higher.equals(newlyInsertedLocName)) {
-                System.out.println("add localInNodeSet relation:");
-                addRelationHigherToLower(lattice, locInfo, higher, newlyInsertedLocName);
-              }
-            } else {
-              throw new Error("Failed to generate a composite location.");
-            }
+            System.out.println("----srcNode=" + localNode + "  dstNode=" + flowNode);
+            addRelationToLattice(methodInfo.getMethodDesc(), methodLattice, methodInfo, localNode,
+                flowNode);
 
           }
 
@@ -1052,12 +1098,9 @@ public class LocationInference {
           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");
 
         for (Iterator iterator = localOutNodeSet.iterator(); iterator.hasNext();) {
           FlowNode localOutNode = (FlowNode) iterator.next();
@@ -1066,24 +1109,17 @@ public class LocationInference {
             continue;
           }
 
-          Descriptor localOutDesc = localOutNode.getDescTuple().get(0);
-          CompositeLocation outNodeInferLoc = methodInfo.getInferLocation(localOutDesc);
+          CompositeLocation outNodeInferLoc =
+              generateInferredCompositeLocation(methodInfo,
+                  flowGraph.getLocationTuple(localOutNode));
 
           if (isCompositeLocation(outNodeInferLoc)) {
             // need to make sure that newLocSymbol is higher than the infernode
             // location
+            System.out.println("--- srcNode=" + flowNode + "  dstNode=" + localOutNode);
+            addRelationToLattice(methodInfo.getMethodDesc(), methodLattice, methodInfo, flowNode,
+                localOutNode);
 
-            if (outNodeInferLoc.getTuple().startsWith(curPrefix)
-                && outNodeInferLoc.getSize() == (curPrefix.size() + 1)) {
-
-              String lower = outNodeInferLoc.get(outNodeInferLoc.getSize() - 1).getLocIdentifier();
-              System.out.println("add outNodeInferLoc relation:");
-
-              addRelationHigherToLower(lattice, locInfo, newlyInsertedLocName, lower);
-
-            } else {
-              throw new Error("Failed to generate a composite location.");
-            }
           }
         }
 
@@ -1096,6 +1132,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;
   }
@@ -1127,8 +1172,6 @@ public class LocationInference {
     // return;
     // }
     Set<String> 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();) {
@@ -1142,19 +1185,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<Pair<Descriptor, Descriptor>> inferLocSet = locInfo.getRelatedInferLocSet(oldLocSymbol);
+        System.out.println("$$$update related locations=" + inferLocSet);
+        for (Iterator iterator2 = inferLocSet.iterator(); iterator2.hasNext();) {
+          Pair<Descriptor, Descriptor> pair = (Pair<Descriptor, Descriptor>) 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);
@@ -1527,7 +1603,7 @@ public class LocationInference {
     case Kind.FieldAccessNode:
       flowTuple =
           analyzeFlowFieldAccessNode(md, nametable, (FieldAccessNode) en, nodeSet, base,
-              implicitFlowTupleSet);
+              implicitFlowTupleSet, isLHS);
       if (flowTuple != null) {
         nodeSet.addTuple(flowTuple);
       }
@@ -1722,7 +1798,6 @@ public class LocationInference {
   private void analyzeFlowMethodParameters(MethodDescriptor callermd, SymbolTable nametable,
       MethodInvokeNode min) {
 
-
     if (min.numArgs() > 0) {
 
       int offset;
@@ -1849,7 +1924,6 @@ public class LocationInference {
   private NTuple<Descriptor> analyzeFlowNameNode(MethodDescriptor md, SymbolTable nametable,
       NameNode nn, NodeTupleSet nodeSet, NTuple<Descriptor> base, NodeTupleSet implicitFlowTupleSet) {
 
-
     if (base == null) {
       base = new NTuple<Descriptor>();
     }
@@ -1930,8 +2004,7 @@ public class LocationInference {
 
   private NTuple<Descriptor> analyzeFlowFieldAccessNode(MethodDescriptor md, SymbolTable nametable,
       FieldAccessNode fan, NodeTupleSet nodeSet, NTuple<Descriptor> base,
-      NodeTupleSet implicitFlowTupleSet) {
-
+      NodeTupleSet implicitFlowTupleSet, boolean isLHS) {
 
     ExpressionNode left = fan.getExpression();
     TypeDescriptor ltd = left.getType();
@@ -1946,18 +2019,20 @@ public class LocationInference {
     if (ltd.isClassNameRef() || (varName != null && varName.equals("this"))) {
       // using a class name directly or access using this
       if (fd.isStatic() && fd.isFinal()) {
-        // loc.addLocation(Location.createTopLocation(md));
-        // return loc;
+        return null;
       }
     }
 
     if (left instanceof ArrayAccessNode) {
+
       ArrayAccessNode aan = (ArrayAccessNode) left;
       left = aan.getExpression();
+      analyzeFlowExpressionNode(md, nametable, aan.getIndex(), nodeSet, base, implicitFlowTupleSet,
+          isLHS);
     }
     // 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;
@@ -1965,9 +2040,8 @@ public class LocationInference {
 
       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);
         }
 
@@ -2050,6 +2124,15 @@ public class LocationInference {
         addFlowGraphEdge(md, tuple, tuple);
       }
 
+      // creates edges from implicitFlowTupleSet to LHS
+      for (Iterator<NTuple<Descriptor>> iter = implicitFlowTupleSet.iterator(); iter.hasNext();) {
+        NTuple<Descriptor> fromTuple = iter.next();
+        for (Iterator<NTuple<Descriptor>> iter2 = nodeSetLHS.iterator(); iter2.hasNext();) {
+          NTuple<Descriptor> toTuple = iter2.next();
+          addFlowGraphEdge(md, fromTuple, toTuple);
+        }
+      }
+
     }
 
   }