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