/// <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>
 /// Constructor
 /// </summary>
 /// <param name="analyzer"></param>
 /// <param name="m"></param>
 public ReachingDefNNArrayInstructionVisitor(Analyzer analyzer, MethodReachingDefNNArrayChecker m) {
   this.analyzer = analyzer;
   checker = m;
   delayedParameters = DelayedParameters();
 }
Example #3
0
        /// <summary>
        /// Put general analysis targeting to general IL properties.
        /// </summary>
        /// <param name="method"></param>
        protected void GeneralAnalysis(Method method)
        {
            nonNullInfo = null;

            if (!this.CodeIsWellFormed)
            {
                return;
            }

            if (debug)
            {
                ControlFlowGraph cfg = GetCFG(method);
                if (cfg != null)
                {
                    cfg.Display(Console.Out);
                }
            }

            if (!method.Name.Name.StartsWith("Microsoft.Contracts"))
            {
                // Definite assignment checking

                //System.Console.WriteLine("--------------- Analyzing Method: {0}", method.Name);


                if (this.DefiniteAssignmentChecking)
                {
                    // For every statement, three things are returned from this pre- stage analysis
                    // 1) which program vars (that represent NN arrays) are created but not committed
                    // 2) which program vars (that represent NN arrays) are created and committed between
                    //    the creation and commitment of current array.
                    // 3) if the statement is a commitment call for an NN array, whether it
                    //    is ok to lift the array to be non-delayed.
                    PreDAStatus preAnalysisResult = MethodReachingDefNNArrayChecker.Check(typeSystem, method, this);
                    if (preAnalysisResult != null)
                    {
                        delayInfo = MethodDefiniteAssignmentChecker.Check(typeSystem, method, this, preAnalysisResult);
                    }
                }
                if (Analyzer.Debug)
                {
                    if (delayInfo != null)
                    {
                        System.Console.WriteLine("----- delay info count: {0}", delayInfo.Count());
                    }
                }

                if (this.ExposureChecking)
                {
                    ExposureChecker.Check(typeSystem, method, this);
                }

                // NonNull checking
                if (this.NonNullChecking)
                {
                    nonNullInfo = NonNullChecker.Check(typeSystem, method, this);
                }

                //System.Console.WriteLine("---------------- Finished Analyzing Method:{0}", method.Name);
            }
        }