bug fix
[IRC.git] / Robust / src / Analysis / SSJava / DefinitelyWrittenCheck.java
index 93145be82aff921ea5f1c0f72ae5fe7815a9f262..2536171de0ec1049f11cba86a0988f63991ca57f 100644 (file)
@@ -17,13 +17,16 @@ import IR.State;
 import IR.TypeDescriptor;
 import IR.Flat.FKind;
 import IR.Flat.FlatCall;
+import IR.Flat.FlatElementNode;
 import IR.Flat.FlatFieldNode;
 import IR.Flat.FlatLiteralNode;
 import IR.Flat.FlatMethod;
 import IR.Flat.FlatNode;
 import IR.Flat.FlatOpNode;
+import IR.Flat.FlatSetElementNode;
 import IR.Flat.FlatSetFieldNode;
 import IR.Flat.TempDescriptor;
+import IR.Tree.Modifiers;
 import Util.Pair;
 
 public class DefinitelyWrittenCheck {
@@ -82,6 +85,9 @@ public class DefinitelyWrittenCheck {
   // when analyzing flatcall, need to re-schedule set of callee
   private Set<MethodDescriptor> calleesToEnqueue;
 
+  public static final String arrayElementFieldName = "___element_";
+  static protected Hashtable<TypeDescriptor, FieldDescriptor> mapTypeToArrayField;
+
   private Set<ClearingSummary> possibleCalleeCompleteSummarySetToCaller;
 
   private LinkedList<MethodDescriptor> sortedDescriptors;
@@ -117,6 +123,7 @@ public class DefinitelyWrittenCheck {
     this.methodDescriptorsToVisitStack = new Stack<MethodDescriptor>();
     this.calleesToEnqueue = new HashSet<MethodDescriptor>();
     this.possibleCalleeCompleteSummarySetToCaller = new HashSet<ClearingSummary>();
+    this.mapTypeToArrayField = new Hashtable<TypeDescriptor, FieldDescriptor>();
     this.LOCAL = new TempDescriptor("LOCAL");
   }
 
@@ -136,7 +143,6 @@ public class DefinitelyWrittenCheck {
     ClearingSummary result =
         mapMethodDescriptorToCompleteClearingSummary.get(sortedDescriptors.peekFirst());
 
-    System.out.println("checkSharedLocationResult=" + result);
 
     Set<NTuple<Descriptor>> hpKeySet = result.keySet();
     for (Iterator iterator = hpKeySet.iterator(); iterator.hasNext();) {
@@ -159,7 +165,6 @@ public class DefinitelyWrittenCheck {
     // the same time once per the out-most loop
 
     computeReadSharedDescriptorSet();
-    System.out.println("Reading Shared Location=" + mapSharedLocation2DescriptorSet);
 
     methodDescriptorsToVisitStack.clear();
 
@@ -365,6 +370,18 @@ public class DefinitelyWrittenCheck {
       NTuple<Descriptor> fldHeapPath = new NTuple<Descriptor>(lhsHeapPath.getList());
       if (fld.getType().isImmutable()) {
         writeLocation(curr, fldHeapPath, fld);
+      } else {
+        // updates reference field case:
+        // 2. if there exists a tuple t in sharing summary that starts with
+        // hp(x) then, set flag of tuple t to 'true'
+        fldHeapPath.add(fld);
+        Set<NTuple<Descriptor>> hpKeySet = curr.keySet();
+        for (Iterator iterator = hpKeySet.iterator(); iterator.hasNext();) {
+          NTuple<Descriptor> hpKey = (NTuple<Descriptor>) iterator.next();
+          if (hpKey.startsWith(fldHeapPath)) {
+            curr.get(hpKey).updateFlag(true);
+          }
+        }
       }
 
     }
@@ -699,14 +716,14 @@ public class DefinitelyWrittenCheck {
   private void writeLocation(ClearingSummary curr, NTuple<Descriptor> hp, Descriptor d) {
     Location loc = getLocation(d);
     if (loc != null && hasReadingEffectOnSharedLocation(hp, loc, d)) {
+
+      // 1. add field x to the clearing set
       SharedStatus state = getState(curr, hp);
       state.addVar(loc, d);
 
-      // if the set v contains all of variables belonging to the shared
+      // 3. if the set v contains all of variables belonging to the shared
       // location, set flag to true
-
       Set<Descriptor> sharedVarSet = mapSharedLocation2DescriptorSet.get(loc);
-
       if (state.getVarSet(loc).containsAll(sharedVarSet)) {
         state.updateFlag(loc, true);
       }
@@ -878,10 +895,23 @@ public class DefinitelyWrittenCheck {
       case FKind.FlatFieldNode:
       case FKind.FlatElementNode: {
 
-        FlatFieldNode ffn = (FlatFieldNode) fn;
-        lhs = ffn.getDst();
-        rhs = ffn.getSrc();
-        fld = ffn.getField();
+        if (fn.kind() == FKind.FlatFieldNode) {
+          FlatFieldNode ffn = (FlatFieldNode) fn;
+          lhs = ffn.getDst();
+          rhs = ffn.getSrc();
+          fld = ffn.getField();
+        } else {
+          FlatElementNode fen = (FlatElementNode) fn;
+          lhs = fen.getDst();
+          rhs = fen.getSrc();
+          TypeDescriptor td = rhs.getType().dereference();
+          fld = getArrayField(td);
+        }
+
+        if (fld.isFinal() /* && fld.isStatic() */) {
+          // if field is final and static, no need to check
+          break;
+        }
 
         // read field
         NTuple<Descriptor> srcHeapPath = mapHeapPath.get(rhs);
@@ -901,9 +931,17 @@ public class DefinitelyWrittenCheck {
       case FKind.FlatSetFieldNode:
       case FKind.FlatSetElementNode: {
 
-        FlatSetFieldNode fsfn = (FlatSetFieldNode) fn;
-        lhs = fsfn.getDst();
-        fld = fsfn.getField();
+        if (fn.kind() == FKind.FlatSetFieldNode) {
+          FlatSetFieldNode fsfn = (FlatSetFieldNode) fn;
+          lhs = fsfn.getDst();
+          fld = fsfn.getField();
+        } else {
+          FlatSetElementNode fsen = (FlatSetElementNode) fn;
+          lhs = fsen.getDst();
+          rhs = fsen.getSrc();
+          TypeDescriptor td = lhs.getType().dereference();
+          fld = getArrayField(td);
+        }
 
         // write(field)
         NTuple<Descriptor> lhsHeapPath = computePath(lhs);
@@ -917,13 +955,13 @@ public class DefinitelyWrittenCheck {
       case FKind.FlatCall: {
         FlatCall fc = (FlatCall) fn;
         bindHeapPathCallerArgWithCaleeParam(fc);
-
         // add <hp,statement,false> in which hp is an element of
         // READ_bound set
         // of callee: callee has 'read' requirement!
+
+        
         for (Iterator iterator = calleeUnionBoundReadSet.iterator(); iterator.hasNext();) {
           NTuple<Descriptor> read = (NTuple<Descriptor>) iterator.next();
-
           Hashtable<FlatNode, Boolean> gen = curr.get(read);
           if (gen == null) {
             gen = new Hashtable<FlatNode, Boolean>();
@@ -990,7 +1028,6 @@ public class DefinitelyWrittenCheck {
     // transform all READ/OVERWRITE set from the any possible
     // callees to the
     // caller
-
     calleeUnionBoundReadSet.clear();
     calleeIntersectBoundOverWriteSet.clear();
 
@@ -1113,7 +1150,8 @@ public class DefinitelyWrittenCheck {
         (LinkedList<MethodDescriptor>) sortedDescriptors.clone();
 
     // no need to analyze method having ssjava loop
-    methodContainingSSJavaLoop = descriptorListToAnalyze.removeFirst();
+    // methodContainingSSJavaLoop = descriptorListToAnalyze.removeFirst();
+    methodContainingSSJavaLoop = ssjava.getMethodContainingSSJavaLoop();
 
     // current descriptors to visit in fixed-point interprocedural analysis,
     // prioritized by
@@ -1241,15 +1279,28 @@ public class DefinitelyWrittenCheck {
     }
       break;
 
-    case FKind.FlatFieldNode:
-    case FKind.FlatElementNode: {
+    case FKind.FlatElementNode:
+    case FKind.FlatFieldNode: {
 
       // y=x.f;
 
-      FlatFieldNode ffn = (FlatFieldNode) fn;
-      lhs = ffn.getDst();
-      rhs = ffn.getSrc();
-      fld = ffn.getField();
+      if (fn.kind() == FKind.FlatFieldNode) {
+        FlatFieldNode ffn = (FlatFieldNode) fn;
+        lhs = ffn.getDst();
+        rhs = ffn.getSrc();
+        fld = ffn.getField();
+      } else {
+        FlatElementNode fen = (FlatElementNode) fn;
+        lhs = fen.getDst();
+        rhs = fen.getSrc();
+        TypeDescriptor td = rhs.getType().dereference();
+        fld = getArrayField(td);
+      }
+
+      if (fld.isFinal() /* && fld.isStatic() */) {
+        // if field is final and static, no need to check
+        break;
+      }
 
       // set up heap path
       NTuple<Descriptor> srcHeapPath = mapHeapPath.get(rhs);
@@ -1269,8 +1320,7 @@ public class DefinitelyWrittenCheck {
           }
         }
 
-        // need to kill hp(x.f) from WT
-        writtenSet.remove(readingHeapPath);
+        //no need to kill hp(x.f) from WT
       }
 
     }
@@ -1280,10 +1330,19 @@ public class DefinitelyWrittenCheck {
     case FKind.FlatSetElementNode: {
 
       // x.f=y;
-      FlatSetFieldNode fsfn = (FlatSetFieldNode) fn;
-      lhs = fsfn.getDst();
-      fld = fsfn.getField();
-      rhs = fsfn.getSrc();
+
+      if (fn.kind() == FKind.FlatSetFieldNode) {
+        FlatSetFieldNode fsfn = (FlatSetFieldNode) fn;
+        lhs = fsfn.getDst();
+        fld = fsfn.getField();
+        rhs = fsfn.getSrc();
+      } else {
+        FlatSetElementNode fsen = (FlatSetElementNode) fn;
+        lhs = fsen.getDst();
+        rhs = fsen.getSrc();
+        TypeDescriptor td = lhs.getType().dereference();
+        fld = getArrayField(td);
+      }
 
       // set up heap path
       NTuple<Descriptor> lhsHeapPath = mapHeapPath.get(lhs);
@@ -1306,25 +1365,26 @@ public class DefinitelyWrittenCheck {
 
       FlatCall fc = (FlatCall) fn;
 
-      bindHeapPathCallerArgWithCaleeParam(fc);
-
-      // add heap path, which is an element of READ_bound set and is not
-      // an
-      // element of WT set, to the caller's READ set
-      for (Iterator iterator = calleeUnionBoundReadSet.iterator(); iterator.hasNext();) {
-        NTuple<Descriptor> read = (NTuple<Descriptor>) iterator.next();
-        if (!writtenSet.contains(read)) {
-          readSet.add(read);
+      if (fc.getThis() != null) {
+        bindHeapPathCallerArgWithCaleeParam(fc);
+        
+        // add heap path, which is an element of READ_bound set and is not
+        // an
+        // element of WT set, to the caller's READ set
+        for (Iterator iterator = calleeUnionBoundReadSet.iterator(); iterator.hasNext();) {
+          NTuple<Descriptor> read = (NTuple<Descriptor>) iterator.next();
+          if (!writtenSet.contains(read)) {
+            readSet.add(read);
+          }
         }
-      }
-      writtenSet.removeAll(calleeUnionBoundReadSet);
 
-      // add heap path, which is an element of OVERWRITE_bound set, to the
-      // caller's WT set
-      for (Iterator iterator = calleeIntersectBoundOverWriteSet.iterator(); iterator.hasNext();) {
-        NTuple<Descriptor> write = (NTuple<Descriptor>) iterator.next();
-        writtenSet.add(write);
-      }
+        // add heap path, which is an element of OVERWRITE_bound set, to the
+        // caller's WT set
+        for (Iterator iterator = calleeIntersectBoundOverWriteSet.iterator(); iterator.hasNext();) {
+          NTuple<Descriptor> write = (NTuple<Descriptor>) iterator.next();
+          writtenSet.add(write);
+        }
+      } 
 
     }
       break;
@@ -1339,6 +1399,17 @@ public class DefinitelyWrittenCheck {
 
   }
 
+  static public FieldDescriptor getArrayField(TypeDescriptor td) {
+    FieldDescriptor fd = mapTypeToArrayField.get(td);
+    if (fd == null) {
+      fd =
+          new FieldDescriptor(new Modifiers(Modifiers.PUBLIC), td, arrayElementFieldName, null,
+              false);
+      mapTypeToArrayField.put(td, fd);
+    }
+    return fd;
+  }
+
   private void mergeSharedLocationAnaylsis(ClearingSummary curr, Set<ClearingSummary> inSet) {
 
     if (inSet.size() == 0) {