/// <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);
    }
 public DefiniteAssignmentInstructionVisitor(Analyzer analyzer, MethodDefiniteAssignmentChecker m,
   PreDAStatus preResult){
   mpc=m;
   //reportedErrors=new Hashtable();
   this.analyzer = analyzer;
   nns = preResult;
 }
Ejemplo n.º 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);
            }
        }