/// <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(); }
/// <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); } }