/// <summary>
        /// It visits an individual statement. It is called from VisitBlock.
        ///
        /// It calls NonNullInstructionVisitor
        /// </summary>
        /// <param name="block"></param>
        /// <param name="statement"></param>
        /// <param name="dfstate"></param>
        /// <returns></returns>
        protected override IDataFlowState VisitStatement(CfgBlock block, Statement statement, IDataFlowState dfstate)
        {
            // For debug purpose
            if (Analyzer.Debug)
            {
                try{
                    Analyzer.WriteLine("\n:::" + new SampleInstructionVisitor().Visit(statement, null) + "   :::   " + statement.SourceContext.SourceText);
                }catch (Exception e) {
                    Analyzer.WriteLine("Print error: " + statement + ": " + e.Message);
                }
            }

            IDataFlowState result = null;

            try{
                result = (IDataFlowState)(iVisitor.Visit(statement, dfstate));
            }catch (Exception e) {
                typeSystem.HandleError(statement, Cci.Error.InternalCompilerError, ":NonNull:" + e.Message);
                Console.WriteLine(e.StackTrace);
            }
            if (result != null && Analyzer.Debug)
            {
                result.Dump();
            }
            return(result);
        }
        /// <summary>
        /// It split exceptions for current handler and the next chained handler.
        ///
        /// It will:
        ///
        ///   If the exception is completely intercepted by current handler, the
        ///   exception will be consumed.
        ///
        ///   If the exception caught but not completely, both current handler and
        ///   the next handler will take the states.
        ///
        ///   If the exception is irrelevant to current caught, the next handler
        ///   will take over the state. Current handler is then bypassed.
        /// </summary>
        /// <param name="handler"></param>
        /// <param name="currentHandlerState"></param>
        /// <param name="nextHandlerState"></param>
        protected override void SplitExceptions(CfgBlock handler, ref IDataFlowState currentHandlerState, out IDataFlowState nextHandlerState)
        {
            Debug.Assert(currentHandlerState != null, "Internal error in NonNull Analysis");

            ExposureState state = (ExposureState)currentHandlerState;

            if (handler == null || handler.Length == 0)
            {
                nextHandlerState = null;
                return;
            }

            if (handler[0] is Unwind)
            {
                nextHandlerState    = null;
                currentHandlerState = null;
                return;
            }

            Debug.Assert(handler[0] is Catch, "Exception Handler does not starts with Catch");

            Debug.Assert(state.currentException != null, "No current exception to handle");

            Catch c = (Catch)handler[0];

            if (handler.ExceptionHandler != null &&
                !state.currentException.IsAssignableTo(c.Type))
            {
                nextHandlerState = state;;
            }
            else
            {
                nextHandlerState = null;
            }

            // Compute what trickles through to the next handler
            //  and what sticks to this handler.
            if (state.currentException.IsAssignableTo(c.Type))
            {
                // everything sticks
                nextHandlerState = null;
            }
            else if (c.Type.IsAssignableTo(state.currentException))
            {
                // c sticks, rest goes to next handler
                nextHandlerState = state;

                // copy state to modify the currentException
                state = new ExposureState(state);
                state.currentException = c.Type;
                currentHandlerState    = state;
            }
            else
            {
                // nothing stick all goes to next handler
                nextHandlerState    = state;
                currentHandlerState = null;
            }
            return;
        }
Beispiel #3
0
        /// <summary>
        /// Merge the new pending state with the old pending states.
        /// </summary>
        /// <returns>merged pending state</returns>
        private IDataFlowState JoinWithPendingState(CfgBlock prev, CfgBlock block, IDataFlowState newState)
        {
            if (Tracing)
            {
                Console.WriteLine("JoinWithPendingState: block {0} -> {1}",
                                  (prev).UniqueKey,
                                  (block).UniqueKey);
            }

            IDataFlowState pending = PendingState(block);
            // note, we call Merge even if old is null.
            bool changed;
            bool precise;

            if (Tracing)
            {
                SourceContext sc = (block).SourceContext;

                if (sc.Document == null && block.Length > 0)
                {
                    sc = ((Statement)block[0]).SourceContext;
                }
                Console.WriteLine("Join with pending state at line {0}", sc.StartLine);
            }

            IDataFlowState merged = this.Merge(prev, block, pending, newState, out changed, out precise);

            if (Tracing)
            {
                Console.WriteLine("Join changed {0}", changed);
            }
            return(merged);
        }
Beispiel #4
0
 /// <summary>
 /// Compute the join of two data flow states at the given block.
 /// </summary>
 /// <param name="previous">Predecessor block for this new state</param>
 /// <param name="joinPoint">Block at which join is computed</param>
 /// <param name="atMerge">Old state at this block. Can be null, in which case the incoming state
 /// is the first non-bottom state. In this case, the method must set changed
 ///  <c>resultDiffersFromPreviousMerge</c> to true.</param>
 /// <param name="incoming">New data flow state flowing to this block.</param>
 /// <param name="resultDiffersFromPreviousMerge">Boolean for fix point. If the state after
 /// the merge is equal to the old <c>atMerge</c> state, set to false, otherwise set to true.</param>
 /// <param name="mergeIsPrecise">can be set to true if the merged result state strictly contains only
 /// information representing either the atMerge or the incoming state, but no extra approximation. If
 /// this information cannot be determined by the merge, it must return false. True can only be returned
 /// if result is truly precise.</param>
 /// <returns>The new merged state.</returns>
 protected abstract IDataFlowState Merge(
     CfgBlock previous,
     CfgBlock joinPoint,
     IDataFlowState atMerge,
     IDataFlowState incoming,
     out bool resultDiffersFromPreviousMerge,
     out bool mergeIsPrecise
     );
Beispiel #5
0
 private void SetPendingState(CfgBlock block, IDataFlowState pending)
 {
     pendingStates[block.Index] = pending;
     if (Tracing)
     {
         Console.WriteLine("SetPendingState: block {0}", (block).UniqueKey);
     }
 }
Beispiel #6
0
        /// <summary>
        /// Like PendingState returns the pending state for the given block, but
        /// it also sets the pending state for this block to null.
        /// </summary>
        /// <returns>old pending state</returns>
        private IDataFlowState PopPendingState(CfgBlock block)
        {
            IDataFlowState pending = pendingStates[block.Index];

            pendingStates[block.Index] = null;

            if (Tracing)
            {
                Console.WriteLine("PopPendingState: block {0}", (block).UniqueKey);
            }
            return(pending);
        }
