public void CollectExistentialVars(Statement position, InitializedVariables iv)
 {
   // add to the (static) table one line (stmt, existential delayed variables that reach "stmt")
   nodeExistentialTable.Add(position, iv.MayHaveExistentialDelayedVars);
 }
 public NNArrayStatus(InitializedVariables ivs, HashSet vars, HashSet fields, HashSet zeroInts, InitializedVarStack stack) {
   this.ivs = ivs;
   this.vars = vars;
   this.fields = fields;
   this.zeroInts = zeroInts;
   this.stack = stack;
 }
 /// <summary>
 /// Returns an arraylist of delayed parameters of the current method, based on their status in the analysis
 /// (not based on whether they are declared as delayed).  
 /// </summary>
 /// <param name="ivs"> the state of variable-initialization (def-assign) analysis </param>
 /// <returns>Returns an arraylist of program variables that are delayed, according to a particular var-initialization
 /// analysis state</returns>
 private ArrayList delayedParameters (InitializedVariables ivs) {
   ArrayList result = new ArrayList();
   if (ivs == null) return result;
   if (this.mpc.currentMethod == null) return result;
   if (this.mpc.currentMethod.Parameters == null) return result;
   foreach (Parameter p in this.mpc.currentMethod.Parameters) {
     if (ivs.IsDelayed(p)) {
       result.Add(p);
     }
   }
   if (!this.mpc.currentMethod.IsStatic) {
     if (ivs.IsDelayed(this.mpc.currentMethod.ThisParameter)) {
       result.Add(this.mpc.currentMethod.ThisParameter);
     }
   }
   return result;
 }
 private bool CallOnThis(InitializedVariables iv, Variable receiver) {
   if (receiver == null) return false;
   if (this.mpc.currentMethod.ThisParameter != null
       && iv.IsEqual(receiver, this.mpc.currentMethod.ThisParameter)) {
     return true;
   }
   return false;
 }
 private void CheckTargetDelayLongerThanSource(InitializedVariables iv, Variable pointer, Variable source, TypeNode type, Node context) {
   if (type.IsValueType) return;
   if (iv.TargetDelayLongerThanSource(pointer, source)) return;
   Node offendingNode = (source.SourceContext.Document == null) ? context : source;
   if ((pointer == null || !mpc.reportedErrors.Contains(pointer)) && !mpc.reportedErrors.Contains(source)) {
     if (source.Name != null) {
       mpc.typeSystem.HandleError(offendingNode, Error.StoreIntoLessDelayedLocation, source.Name.Name);
     }
   }
 }
    /// <summary>
    /// The instantiated formal type is non-delayed unless the parameter is marked delayed and "delayedInstance" is true.
    /// [Existential Delay Change] When there is only one delayed argument, we allow it to be existential delayed
    /// This is done by keeping track of the number of possible delay matches. 
    /// if actual/formal is universal/universal, then this number (possibleDelayMatch) is not changed, we allow it only when
    ///      the number is not zero (the only way it can be zero at this point (delayinstance is true) is because
    ///      an existential/universal delay match happened.
    /// if actual/formal is existential/universal, then match happens only when the number is 1
    ///      number is changed to zero to disallow future existential/universal match
    /// Delay match error will be reported as delay not compatible with the witness. If the witness does not have an appropriate delay
    /// we do not report an error, which will be safe (see comments below).
    /// </summary>
    private void CheckParameterDelay(InitializedVariables iv, Variable actual, Method callee, Parameter p, 
      bool delayedInstance, Node context,
      int witness, int num) {
      if (actual == null) return;
      if (p == null) return;

      // Special check that we don't pass pointers to delayed objects by reference
      Reference r = p.Type as Reference;
      if (r != null && !r.ElementType.IsValueType) {
        if (iv.IsDelayed(actual) || iv.IsDelayedRefContents(actual)) {
          Node offendingNode = (actual.SourceContext.Document != null) ? actual : context;
          mpc.typeSystem.HandleError(offendingNode, Error.DelayedReferenceByReference);
          return;
        }
      }

      // delayed instance requires that for every delayed formal, the corresponding actual must
      // be committed to an appropriate delay type. 
      if (delayedInstance && this.IsUniversallyDelayed(p)) {
        // CanAssumeDelay Decides whether the actual 1) is of the same delay (universal delay) as the formal
        //                                        or 2) is bottom, thus can be assumed to be universal delay afterwards
        // CanAssumeDelay cannot decide, and thus returns false when actual is existentially delayed
        bool actualIsSameDelayAsFormal = iv.CanAssumeDelayed(actual);

        if (actualIsSameDelayAsFormal) { 
          return;
        }

        if (iv.IsExistentialDelayed(actual))
        {
          // errors, if any, has been handled already in MethodCallDelayInstance
          // return here to avoid falling into the error reporting below. 
          return;
        }

        // if p is a universally delayed parameter, while actual cannot take a delayed type, 
        // (e.g., it is top), report error
        Node offendingNode = (actual.SourceContext.Document != null) ? actual : context;
        if (p is This) {
          mpc.typeSystem.HandleError(offendingNode, Error.ReceiverMustBeDelayed);
        }
        else {
          if (num != witness) // note this is not an extra check, the fact that witness is the position of the
            // first known delayed actual doesnt mean it will match correctly (i.e., possibly delay match might
            // not be right. 
            // We are not losing warnings either because if num == witness, only if possiblyDelayMatch == 1
            // we will have no warning, in which case, we are guaranteed to have a delay match and won't reach here
          {
            mpc.typeSystem.HandleError(offendingNode, Error.ActualMustBeDelayed, num.ToString(), (witness==0)?"this(receiver)": "No."+witness.ToString());
          }
        }
        return;
      }
      else {
        /* 
        if (callee is InstanceInitializer && p is This && iv.IsBottom(actual)) {
          if (ThisIsSoleDelayedParameter(callee)) {
            // leave undetermined status of this.
            return;
          }
        }
        */
        // actual is known to be not delayed. CanAssumeNotDelay has this side effect to change
        // actual's delay type from bottom to nondelay if its type is not already nondelay
        if (iv.CanAssumeNotDelayed(actual)) {
          return;
        }
        // if its type is delayed, or top, report error... it is assumed that actual's type cannot 
        // be top, which, when violated (likely to happen), leads to inaccurate error message.
        // TODO: distinguish between actual's type being delayed or being top.
        Node offendingNode = (actual.SourceContext.Document != null) ? actual : context;
        if (p is This) {
        //  System.Console.WriteLine("p is Universally delayed: {0}", this.IsUniversallyDelayed(p));
        //  System.Console.WriteLine("delayInstance is {0}", delayedInstance);
        //  System.Console.WriteLine("{0} violates delay of {1}", actual, p);
        //  System.Console.WriteLine("Value of possible delay match:{0} ", possibleDelayMatch);
          mpc.typeSystem.HandleError(offendingNode, Error.ReceiverCannotBeDelayed);
        }
        else {
          //System.Console.WriteLine("{0} is offending {1} for function {2}", actual, p, callee.Name);
          //System.Console.WriteLine("delayinstance:{0}; possibleDelayMatch:{1}", delayedInstance, possibleDelayMatch);
          //iv.PrintStatus(actual);
          //System.Console.WriteLine("p is universally delayed: {0}", this.IsUniversallyDelayed(p));
          mpc.typeSystem.HandleError(offendingNode, Error.ActualCannotBeDelayed);
        }
        return;
      }
    }
    /// <summary>
    /// Merges two initialization stacks. 
    /// </summary>
    /// <param name="stack1">Input stack 1.</param>
    /// <param name="stack2">Input stack 2.</param>
    /// <returns>
    /// A new InitializedVarStack retvalue, such that:
    /// retvalue = {v | v in union(stack1, stack2) and v not in common trunk}
    /// "common trunk" = CDR^n (stack1) where n is the smallest non-negative integer such that
    /// there exists a non-negative m such that CDR ^m (stack2) = CDR ^n (stack1);
    /// </returns>
    public static InitializedVarStack Merge(InitializedVarStack stack1, InitializedVarStack stack2, InitializedVariables iv) {
      InitializedVarStack retvalue;

      // shallow one's depth
      int depth1 = stack1.layers.Count;
      int depth2 = stack2.layers.Count;

      // they may both be zero, which is contained by this case
      if (depth1 == depth2) {
        if (Same(stack1, stack2, iv)) {
          retvalue = new InitializedVarStack(stack1);
          return retvalue;
        }
        // if not the same, go on
      }

      // if one of them is zero, return the other
      if (depth1 == 0 ) {
        retvalue = new InitializedVarStack(stack2); 
        return retvalue;
      }
      if (depth2 == 0) {
        retvalue = new InitializedVarStack(stack1);
        return retvalue;
      }

      retvalue = new InitializedVarStack();

      int depth = depth1 > depth2 ? depth1 : depth2;
      InitializedVarStack shallowone = (depth1 < depth2) ? stack1 : stack2;
      InitializedVarStack deepone = (depth1 < depth2) ? stack2 : stack1;

      // shallow one's top must be the crush of the deep one's top |depth1-depth2| + 1 layers. 
      HashSet set = new HashSet();
      object[] array = deepone.layers.ToArray();
      for (int i = 0; i < Math.Abs(depth1 - depth2) +1 ; i++) {
        set = (HashSet)Set.Union(set, (HashSet)array[i]);
      }

      if (!ContainSameValue((HashSet)shallowone.layers.Peek(), set, iv)) {
        //Leave this print-out here to signal possible unknown problems.  
        if (Analyzer.Debug) {
          Console.WriteLine("New delayed value created not in all paths");
        }
        retvalue = new InitializedVarStack(shallowone);
        return retvalue;
      }

      // make a copy of shallow one and return
      retvalue = new InitializedVarStack(shallowone);
      
      // shallow one's CDR must be the same as the deeper one's 
      object[] array2 = shallowone.layers.ToArray();
      int diff = Math.Abs(depth1 - depth2); 
      for (int j = 1; j < array2.Length; j++) {
        if (!ContainSameValue((HashSet)array2[j], (HashSet)array[j + diff], iv)) {
          // TODO: This is unlikely to happen. Still should consider to report 
          // an error. 
        }
      }
      return retvalue;
    }
 private void CheckReturnNotDelay(InitializedVariables iv, Variable var, Node context) {
   if (var == null)
     return;
   if (!iv.CanAssumeNotDelayed(var) && !this.mpc.currentMethod.IsPropertyGetter) {
     if (!mpc.reportedErrors.Contains(var) && var.Name != null && var.Name.Name != "") {
       Error errorCode = Error.ReturnOfDelayedValue;
       Node offendingNode = (var.SourceContext.Document == null) ? context : var;
       mpc.typeSystem.HandleError(offendingNode, errorCode, var.Name.Name);
       mpc.reportedErrors.Add(var, null);
     }
   }
   iv.SetValueNonDelayed(var);
 }
    /// <summary>
    /// Standard check function, except that it returns a PreDAStatus data structure
    /// that contains the three tables mentioned above.
    /// </summary>
    /// <param name="t"></param>
    /// <param name="method"></param>
    /// <param name="analyzer"></param>
    /// <returns>A PreDAStatus data structure, or a null if error occurs. </returns>
    public static PreDAStatus Check(TypeSystem t, Method method, Analyzer analyzer) {
      Debug.Assert(method != null && analyzer != null);
      MethodReachingDefNNArrayChecker checker = new MethodReachingDefNNArrayChecker(t, analyzer, method);
      ControlFlowGraph cfg = analyzer.GetCFG(method);

      if (cfg == null)
        return null;

      InitializedVariables iv = new InitializedVariables(analyzer);
      NNArrayStatus status = new NNArrayStatus(iv);
      NNArrayStatus.Checker = checker;
      checker.Run(cfg, status);
      
      // Check whether there are arrays that have been created but not committed
      NNArrayStatus exitStatus2 = checker.exitState as NNArrayStatus;
      if (exitStatus2 != null) {
        if (Analyzer.Debug) {
          Console.WriteLine("exit state of {0} is", method.FullName);
          exitStatus2.Dump();
        }
        ArrayList notCommitted = exitStatus2.CreatedButNotInitedArrays();
        if (notCommitted != null && notCommitted.Count != 0) {
          foreach (object o in notCommitted) {
            string offendingString = "A non null element array";
            Node offendingNode = method;
            if (o is Variable) {
              offendingString = "Variable \'" + o + "\'";
              offendingNode = o as Variable;
            }
            if (o is Pair<Variable, Field>) {
              Pair<Variable, Field> pair = o as Pair<Variable, Field>;
              Variable var = pair.Fst;
              Field fld = pair.Snd;
              offendingString = "Field \'" + var + "." + fld + "\'";
              if (NNArrayStatus.FieldsToMB.ContainsKey(pair)) {
                offendingNode = NNArrayStatus.FieldsToMB[pair] as MemberBinding;
                if (offendingNode == null) {
                  offendingNode = fld;
                } else {
                  MemberBinding mb = offendingNode as MemberBinding;
                  if (mb.TargetObject == null || mb.SourceContext.SourceText == null) {
                    offendingNode = fld;
                  }
                }
              }
            }
            checker.HandleError(offendingNode, Error.ShouldCommit, offendingString);
          }
        }

        ArrayList notCommittedOnAllPaths = exitStatus2.CreatedButNotFullyCommittedArrays();
        if (notCommittedOnAllPaths != null && notCommittedOnAllPaths.Count != 0) {
          foreach (object o in notCommittedOnAllPaths) {
            string offendingString = "A non-null element array";
            Node offendingNode = method;
            if (o is Variable) {
              offendingString = "variable \'" + o + "\'";
              offendingNode = o as Variable;
            } else if (o is Pair<Variable, Field>) {
              Pair<Variable, Field> pair = o as Pair<Variable, Field>;
              Variable var = pair.Fst;
              Field fld = pair.Snd;
              if (NNArrayStatus.FieldsToMB.ContainsKey(pair)) {
                offendingNode = NNArrayStatus.FieldsToMB[pair] as MemberBinding;
                if (offendingNode == null) {
                  offendingNode = fld;
                } else {
                  MemberBinding mb = offendingNode as MemberBinding;
                  if (mb.TargetObject == null || mb.SourceContext.SourceText==null) {
                    offendingNode = fld;
                  }
                }
              }
              offendingString = "field \'" + var + "." + fld + "\'";
            }

            checker.HandleError(offendingNode, Error.ShouldCommitOnAllPaths, offendingString);
          }
        }
        if (checker.errors != null && checker.errors.Count != 0) {
          checker.HandleError();
          checker.errors.Clear();
          return null;
        }
      }
      return new PreDAStatus(checker.NotCommitted, checker.Committed, checker.OKTable, checker.NonDelayArrayTable);
    }
    /// <summary>
    /// Find out which layer (top: level 0) contains the value of variable v.
    /// If v is not on the stack, return -1;
    /// </summary>
    /// <param name="v"></param>
    /// <param name="iv"></param>
    /// <returns></returns>
    public int LevelOf(Variable v, InitializedVariables iv) {
      int depth = layers.Count;
      int i = 0;
      while (i < depth) {
        if (ContainsValueOf(v, iv, this[i])) {
          return i;
        }
        i++;
      }

      return -1;
    }
 /// <summary>
 /// Copy Constructor
 /// </summary>
 /// <param name="old"></param>
 public InitializedVariables(InitializedVariables old) {
   this.analyzer = old.analyzer;
   this.egraph = (IEGraph)old.egraph.Clone();
   this.referenceStatus = old.referenceStatus;
 }
    protected override IDataFlowState VisitBlock(CfgBlock block, IDataFlowState state) {
      Debug.Assert(block!=null);

      InitializedVariables onEntry = (InitializedVariables)state;
      currBlock=block;

      if (Analyzer.Debug) {
        Analyzer.Write("---------block: "+block.UniqueId+";");
        Analyzer.Write("   Exit:");
        foreach (CfgBlock b in block.NormalSuccessors)
          Analyzer.Write(b.UniqueId+";");
        if (block.UniqueSuccessor!=null)
          Analyzer.Write("   FallThrough: "+block.UniqueSuccessor+";");
        if (block.ExceptionHandler!=null)
          Analyzer.Write("   ExHandler: "+block.ExceptionHandler.UniqueId+";");
        Analyzer.WriteLine("");
        state.Dump();
      }
      if (block.ExceptionHandler!=null) {
        InitializedVariables exnState = onEntry;
        onEntry = new InitializedVariables(onEntry); // Copy state, since common ancestor cannot be modified any longer
        PushExceptionState(block, exnState);
      }

      InitializedVariables resultState = (InitializedVariables)base.VisitBlock(block, onEntry);
      if(block.UniqueId== cfg.NormalExit.UniqueId) {
        exitState=resultState;
      }
      return resultState;
      
    }
    /// <summary>
    /// Entry point of the check. 
    /// 
    /// It create a new instance of the checker, and run the checker on the given method.
    /// </summary>
    /// <param name="t"></param>
    /// <param name="method"></param>
    public static IDelayInfo  Check(TypeSystem t, Method method, Analyzer analyzer, PreDAStatus preResult) {
      Debug.Assert(method!=null && analyzer != null);
      MethodDefiniteAssignmentChecker checker= new MethodDefiniteAssignmentChecker(t, analyzer, preResult);
      checker.currentMethod=method;
      ControlFlowGraph cfg=analyzer.GetCFG(method);

      if(cfg==null)
        return null;

      InitializedVariables iv = new InitializedVariables(analyzer);
      checker.Run(cfg,iv);
      if (checker.exitState == null) {
        // Method has no normal return. We should consider having such method as annotated with [NoReturn].
        return checker.NodeExistentialTable;
      }
      InitializedVariables onExit = new InitializedVariables((InitializedVariables)checker.exitState);

      // check for unassigned Out parameters.
      ParameterList pl=checker.currentMethod.Parameters;
      if(pl!=null){
        for(int i=0; i < pl.Count; i++){
          Parameter p = pl[i];
          if(p.Type is Reference && p.IsOut && !onExit.IsAssignedRef(p, ((Reference)p.Type).ElementType as Struct))
            checker.typeSystem.HandleError(method.Name,Error.ParamUnassigned,p.Name.Name);
        }
      }
      // check for struct fields in constructor
      if (method is InstanceInitializer && method.DeclaringType != null && method.DeclaringType.IsValueType) {
        Field unassignedfield = onExit.NonAssignedRefField(method.ThisParameter, (Struct)method.DeclaringType);
        if (unassignedfield != null) {
          checker.typeSystem.HandleError(method, Error.UnassignedThis, checker.typeSystem.GetTypeName(unassignedfield.DeclaringType)+"."+unassignedfield.Name.Name);
        }
      }
      // if delayed constructor, check for field initializations here
      if (method is InstanceInitializer && checker.iVisitor.IsUniversallyDelayed(method.ThisParameter)) {
        checker.iVisitor.CheckCtorNonNullFieldInitialization(method.ThisParameter, method.Name, onExit, Error.NonNullFieldNotInitializedAtEndOfDelayedConstructor);
      }

      // Check for uninitialized base class
      if (method is InstanceInitializer
        && method.DeclaringType is Class
        && method.DeclaringType.BaseType != null
        && method.DeclaringType.BaseType != SystemTypes.MulticastDelegate
        && !onExit.IsBaseAssigned())
        checker.typeSystem.HandleError(method, Error.BaseNotInitialized);

      // Check for assigned but unreferenced variables.
      //TODO: this check should be moved to Looker so that constant folding does not affect it
      onExit.EmitAssignedButNotReferencedErrors(checker.typeSystem);

      return (checker.NodeExistentialTable);
    }
 static InitializedVarStack mergeStack(InitializedVarStack stack1, InitializedVarStack stack2, InitializedVariables ivs) {
   return InitializedVarStack.Merge(stack1, stack2, ivs);
 }
    // equals for two hash set of variables
    static bool ContainSameValue(HashSet s1, HashSet s2, InitializedVariables iv) {
      foreach (Variable v in s1) {
        if (!ContainsValueOf(v, iv, s2)) {
          return false;
        }
      }

      foreach (Variable v in s2) {
        if (!ContainsValueOf(v, iv, s1)) {
          return false;
        }
      }

      return true;
    }
 private void CheckNonDelay(InitializedVariables iv, Variable var, Node context, Error errorCode) {
   if (var == null)
     return;
   if (!iv.CanAssumeNotDelayed(var)) {
     if (!mpc.reportedErrors.Contains(var) && var.Name != null && var.Name.Name != "") {
       // Ugly hack to get delayed analysis past non-conformant use of get_FrameGuard.
       if (!(mpc.currentMethod.Name != null && mpc.currentMethod.Name.Name.StartsWith("get_SpecSharp::FrameGuard"))) {
         Node offendingNode = (var.SourceContext.Document == null) ? context : var;
         mpc.typeSystem.HandleError(offendingNode, errorCode, var.Name.Name);
         mpc.reportedErrors.Add(var, null);
       }
     }
   }
   iv.SetValueNonDelayed(var);
 }
    /// <summary>
    /// Whether two IVStacks are the same, alias wise.
    /// </summary>
    /// <returns></returns>
    static bool Same(InitializedVarStack stack1, InitializedVarStack stack2, InitializedVariables iv) {
      if (stack1.layers.Count != stack2.layers.Count) {
        return false;
      }
      object[] array1 = stack1.layers.ToArray();
      object[] array2 = stack2.layers.ToArray();
      for (int i = 0; i < array1.Length; i++) {
        if (!ContainSameValue((HashSet)array1[i], (HashSet)array2[i], iv)) {
          return false;
        }
      }

      return true;
    }
 private void CheckUse(InitializedVariables iv, Variable var, Node context){
   if (var==null) 
     return;
   if(var is This)
     return;
   else if(! iv.IsAssigned(var)) {
     if(!mpc.reportedErrors.Contains(var) && var.Name != null && var.Name.Name!=""){
       if (var.Name.Name.Equals("return value")){
         mpc.typeSystem.HandleError(mpc.currentMethod.Name, Error.ReturnExpected, mpc.typeSystem.GetMemberSignature(mpc.currentMethod));
         mpc.reportedErrors.Add(var,null);
       }else{
         Node offendingNode = (var.SourceContext.Document == null)?context:var;
         mpc.typeSystem.HandleError(offendingNode, Error.UseDefViolation, var.Name.Name);
         mpc.reportedErrors.Add(var, null);
       }
       iv.SetReferencedAfterError(var);
       return;
     }
     iv.SetValueAssignedAndNonDelayed(var);
   }
   iv.SetReferenced(var);
 }
    /// <summary>
    /// Whether a value or its alias is contained in a set, according to iv
    /// 
    /// iv contains alias information. 
    /// </summary>
    static bool ContainsValueOf(Variable v, InitializedVariables iv, HashSet set) {
      foreach (Variable u in set) {
        if (iv.HasSameValue(u, v)) {
          return true;
        }
      }

      return false;
    }
    /// <summary>
    /// Figure out how to instantiate the quantified delay of the method parameters (if any).
    /// We assume that each method has the form \forall T. where T is a delay. Parameters with the "Delayed" attribute
    /// are assumed to have type Delay(T). 
    /// Given the concrete arguments, this method determines if any parameter whose formal is delayed is actually delayed.
    /// [existential delay change]
    /// In addition, put the checking of existential delayed actuals here
    /// For error diagnostics purpose, we also note the position of the first delay-matched argument
    /// </summary>
    /// <param name="receiver"></param>
    /// <param name="callee"></param>
    /// <param name="arguments"></param>
    /// <returns></returns>
    public bool MethodCallDelayInstance(InitializedVariables iv, Variable receiver, Method callee, 
      ExpressionList arguments, Node context, out int witness)
    {
      Node off = receiver;
      witness = -1;

      if (receiver != null && this.IsUniversallyDelayed(callee.ThisParameter) && iv.IsDelayed(receiver)) {
        if (witness == -1) witness = 0;
      }
      if (callee.Parameters == null || arguments == null)
      {
        // dont have more parameters, not possible to have MoreThan2ExistentialDelay
        return (witness != -1);
      }
      for (int i = 0; i<callee.Parameters.Count; i++) {
        Parameter p = callee.Parameters[i];
        Variable arg = (Variable)arguments[i];
        if (this.IsUniversallyDelayed(p) && iv.IsDelayed(arg)) {
          if (iv.IsExistentialDelayed(arg))
          {
            if (witness != -1)
            {
              // report error
              Node offendingNode = (arg.SourceContext.Document != null) ? arg : context;
              mpc.typeSystem.HandleError(offendingNode, Error.ActualMustBeDelayed, (i+1).ToString(), 
                (witness == 0) ? "this(receiver)" : "No." + witness.ToString());
            };
            off = arg;
          }
          if (witness == -1) witness = i + 1;
        }
      }

      // System.Console.WriteLine("result is:{0}, numDelayMatch is {1}", result, numDelayMatch);
      return (witness != -1);
    }
    /// <summary>
    /// For a variable v, if, according to iv, its value is the same as one of the 
    /// variables kept on the top of stack, remove that value from the top of the stack.
    /// 
    /// </summary>
    /// <param name="v"> The variable.</param>
    /// <param name="iv"> An InitializedVariables data structure, where an EGraph supposedly
    /// maintains the alias information.
    /// </param>
    public void RemoveVar(Variable v, InitializedVariables iv) {

      if (layers!= null && layers.Count != 0) {
        HashSet set = (HashSet)layers.Peek();

        ArrayList toDelete = new ArrayList();

        foreach (Variable u in set) {
          if (iv.HasSameValue(u, v)) {
            toDelete.Add(u);
          }
        }

        if (toDelete.Count != 0) {
          foreach (object o in toDelete) {
            set.Remove(o);
          }
        }
      }
    }
 private void FixupNewlyConstructedObjectDelay(InitializedVariables iv, Variable receiver, InstanceInitializer ctor) {
   if (receiver == null) return;
   if (ctor == null) return;
 }
 public NNArrayStatus(NNArrayStatus nnas) {
   this.ivs = new InitializedVariables(nnas.ivs);
   this.vars = nnas.vars;
   this.fields = nnas.fields;
   this.zeroInts = nnas.zeroInts;
   stack = new InitializedVarStack(nnas.stack);
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="e"></param>
 /// <returns>
 /// true if 1) current method deos not contain a delayed parameter
 /// or 2) the type of concern does not contain a constructor that accepts delayed parameters otherthan 
 /// "this"
 /// </returns>
 private bool delayedParametersNoEffect(TypeNode type, InitializedVariables ivs, PreDAStatus nns, Statement s) {
   if (type == null) return false;
   bool result = false;
   // see if this element type can possibly 
   // have a constructor that accepts delayed parameters
   result = result || (!hasConstructorAcceptingDelay(type));
   result = result || nns.OKToCommit(s);
   return result;
 }
 /// <summary>
 /// This constructor is called at the beginning of checking a method.
 /// </summary>
 /// <param name="old"></param>
 public NNArrayStatus(InitializedVariables old) {
   this.ivs = old;
   vars = new HashSet();
   fields = new HashSet();
   fieldsToMB.Clear();
   this.zeroInts = new HashSet();
   stack = new InitializedVarStack();
 }
 public void CheckCtorNonNullFieldInitialization(Variable receiver, Node context, InitializedVariables iv, Error errorCode) {
   TypeSystem ts = this.mpc.typeSystem;
   Method currMethod = this.mpc.currentMethod;
   MemberList members = this.analyzer.GetTypeView(InitializedVariables.Canonical(currMethod.DeclaringType)).Members;
   for (int i = 0, n = members.Count; i < n; i++) {
     Field f = members[i] as Field;
     if (f == null) continue;
     if (f.IsStatic) continue; // don't worry about static fields here, this is only for instance fields
     if (!ts.IsNonNullType(f.Type)) continue;
     //if (f.IsModelfield) continue; //modelfields are assigned to implicitly, by a pack. But what about non-null modelfields and explicit superclass constructor calls?
     if (!iv.IsAssignedStructField(receiver, f)) {
       if (currMethod.HasCompilerGeneratedSignature) {
         // then it was a default ctor created for the class and the error message
         // should point at the field's declaration
         if (!(currMethod.DeclaringType is ClosureClass))
           ts.HandleError(f, Error.NonNullFieldNotInitializedByDefaultConstructor, ts.GetMemberSignature(f));
       }
       else {
         // the error message should point at the explicit base call that the user wrote or the one
         // inserted by the compiler
         ts.HandleError(context, errorCode, ts.GetMemberSignature(f));
       }
     }
   }
 }
    public static InitializedVariables Merge(InitializedVariables atMerge, InitializedVariables incoming, CfgBlock joinPoint) {
      bool unchanged;
      IEGraph result = atMerge.egraph.Join(incoming.egraph, joinPoint, out unchanged);

      if (unchanged) return null;
      return new InitializedVariables(incoming.analyzer, result, atMerge.referenceStatus);
    }