Beispiel #7
0
 protected override IDataFlowState Merge(CfgBlock previous, CfgBlock joinPoint, IDataFlowState atMerge,
                                         IDataFlowState incoming, out bool resultDiffersFromPreviousMerge, out bool mergeIsPrecise)
 {
     resultDiffersFromPreviousMerge = false;
     mergeIsPrecise = true;
     if (atMerge == null)
     {
         resultDiffersFromPreviousMerge = true;
     }
     atMerge = incoming;
     return(atMerge);
 }
Beispiel #8
0
        /// <summary>
        /// Add the given state to the pending states of the target block. If
        /// the block is enabled (by the pending edge count optimization), add the
        /// block to the worklist.
        ///
        /// Inv: DoneState => PendingState /\ PendingState != null => InQueue
        ///
        /// Cases:
        ///   1. Done => new, nothing to do
        ///   2. Done |_| new is precise.  Pend' = Pend |_| new,  Done' = Done |_| new
        ///   3. Done |_| new is imprecise.  Pend' = Done |_| new,  Done' = Done |_| new
        /// </summary>
        public void PushState(
            CfgBlock currentBlock,
            CfgBlock nextBlock,
            IDataFlowState state
            )
        {
            if (Tracing)
            {
                Console.WriteLine("PushState: block {0} -> {1}",
                                  (currentBlock).UniqueKey,
                                  (nextBlock).UniqueKey);
            }


            // state == null signals that branch is infeasible
            if (state == null)
            {
                return;
            }

            bool precise;
            // Add state to done state
            IDataFlowState stillPending = this.StateToReanalyzeBlock(currentBlock, nextBlock, state, out precise);

            if (stillPending == null)
            {
                if (Tracing)
                {
                    Console.WriteLine("PushState: block {0} no new information for pending state.",
                                      (nextBlock).UniqueKey);
                }
                return;
            }

            if (precise)
            {
                // join stillPending to old pending.
                stillPending = this.JoinWithPendingState(currentBlock, nextBlock, stillPending);
            }
            this.SetPendingState(nextBlock, stillPending);

            // when dequeued, the pending state is what the block needs to be analyzed under.
            //
            joinWorkItems.Enqueue(nextBlock);
            if (Tracing)
            {
                Console.WriteLine("PushState: block {0} put on work queue.",
                                  (nextBlock).UniqueKey);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Default per block visitor. Called from Run.
        ///
        /// It calls VisitStatement on each statement in a block.
        ///
        /// The result of this method is used as the state for all normal control flow successors.
        /// To push state onto an exception handler, use the PushExceptionState method. Furthermore, for
        /// conditional branches, different states can be pushed onto the true and false branches directly
        /// by calling PushPending. In that case, null should be returned from the method in order to avoid pushing
        /// the returned state onto both true and false targets again.
        /// </summary>
        protected virtual IDataFlowState VisitBlock(CfgBlock block, IDataFlowState stateOnEntry)
        {
            IDataFlowState currentState = stateOnEntry;

            for (int i = 0; i < block.Length; i++)
            {
                if (currentState == null)
                {
                    return(null);
                }

                currentState = this.VisitStatement(block, (Statement)block[i], currentState);
            }

            return(currentState);
        }
 protected override IDataFlowState VisitStatement(CfgBlock block, Statement statement, IDataFlowState dfstate) {
   // For debug purpose
   try{
     Analyzer.WriteLine(new SampleInstructionVisitor().Visit(statement,null)+"   :::   " +statement.SourceContext.SourceText);
   }catch(Exception){
     Analyzer.WriteLine("Print error: "+statement);
   }
   IDataFlowState result=null;
   try{
     result =(IDataFlowState)(iVisitor.Visit(statement,dfstate));
   }catch(ModifiesException e){
     typeSystem.HandleError(statement,System.Compiler.Error.Warning,":"+e.Message);
   }catch(Exception e){
     typeSystem.HandleError(statement,System.Compiler.Error.Warning,":CFG1:"+e.Message);
   }
   Analyzer.WriteLine(dfstate);
   return dfstate;
 }
    protected override IDataFlowState VisitBlock(CfgBlock block, IDataFlowState stateOnEntry) {
      Debug.Assert(block!=null);

      currentBlock=block;

      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("");

      NonNullables newState=new NonNullables(stateOnEntry);
      if (block.ExceptionHandler!=null)
        this.PushExceptionState(block,newState);
      return base.VisitBlock (block, newState);
    }
Beispiel #12
0
        protected override IDataFlowState VisitBlock(CfgBlock block, IDataFlowState stateOnEntry)
        {
            IDataFlowState resultState = stateOnEntry;

            IDataFlowState newState = new MyState();

            if (block.ExceptionHandler != null)
            {
                this.PushExceptionState(block, newState);
            }

            resultState = base.VisitBlock(block, newState);

            if (block.UniqueId == cfg.NormalExit.UniqueId)
            {
            }

            if (block.UniqueId == cfg.ExceptionExit.UniqueId)
            {
            }

            return(resultState);
        }
Beispiel #13
0
        /// <summary>
        /// Starts the analysis at the first instruction of the given block
        /// </summary>
        protected virtual void Run(ControlFlowGraph cfg, CfgBlock startBlock, IDataFlowState startState)
        {
            this.Reinitialize(cfg);

            pendingStates[startBlock.Index] = startState;
            joinWorkItems.Enqueue(startBlock);

            while (joinWorkItems.Count > 0)
            {
                //joinWorkItems.Dump();
                CfgBlock currentBlock = joinWorkItems.Dequeue();

                if (Analyzer.Debug)
                {
                    Console.WriteLine("\n*** Working on block {0} [{1} statements, line {2}]\n",
                                      ((currentBlock).UniqueKey),
                                      currentBlock.Length,
                                      (currentBlock.Length == 0)? -1 : ((Statement)currentBlock[0]).SourceContext.StartLine);
                }

                // Flow the current state through the block.
                IDataFlowState currentState = PopPendingState(currentBlock);

                currentState = VisitBlock(currentBlock, currentState);

                // NOTE: VisitBlock may have explicitly pushed states onto some successors. In that case
                // it should return null to avoid this code pushing the same state onto all successors.

                if (currentState != null)
                {
                    foreach (CfgBlock succ in currentBlock.NormalSuccessors)
                    {
                        PushState(currentBlock, succ, currentState);
                    }
                }
            } //while
        }
Beispiel #14
0
        /// <summary>
        /// Push the given state onto the handler of the block.
        /// This causes call-backs to SplitException in order to correctly distribute
        /// the exception state among different nested handlers.
        /// </summary>
        /// <param name="currentBlock">Block from which exception escapes</param>
        /// <param name="state">state on exception flow</param>
        public void PushExceptionState(
            CfgBlock currentBlock,
            IDataFlowState state
            )
        {
            IDataFlowState currentHandlerState = state;
            CfgBlock       currentHandler      = currentBlock;
            IDataFlowState nextHandlerState;

            while (currentHandlerState != null)
            {
                Debug.Assert(currentHandler.ExceptionHandler != null,
                             String.Format("block {0} does not have an exception handler",
                                           (currentHandler).UniqueKey));

                currentHandler = currentHandler.ExceptionHandler;

                if (Tracing)
                {
                    Console.WriteLine("PushExceptionState (in loop): block {0} -> {1}",
                                      (currentBlock).UniqueKey,
                                      (currentHandler).UniqueKey);
                }

                SplitExceptions(currentHandler, ref currentHandlerState, out nextHandlerState);

                /// We allow SplitExceptions to make decisions about not propagating any exceptions
                /// Debug.Assert(currentHandlerState != null || nextHandlerState != null);

                if (currentHandlerState != null)
                {
                    PushState(currentBlock, currentHandler, currentHandlerState);
                }

                currentHandlerState = nextHandlerState;
            }
        }
        /// <summary>
        /// Implementation of visit Block. It is called from run.
        ///
        /// It calls VisitStatement.
        /// </summary>
        /// <param name="block"></param>
        /// <param name="stateOnEntry"></param>
        /// <returns></returns>
        protected override IDataFlowState VisitBlock(CfgBlock block, IDataFlowState stateOnEntry)
        {
            Debug.Assert(block != null);

            currBlock = block;

            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("");

            ExposureState newState;

            if (stateOnEntry == null)
            {
                newState = new ExposureState(typeSystem);
            }
            else
            {
                newState = new ExposureState((ExposureState)stateOnEntry);
            }
//      if (block.ExceptionHandler!=null)
//        this.PushExceptionState(block,newState);
            return(base.VisitBlock(block, newState));
        }
    /// <summary>
    /// Starts the analysis at the first instruction of the given block
    /// </summary>
    protected virtual void Run (ControlFlowGraph cfg, CfgBlock startBlock, IDataFlowState startState) 
    {
      this.Reinitialize(cfg);

      pendingStates[startBlock.Index] = startState;
      joinWorkItems.Enqueue(startBlock);

      while (joinWorkItems.Count > 0) 
      {
        //joinWorkItems.Dump();
        CfgBlock currentBlock = joinWorkItems.Dequeue();	

        if (Analyzer.Debug) 
        {
          Console.WriteLine("\n*** Working on block {0} [{1} statements, line {2}]\n", 
            ((currentBlock).UniqueKey), 
            currentBlock.Length, 
            (currentBlock.Length == 0)? -1 : ((Statement)currentBlock[0]).SourceContext.StartLine);
        }

        // Flow the current state through the block.
        IDataFlowState currentState = PopPendingState(currentBlock);
				
        currentState = VisitBlock(currentBlock, currentState);

        // NOTE: VisitBlock may have explicitly pushed states onto some successors. In that case
        // it should return null to avoid this code pushing the same state onto all successors.

        if (currentState != null) 
        {
          foreach (CfgBlock succ in currentBlock.NormalSuccessors) 
          {
            PushState(currentBlock, succ, currentState);
          }
        }

      } //while
    }
 /// <summary>
 /// Visit the statement. It calls the instruction visitor to perform the transfer function
 /// </summary>
 /// <param name="block"></param>
 /// <param name="statement"></param>
 /// <param name="dfstate"></param>
 /// <returns></returns>
 protected override IDataFlowState VisitStatement(CfgBlock block, Statement statement, IDataFlowState dfstate)
 {
     PointsToAndWriteEffects ptwe = (PointsToAndWriteEffects)dfstate;
     // PointsToAndWriteEffects ptweOld = new PointsToAndWriteEffects(ptwe);
     IDataFlowState res = base.VisitStatement(block, statement, dfstate);
     return res;
     
 }
Beispiel #18
0
    /// <summary>
    /// Compute the Dataflow analysis for the given method
    /// Returns true if the method is pure
    /// </summary>
    /// <param name="method"></param>
    /// <returns></returns>

    public bool ComputePointsToStateFor(Method method)
    {

      // Get or compute the CFG
      ControlFlowGraph cfg = pointsToStateAnalysys.GetCFG(method);

      //if (PointsToAnalysis.debug)
      //    CodePrinter.PrintMethod(method);

      PointsToState initialState = this.pointsToStateAnalysys.Factory.NewElement(method);


      // If we can compute de CFG and the method is not unsafe
      // We compute the dataflow analysis
      if (cfg != null && !PointsToAnalysis.IsUnsafe(method))
      {

        ComputeBeforeDataflow(method);
        this.Run(cfg, initialState);

        if (exitState == null)
        {
          if (PointsToAnalysis.debug)
              Console.WriteLine("Method {0} exitState NULL", method.GetFullUnmangledNameWithTypeParameters());
        }
        // FIX
        PointsToState PointsToStateAtExit = (PointsToState)exitState;
        ComputeAfterDataflow(method);

        return true;
      }
      else
      {
        exitState = null;
        return false;
      }
    }
        /// <summary>
        /// Merge the two states for current block.
        /// </summary>
        /// <param name="previous"></param>
        /// <param name="joinPoint"></param>
        /// <param name="atMerge"></param>
        /// <param name="incoming"></param>
        /// <param name="resultDiffersFromPreviousMerge"></param>
        /// <param name="mergeIsPrecise"></param>
        /// <returns></returns>
        protected override IDataFlowState Merge(CfgBlock previous, CfgBlock joinPoint, IDataFlowState atMerge, IDataFlowState incoming, out bool resultDiffersFromPreviousMerge, out bool mergeIsPrecise)
        {
            mergeIsPrecise = false;

            // No new states;
            if (incoming == null)
            {
                resultDiffersFromPreviousMerge = false;
                return(atMerge);
            }

            // Initialize states
            if (atMerge == null)
            {
                resultDiffersFromPreviousMerge = true;
                return(incoming);
            }

            if (Analyzer.Debug)
            {
                Console.WriteLine("Merge at Block {0}-----------------", (joinPoint).UniqueKey);
                Console.WriteLine("  State at merge");
                atMerge.Dump();
                Console.WriteLine("  Incoming");
                incoming.Dump();
            }

            // Merge the two.

            ExposureState newState = ExposureState.Join((ExposureState)atMerge, (ExposureState)incoming, joinPoint);

            if (newState != null)
            {
                if (Analyzer.Debug)
                {
                    Console.WriteLine("\n  Merged State");
                    newState.Dump();
                }
                resultDiffersFromPreviousMerge = true;
                return(newState);
            }

            if (Analyzer.Debug)
            {
                Console.WriteLine("Merged state same as old.");
            }
            resultDiffersFromPreviousMerge = false;
            return(atMerge);
        }
Beispiel #20
0
 protected override IDataFlowState VisitBlock(CfgBlock block, IDataFlowState stateOnEntry)
 {
     //if (IsInstrumentationCode(block))
     //    return stateOnEntry;
     return(base.VisitBlock(block, stateOnEntry));
 }
Beispiel #21
0
 /// <summary>
 /// Splits the exceptions into the ones that this handler will handle and the ones that should
 /// <code>currentHandlerState</code> and <code>nextHandlerState</code> cannot both be null.
 /// On exit, if <code>currentHandlerState</code> is null, <code>handler</code> handles no exceptions,
 /// and if <code>nextHandlerState</code> is null, <code>handler</code> handles all the exceptions in
 /// the initial exception set of <code>currentHandlerState</code>.
 /// </summary>
 // go on to the next handler. currentHandlerState and next
 protected abstract void SplitExceptions(
     CfgBlock handler,
     ref IDataFlowState currentHandlerState, out IDataFlowState nextHandlerState
     );
Beispiel #22
0
        /// <summary>
        /// Default per statement visitor called from the default VisitBlock.
        /// Does identity transformation. Subclasses either override this method
        /// if the default block handling is sufficient, or they override the Visit method for blocks.
        ///
        /// The result of this method is used as the state for all normal control flow successors.
        /// To push state onto an exception handler, use the PushExceptionState method. Furthermore, for
        /// conditional branches, different states can be pushed onto the true and false branches directly
        /// by calling PushPending. In that case, null should be returned from the method in order to avoid pushing
        /// the returned state onto both true and false targets again.
        /// </summary>
        protected virtual IDataFlowState VisitStatement(CfgBlock block, Statement statement, IDataFlowState dfstate)
        {
            // simple case analysis to distinguish throws
            switch (statement.NodeType)
            {
            case NodeType.Throw:
            case NodeType.Rethrow:
            {
                PushExceptionState(block, dfstate);
                return(null);
            }

            default:
                return(dfstate);
            }
        }
    /// <summary>
    /// It visits an individual statement. It is called from VisitBlock.
    /// 
    /// It calls NonNullInstructionVisitor
    /// </summary>
    /// <param name="block"></param>
    /// <param name="statement"></param>
    /// <param name="dfstate"></param>
    /// <returns></returns>
    protected override IDataFlowState VisitStatement(CfgBlock block, Statement statement, IDataFlowState dfstate) {
      // For debug purpose
      if (Analyzer.Debug) {
        try{
          Analyzer.WriteLine("\n:::"+new SampleInstructionVisitor().Visit(statement,null)+"   :::   " +statement.SourceContext.SourceText);
        }catch(Exception e){
          Analyzer.WriteLine("Print error: "+statement+": "+e.Message);
        }
      }

      IDataFlowState result=null;
      try{
        result =(IDataFlowState)(iVisitor.Visit(statement,dfstate));
      }catch(Exception e){
        typeSystem.HandleError(statement,Cci.Error.InternalCompilerError,":NonNull:"+e.Message);
		    Console.WriteLine(e.StackTrace);
      }
      if (result != null && Analyzer.Debug){
        result.Dump();
      }
      return result;
    }
    /// <summary>
    /// Implementation of visit Block. It is called from run.
    /// 
    /// It calls VisitStatement.
    /// </summary>
    /// <param name="block"></param>
    /// <param name="stateOnEntry"></param>
    /// <returns></returns>
    protected override IDataFlowState VisitBlock(CfgBlock block, IDataFlowState stateOnEntry) {
      Debug.Assert(block!=null);

      currBlock=block;

      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("");

      ExposureState newState;
      if(stateOnEntry==null)
        newState=new ExposureState(typeSystem);
      else
        newState=new ExposureState((ExposureState)stateOnEntry);
//      if (block.ExceptionHandler!=null)
//        this.PushExceptionState(block,newState);
      return base.VisitBlock (block, newState);
    }
    /// <summary>
    /// Merge the two states for current block.
    /// </summary>
    /// <param name="previous"></param>
    /// <param name="joinPoint"></param>
    /// <param name="atMerge"></param>
    /// <param name="incoming"></param>
    /// <param name="resultDiffersFromPreviousMerge"></param>
    /// <param name="mergeIsPrecise"></param>
    /// <returns></returns>
    protected override IDataFlowState Merge(CfgBlock previous, CfgBlock joinPoint, IDataFlowState atMerge, IDataFlowState incoming, out bool resultDiffersFromPreviousMerge, out bool mergeIsPrecise) {

      mergeIsPrecise = false;
    
      // No new states;
      if(incoming==null) {
        resultDiffersFromPreviousMerge = false;
        return atMerge;
      }

      // Initialize states
      if(atMerge==null){
        resultDiffersFromPreviousMerge = true;
        return incoming;
      }

      if (Analyzer.Debug) {
        Console.WriteLine("Merge at Block {0}-----------------", (joinPoint).UniqueKey);
        Console.WriteLine("  State at merge");
        atMerge.Dump();
        Console.WriteLine("  Incoming");
        incoming.Dump();
      }

      // Merge the two.
      
      ExposureState newState = ExposureState.Join((ExposureState)atMerge, (ExposureState)incoming, joinPoint);

      if (newState != null) {
        if (Analyzer.Debug) {
          Console.WriteLine("\n  Merged State");
          newState.Dump();
        }
        resultDiffersFromPreviousMerge = true;
        return newState;
      }

      if (Analyzer.Debug) {
        Console.WriteLine("Merged state same as old.");
      }
      resultDiffersFromPreviousMerge = false;
      return atMerge;
    }
 private void SetPendingState (CfgBlock block, IDataFlowState pending) 
 {
   pendingStates[block.Index] = pending;
   if (Tracing) 
   {
     Console.WriteLine("SetPendingState: block {0}", (block).UniqueKey);
   }
 }
 /// <summary>
 /// Splits the exceptions into the ones that this handler will handle and the ones that should
 /// <code>currentHandlerState</code> and <code>nextHandlerState</code> cannot both be null.
 /// On exit, if <code>currentHandlerState</code> is null, <code>handler</code> handles no exceptions,
 /// and if <code>nextHandlerState</code> is null, <code>handler</code> handles all the exceptions in
 /// the initial exception set of <code>currentHandlerState</code>.
 /// </summary>
 // go on to the next handler. currentHandlerState and next
 protected abstract void SplitExceptions (
   CfgBlock handler, 
   ref IDataFlowState currentHandlerState, out IDataFlowState nextHandlerState
   );
 /// <summary>
 /// Compute the join of two data flow states at the given block.
 /// </summary>
 /// <param name="previous">Predecessor block for this new state</param>
 /// <param name="joinPoint">Block at which join is computed</param>
 /// <param name="atMerge">Old state at this block. Can be null, in which case the incoming state
 /// is the first non-bottom state. In this case, the method must set changed
 ///  <c>resultDiffersFromPreviousMerge</c> to true.</param>
 /// <param name="incoming">New data flow state flowing to this block.</param>
 /// <param name="resultDiffersFromPreviousMerge">Boolean for fix point. If the state after
 /// the merge is equal to the old <c>atMerge</c> state, set to false, otherwise set to true.</param>
 /// <param name="mergeIsPrecise">can be set to true if the merged result state strictly contains only
 /// information representing either the atMerge or the incoming state, but no extra approximation. If
 /// this information cannot be determined by the merge, it must return false. True can only be returned
 /// if result is truly precise.</param>
 /// <returns>The new merged state.</returns>
 protected abstract IDataFlowState Merge (
   CfgBlock previous, 
   CfgBlock joinPoint, 
   IDataFlowState atMerge, 
   IDataFlowState incoming, 
   out bool resultDiffersFromPreviousMerge,
   out bool mergeIsPrecise
   );
 /// <summary>
 /// Default per statement visitor called from the default VisitBlock.
 /// Does identity transformation. Subclasses either override this method
 /// if the default block handling is sufficient, or they override the Visit method for blocks.
 /// 
 /// The result of this method is used as the state for all normal control flow successors.
 /// To push state onto an exception handler, use the PushExceptionState method. Furthermore, for
 /// conditional branches, different states can be pushed onto the true and false branches directly
 /// by calling PushPending. In that case, null should be returned from the method in order to avoid pushing
 /// the returned state onto both true and false targets again.
 /// </summary>
 protected virtual IDataFlowState VisitStatement (CfgBlock block, Statement statement, IDataFlowState dfstate) 
 {
   // simple case analysis to distinguish throws
   switch (statement.NodeType) 
   {
     case NodeType.Throw:
     case NodeType.Rethrow:
     {
       PushExceptionState(block, dfstate);
       return null;
     }
     default:
       return dfstate;
   }
 }
    /// <summary>
    /// Default per block visitor. Called from Run.
    /// 
    /// It calls VisitStatement on each statement in a block. 
    /// 
    /// The result of this method is used as the state for all normal control flow successors.
    /// To push state onto an exception handler, use the PushExceptionState method. Furthermore, for
    /// conditional branches, different states can be pushed onto the true and false branches directly
    /// by calling PushPending. In that case, null should be returned from the method in order to avoid pushing
    /// the returned state onto both true and false targets again.
    /// </summary>
    protected virtual IDataFlowState VisitBlock (CfgBlock block, IDataFlowState stateOnEntry) 
    {
      IDataFlowState currentState = stateOnEntry;

      for (int i=0; i<block.Length; i++) 
      {
        if (currentState == null) return null;

        currentState = this.VisitStatement(block, (Statement)block[i], currentState);
      }

      return currentState;
    }
Beispiel #31
0
    /// <summary>
    /// Merge two cState
    /// </summary>
    /// <param name="previous"></param>
    /// <param name="joinPoint"></param>
    /// <param name="atMerge"></param>
    /// <param name="incoming"></param>
    /// <param name="resultDiffersFromPreviousMerge"></param>
    /// <param name="mergeIsPrecise"></param>
    /// <returns></returns>
    protected override IDataFlowState Merge(CfgBlock previous, CfgBlock joinPoint, IDataFlowState atMerge,
        IDataFlowState incoming, out bool resultDiffersFromPreviousMerge, out bool mergeIsPrecise)
    {
      resultDiffersFromPreviousMerge = false;
      mergeIsPrecise = false;

      // No new states;
      if (incoming == null)
        return atMerge;

      // Initialize states
      if (atMerge == null)
      {
        resultDiffersFromPreviousMerge = true;
        return incoming;
      }

      //if (((PointsToState )atMerge).Equals(incoming))
      //    return atMerge;
      if (((PointsToState)atMerge).Includes((PointsToState)incoming))
        return atMerge;



      // Merge the two.
      PointsToState newState = ((PointsToState)atMerge).Copy();
      newState.Join((PointsToState)incoming);

      //if( newState.Method.FullName.StartsWith("System.Runtime.Remoting.Lifetime.Lease.ProcessNextSponsor"))
      //{
      //    PointsToState oldResult = (PointsToState)incoming;
      //    PointsToState newResult = newState;
      //        Console.Out.WriteLine("DIFERENCE a vs b");
      //        oldResult.PointsToGraph.DumpDifference(newResult.PointsToGraph);
      //        Console.Out.WriteLine("DIFERENCE b vs a");
      //        newResult.PointsToGraph.DumpDifference(oldResult.PointsToGraph);
      //}

      resultDiffersFromPreviousMerge = true;

      return newState;
    }
    /// <summary>
    /// It split exceptions for current handler and the next chained handler.
    /// 
    /// It will:
    /// 
    ///   If the exception is completely intercepted by current handler, the
    ///   exception will be consumed.
    ///   
    ///   If the exception caught but not completely, both current handler and 
    ///   the next handler will take the states.
    ///   
    ///   If the exception is irrelevant to current caught, the next handler 
    ///   will take over the state. Current handler is then bypassed.
    /// </summary>
    /// <param name="handler"></param>
    /// <param name="currentHandlerState"></param>
    /// <param name="nextHandlerState"></param>
    protected override void SplitExceptions(CfgBlock handler, ref IDataFlowState currentHandlerState, out IDataFlowState nextHandlerState) {

      Debug.Assert(currentHandlerState!=null,"Internal error in NonNull Analysis");

      ExposureState state = (ExposureState)currentHandlerState;

      if(handler==null || handler.Length==0){
        nextHandlerState=null;
        return;
      }

      if(handler[0] is Unwind){
        nextHandlerState=null;
        currentHandlerState=null;
        return;
      }

      Debug.Assert(handler[0] is Catch, "Exception Handler does not starts with Catch");
      
      Debug.Assert(state.currentException!=null,"No current exception to handle");
      
      Catch c=(Catch)handler[0];

      if(handler.ExceptionHandler!=null && 
        !state.currentException.IsAssignableTo(c.Type)) {
        nextHandlerState = state;;
      }
      else {
        nextHandlerState=null;
      }

      // Compute what trickles through to the next handler
      //  and what sticks to this handler.
      if(state.currentException.IsAssignableTo(c.Type)) {
        // everything sticks 
        nextHandlerState = null;
      }
      else if (c.Type.IsAssignableTo(state.currentException)) {
        // c sticks, rest goes to next handler
        nextHandlerState = state;

        // copy state to modify the currentException
        state = new ExposureState(state);
        state.currentException = c.Type;
        currentHandlerState = state;
      }else {
        // nothing stick all goes to next handler
        nextHandlerState = state;
        currentHandlerState = null;
      }
      return;
    }
Beispiel #33
0
    /// <summary>
    /// Visit the statement. It calls the instruction visitor to perform the transfer function
    /// </summary>
    /// <param name="block"></param>
    /// <param name="statement"></param>
    /// <param name="dfstate"></param>
    /// <returns></returns>
    protected override IDataFlowState VisitStatement(CfgBlock block, Statement statement, IDataFlowState dfstate)
    {


      if (PointsToAnalysis.debug)
      {
        Console.Out.WriteLine("Before: {0} ({1}) {2}", CodePrinter.StatementToString(statement),
            statement.SourceContext.StartLine, statement.GetType());
        dfstate.Dump();
      }

      PointsToState currentState = dfstate as PointsToState;

      /*
      if (PointsToAnalysis.IsCompilerGenerated(currentState.Method))
        if (!this.pointsToStateAnalysys.enclosingState.ContainsKey(currentState.Method.DeclaringType))
          return currentState;
      */

      if (PointsToAnalysis.verbose)
      {
        iterationsCounter++;
        if (iterationsCounter % 5000 == 0)
        {
          Console.Out.WriteLine("Counter: {3} {4} {0} ({1}) {2}", CodePrinter.StatementToString(statement),
              statement.SourceContext.StartLine, statement.GetType(), iterationsCounter, currentState.Method.FullName);
          dfstate.Dump();

        }
      }
      //if (CodePrinter.StatementToString(statement).Contains("return value := this.f"))
      //    System.Diagnostics.Debugger.Break();

      IDataFlowState result = (IDataFlowState)currentState;


      // For Debug...
      if (currentState.Method.Name.Name.Equals("Push"))
      { }


      // If there are too many calls to non analyzable methods
      // starts to ignore the statements
      // if (!pointsToStateAnalysys.BoogieMode || currentState.CallsToNonAnalyzable.Count < pointsToStateAnalysys.maxCallToNonAnalyzable)
      if (HasToVisit(currentState))
        result = (IDataFlowState)(iVisitor.Visit(statement, dfstate));


      if (PointsToAnalysis.debug)
      {
        Console.Out.WriteLine("After: {0} ({1})", CodePrinter.StatementToString(statement), statement.SourceContext.StartLine);
        dfstate.Dump();
      }

      //return dfstate;
      return result;
    }
    /// <summary>
    /// Merge the new pending state with the old pending states.
    /// </summary>
    /// <returns>merged pending state</returns>
    private IDataFlowState JoinWithPendingState (CfgBlock prev, CfgBlock block, IDataFlowState newState) 
    {
      if (Tracing) 
      {
        Console.WriteLine("JoinWithPendingState: block {0} -> {1}", 
          (prev).UniqueKey, 
          (block).UniqueKey);
      }

      IDataFlowState pending = PendingState(block);
      // note, we call Merge even if old is null.
      bool changed;
      bool precise;

      if (Tracing) {
        SourceContext sc = (block).SourceContext;

        if (sc.Document == null && block.Length > 0) {
          sc = ((Statement)block[0]).SourceContext;
        }
        Console.WriteLine("Join with pending state at line {0}", sc.StartLine);
      }

      IDataFlowState merged = this.Merge(prev, block, pending, newState, out changed, out precise);
	
      if (Tracing) {
         Console.WriteLine("Join changed {0}", changed);
      }
      return merged;
    }
Beispiel #35
0
    // Visit the block in the CFG 
    protected override IDataFlowState VisitBlock(CfgBlock block, IDataFlowState stateOnEntry)
    {
      IDataFlowState resultState = stateOnEntry;

      Debug.Assert(block != null);

      currBlock = block;

      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("");

      PointsToState newState = ((PointsToState)stateOnEntry).Copy();
      // If there are too many calls to non analyzable methods
      // starts to ignore the statements
      //if (!pointsToStateAnalysys.BoogieMode ||
      //    newState.CallsToNonAnalyzable.Count < pointsToStateAnalysys.maxCallToNonAnalyzable)

      if (HasToVisit(newState))
      {
        if (block.ExceptionHandler != null)
          this.PushExceptionState(block, newState);

        resultState = base.VisitBlock(block, newState);
      }

      if (block.UniqueId == cfg.NormalExit.UniqueId)
      {
        exitState = resultState;
      }

      if (block.UniqueId == cfg.ExceptionExit.UniqueId)
      {
        exitState = resultState;
      }

      return resultState;
    }
    /// <summary>
    /// Record the incoming status's sets of created and committed NN Arrays.
    /// </summary>
    /// <param name="block"></param>
    /// <param name="statement"></param>
    /// <param name="dfstate"></param>
    /// <returns></returns>
    protected override IDataFlowState VisitStatement(CfgBlock block, Statement statement, IDataFlowState dfstate) {
      //IDataFlowState result =  base.VisitStatement(block, statement, dfstate);
      table[statement.UniqueKey] = (dfstate as NNArrayStatus).CreatedButNotInitedArrays();
      tableCommitted[statement.UniqueKey] = (dfstate as NNArrayStatus).CommittedArrays();
 
      IDataFlowState result = null;
      //try {
        result = (IDataFlowState)(iVisitor.Visit(statement, dfstate));
        if (Analyzer.Debug && result != null) {
          result.Dump();
        }
      //}
      //catch (Exception e) {
      //  this.TypeSystem.HandleError(statement, Error.InternalCompilerError, "NNArray Pre Analysis " + e.Message);
      //}
      return result;
    }
Beispiel #37
0
 protected override IDataFlowState Merge(CfgBlock previous, CfgBlock joinPoint, IDataFlowState atMerge, IDataFlowState incoming, out bool resultDiffersFromPreviousMerge, out bool mergeIsPrecise)
 {
     if (nonNullInfo != null)
     {
         INonNullState nns = nonNullInfo.OnEdge(previous, joinPoint);
         if (nns == null && atMerge != null)
         {
             incoming = null;
         }
     }
     return(base.Merge(previous, joinPoint, atMerge, incoming, out resultDiffersFromPreviousMerge, out mergeIsPrecise));
 }
    /// <summary>
    /// Push the given state onto the handler of the block.
    /// This causes call-backs to SplitException in order to correctly distribute
    /// the exception state among different nested handlers.
    /// </summary>
    /// <param name="currentBlock">Block from which exception escapes</param>
    /// <param name="state">state on exception flow</param>
    public void PushExceptionState (
      CfgBlock currentBlock,
      IDataFlowState state
      )
    {
      IDataFlowState currentHandlerState = state;
      CfgBlock currentHandler = currentBlock;
      IDataFlowState nextHandlerState;

      while (currentHandlerState != null)
      {
        Debug.Assert(currentHandler.ExceptionHandler != null, 
          String.Format("block {0} does not have an exception handler",
          (currentHandler).UniqueKey));

        currentHandler = currentHandler.ExceptionHandler;

        if (Tracing) 
        {
          Console.WriteLine("PushExceptionState (in loop): block {0} -> {1}", 
            (currentBlock).UniqueKey,
            (currentHandler).UniqueKey);
        }

        SplitExceptions(currentHandler, ref currentHandlerState, out nextHandlerState);

        /// We allow SplitExceptions to make decisions about not propagating any exceptions
        /// Debug.Assert(currentHandlerState != null || nextHandlerState != null);

        if (currentHandlerState != null)
        {
          PushState(currentBlock, currentHandler, currentHandlerState);
        }

        currentHandlerState = nextHandlerState;
      } 
    }
Beispiel #39
0
 /// <summary>
 /// Starts the analysis from the entry block of the CFG
 /// </summary>
 protected virtual void Run(ControlFlowGraph cfg, IDataFlowState startState)
 {
     this.Run(cfg, cfg.Entry, startState);
 }
 protected override IDataFlowState VisitStatement(CfgBlock block, Statement statement, IDataFlowState dfstate) 
 {
   // For debug purpose
   if (Analyzer.Debug)
   {
     try
     {
       Analyzer.WriteLine(new SampleInstructionVisitor().Visit(statement, null) + "   :::   " + statement.SourceContext.SourceText);
     }
     catch (Exception)
     {
       Analyzer.WriteLine("Print error: " + statement);
     }
   }
  
   IDataFlowState result=null;
   try{
     result =(IDataFlowState)(iVisitor.Visit(statement,dfstate));
     if (Analyzer.Debug && result != null) {
       result.Dump();
    }
   }catch(Exception e){
     typeSystem.HandleError(statement,Error.InternalCompilerError,"Definite Assignement: "+e.Message);
   }
   return result;
 }
 /// <summary>
 /// Merge two PtWe
 /// </summary>
 /// <param name="previous"></param>
 /// <param name="joinPoint"></param>
 /// <param name="atMerge"></param>
 /// <param name="incoming"></param>
 /// <param name="resultDiffersFromPreviousMerge"></param>
 /// <param name="mergeIsPrecise"></param>
 /// <returns></returns>
 protected override IDataFlowState Merge(CfgBlock previous, CfgBlock joinPoint, IDataFlowState atMerge,
     IDataFlowState incoming, out bool resultDiffersFromPreviousMerge, out bool mergeIsPrecise)
 {
     return base.Merge(previous,joinPoint,atMerge,incoming,out resultDiffersFromPreviousMerge, out mergeIsPrecise);
 }
 protected override void Run(ControlFlowGraph cfg, IDataFlowState startState) {
   base.Run(cfg, startState);
 }
Beispiel #43
0
 protected override void SplitExceptions(CfgBlock handler, ref IDataFlowState currentHandlerState,
                                         out IDataFlowState nextHandlerState)
 {
     nextHandlerState = null;
 }
 /// <summary>
 /// Starts the analysis from the entry block of the CFG
 /// </summary>
 protected virtual void Run (ControlFlowGraph cfg, IDataFlowState startState) 
 {
   this.Run(cfg, cfg.Entry, startState);
 }
Beispiel #45
0
        /// <summary>
        /// Visit the statement. It calls the instruction visitor to perform the transfer function
        /// </summary>
        /// <param name="block"></param>
        /// <param name="statement"></param>
        /// <param name="dfstate"></param>
        /// <returns></returns>
        protected override IDataFlowState VisitStatement(CfgBlock block, Statement statement, IDataFlowState dfstate)
        {
            IDataFlowState result = (IDataFlowState)(iVisitor.Visit(statement, dfstate));

            return(result);
        }
    /// <summary>
    /// Add the given state to the pending states of the target block. If 
    /// the block is enabled (by the pending edge count optimization), add the
    /// block to the worklist.
    /// 
    /// Inv: DoneState => PendingState /\ PendingState != null => InQueue
    /// 
    /// Cases:
    ///   1. Done => new, nothing to do
    ///   2. Done |_| new is precise.  Pend' = Pend |_| new,  Done' = Done |_| new
    ///   3. Done |_| new is imprecise.  Pend' = Done |_| new,  Done' = Done |_| new
    /// </summary>
    public void PushState (
      CfgBlock currentBlock, 
      CfgBlock nextBlock, 
      IDataFlowState state
      ) 
    {
      if (Tracing) 
      {
        Console.WriteLine("PushState: block {0} -> {1}", 
          (currentBlock).UniqueKey,
          (nextBlock).UniqueKey);
      }


      // state == null signals that branch is infeasible
      if (state == null) 
      {
        return;
      }

      bool precise;
      // Add state to done state
      IDataFlowState stillPending = this.StateToReanalyzeBlock(currentBlock, nextBlock, state, out precise);

      if (stillPending == null) 
      {
        if (Tracing) 
        {
          Console.WriteLine("PushState: block {0} no new information for pending state.", 
            (nextBlock).UniqueKey);
        }
        return;
      }

      if (precise) 
      {
        // join stillPending to old pending.
        stillPending = this.JoinWithPendingState(currentBlock, nextBlock, stillPending);
      }
      this.SetPendingState (nextBlock, stillPending);
			
      // when dequeued, the pending state is what the block needs to be analyzed under.
      //
      joinWorkItems.Enqueue(nextBlock);
      if (Tracing) 
      {
        Console.WriteLine("PushState: block {0} put on work queue.", 
          (nextBlock).UniqueKey);
      }
    }
    /// <summary>
    /// merge the two state atMerge and incoming.
    /// </summary>
    /// <param name="previous"></param>
    /// <param name="joinPoint"></param>
    /// <param name="atMerge"></param>
    /// <param name="incoming"></param>
    /// <param name="resultDiffersFromPreviousMerge"></param>
    /// <param name="mergeIsPrecise"></param>
    /// <returns></returns>
    protected override IDataFlowState Merge(CfgBlock previous, CfgBlock joinPoint, IDataFlowState atMerge, IDataFlowState incoming, out bool resultDiffersFromPreviousMerge, out bool mergeIsPrecise) {
      resultDiffersFromPreviousMerge = false;
      mergeIsPrecise = false;

      // No new states;
      if (incoming == null)
        return atMerge;

      // Initialize states
      if (atMerge == null) {
        resultDiffersFromPreviousMerge = true;
        //
        //((NNArrayStatus)incoming).FilterStackAndTemporaryLocals(joinPoint.StackDepth);
        return incoming;
      }

      if (Analyzer.Debug ) {
        Console.WriteLine("Array Reachable Def merge at block {0}", (joinPoint).UniqueKey);
        Console.WriteLine("atMerge:\n---------");
        atMerge.Dump();
        Console.WriteLine("incoming:\n---------");
        incoming.Dump();
      }
      // Merge the two.
      NNArrayStatus newState = NNArrayStatus.Merge((NNArrayStatus)atMerge, (NNArrayStatus)incoming, joinPoint);
      if (newState == null) {
        if (Analyzer.Debug) {
          Console.WriteLine("result UNchanged");
        }
        return atMerge;
      }
      resultDiffersFromPreviousMerge = true;
      if (Analyzer.Debug) {
        Console.WriteLine("Result of merge\n---------");
        newState.Dump();
      }
      return newState;
    }
Beispiel #48
0
 // Exception management
 internal void PushExceptionWrapper(IDataFlowState state)
 {
   this.PushExceptionState(currBlock, state);
 }
    protected override IDataFlowState VisitBlock(CfgBlock block, IDataFlowState state) {
      Debug.Assert(block != null);

      NNArrayStatus onEntry = (NNArrayStatus)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) {
        NNArrayStatus exnState = onEntry;
        onEntry = new NNArrayStatus(onEntry); // Copy state, since common ancestor cannot be modified any longer
        PushExceptionState(block, exnState);
      }

      NNArrayStatus resultState = (NNArrayStatus)base.VisitBlock(block, onEntry);
      if (block.UniqueId == cfg.NormalExit.UniqueId) {
        exitState = resultState;
      }
      if (resultState == null) {
        return null;
      }
      return new NNArrayStatus(resultState);

    }
    /// <summary>
    /// Checks if a block needs to be reanalyzed and under what state.
    /// 
    /// Updates the doneState of this block to reflect the pending state
    /// </summary>
    /// <returns>null if no reanalysis necessary, the DFS state if the merge is precise,
    /// the merged state if the merge is imprecise
    /// </returns>
    private IDataFlowState StateToReanalyzeBlock (CfgBlock prev, CfgBlock block, IDataFlowState pending, out bool preciseMerge) {
      IDataFlowState done = DoneState(block);
      // note, we call Merge even if old is null.
      bool changed;

      if (Tracing) {
        Console.WriteLine("StateToReanalyzeBlock: block {0} -> {1}", 
          (prev).UniqueKey, 
          (block).UniqueKey);

        SourceContext sc = (block).SourceContext;

        if (sc.Document == null && block.Length > 0) {
          sc = ((Statement)block[0]).SourceContext;
        }
        Console.WriteLine("StateToReanalyzeBlock at line {0}", sc.StartLine);

      }
      IDataFlowState merged = this.Merge(prev, block, done, pending, out changed, out preciseMerge);
	
      if (merged != null)
        doneStates[block.Index] = merged;

      if ( ! changed ) {

        if (Tracing) {
          Console.WriteLine("Done State");
          done.Dump();
          Console.WriteLine("Pending State");
          pending.Dump();
          Console.WriteLine("StateToReanalyzeBlock result UNchanged");
        }
        return null;
      }
      if ( preciseMerge ) return pending;

      if (Tracing) {
        Console.WriteLine("StateToReanalyzeBlock result CHANGED");
        if (done == null) {
          Console.WriteLine("no done state yet");
        }
        else {
          Console.WriteLine("Done State");
          done.Dump();
        }
        Console.WriteLine("Pending State");
        pending.Dump();
        Console.WriteLine("Merged State");
        merged.Dump();
      }
      return merged;
    }
 protected override void SplitExceptions(CfgBlock handler, ref IDataFlowState currentHandlerState, out IDataFlowState nextHandlerState) {
   nextHandlerState = null;
   return;
 }
Beispiel #52
0
        /// <summary>
        /// Checks if a block needs to be reanalyzed and under what state.
        ///
        /// Updates the doneState of this block to reflect the pending state
        /// </summary>
        /// <returns>null if no reanalysis necessary, the DFS state if the merge is precise,
        /// the merged state if the merge is imprecise
        /// </returns>
        private IDataFlowState StateToReanalyzeBlock(CfgBlock prev, CfgBlock block, IDataFlowState pending, out bool preciseMerge)
        {
            IDataFlowState done = DoneState(block);
            // note, we call Merge even if old is null.
            bool changed;

            if (Tracing)
            {
                Console.WriteLine("StateToReanalyzeBlock: block {0} -> {1}",
                                  (prev).UniqueKey,
                                  (block).UniqueKey);

                SourceContext sc = (block).SourceContext;

                if (sc.Document == null && block.Length > 0)
                {
                    sc = ((Statement)block[0]).SourceContext;
                }
                Console.WriteLine("StateToReanalyzeBlock at line {0}", sc.StartLine);
            }
            IDataFlowState merged = this.Merge(prev, block, done, pending, out changed, out preciseMerge);

            if (merged != null)
            {
                doneStates[block.Index] = merged;
            }

            if (!changed)
            {
                if (Tracing)
                {
                    Console.WriteLine("Done State");
                    done.Dump();
                    Console.WriteLine("Pending State");
                    pending.Dump();
                    Console.WriteLine("StateToReanalyzeBlock result UNchanged");
                }
                return(null);
            }
            if (preciseMerge)
            {
                return(pending);
            }

            if (Tracing)
            {
                Console.WriteLine("StateToReanalyzeBlock result CHANGED");
                if (done == null)
                {
                    Console.WriteLine("no done state yet");
                }
                else
                {
                    Console.WriteLine("Done State");
                    done.Dump();
                }
                Console.WriteLine("Pending State");
                pending.Dump();
                Console.WriteLine("Merged State");
                merged.Dump();
            }
            return(merged);
        }