コード例 #1
0
 internal static bool IsInstrumentationCode(CfgBlock block)
 {
     if (block.ExceptionHandler != null)
     {
         for (CfgBlock handler = block.ExceptionHandler; handler != null;
              handler = handler.ExceptionHandler)
         {
             Catch catchStmt = handler[0] as Catch;
             if (catchStmt == null)
             {
                 continue;
             }
             TypeNode exnType = catchStmt.Type;
             if (exnType == null)
             {
                 continue;
             }
             if (Equals(exnType.FullName, "Microsoft.Contracts.ContractMarkerException"))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
コード例 #2
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
        /// <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);
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        /// <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;
        }
コード例 #5
0
ファイル: EGraph.cs プロジェクト: Plankankul/SpecSharp
        public IEGraph Join(IEGraph g2, CfgBlock joinPoint, out bool resultIsomorphicToThis)
        {
            IMergeInfo minfo;
            IEGraph    result = Join(g2, joinPoint, out minfo);

            resultIsomorphicToThis = !minfo.Changed;
            return(result);
        }
コード例 #6
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
 public void Dump()
 {
     for (int i = 0; i < array.Count; i++)
     {
         CfgBlock block = (CfgBlock)array[i];
         Console.WriteLine("{0}: b{1} ({2})", i, block.Index, block.UniqueKey);
     }
 }
コード例 #7
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
 /// <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
     );
コード例 #8
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
 private void SetPendingState(CfgBlock block, IDataFlowState pending)
 {
     pendingStates[block.Index] = pending;
     if (Tracing)
     {
         Console.WriteLine("SetPendingState: block {0}", (block).UniqueKey);
     }
 }
コード例 #9
0
        private void PushDepth(CfgBlock succ, int depth)
        {
            int olddepth = block2depth[succ.Index];

            if (visited[succ.Index])
            {
                //System.Diagnostics.Debug.Assert( olddepth == depth, "Stack depth differs" );
                return;
            }
            visited[succ.Index]     = true;
            block2depth[succ.Index] = depth;
        }
コード例 #10
0
        private int InitialDepthOfBlock(CfgBlock block, ControlFlowGraph cfg)
        {
            int sd = block2depth[block.Index];

            if (this.visited[block.Index])
            {
                return(sd);
            }

            this.visited[block.Index] = true;
            int depth;

            ExceptionHandler eh = cfg.HandlerThatStartsAtBlock(block);

            if (eh == null)
            {
                // if we haven't seen this block and it is not the entry block
                // nor the Exception Exit of the method
                // it is unreachable
                if (block == cfg.Entry)
                {
                    depth = 0;
                }
                else if (block == cfg.ExceptionExit)
                {
                    depth = 0;
                }
                else
                {
                    depth = -1;
                }
            }
            else
            {
                switch (eh.HandlerType)
                {
                case NodeType.Catch:
                case NodeType.FaultHandler:
                case NodeType.Filter:
                    depth = 1;
                    break;

                case NodeType.Finally:
                    depth = 0;
                    break;

                default:
                    throw new ApplicationException("unknown handler type");
                }
            }
            block2depth[block.Index] = depth;
            return(depth);
        }
コード例 #11
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
        /// <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);
        }
コード例 #12
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));
 }
コード例 #13
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);
 }
コード例 #14
0
ファイル: EGraph.cs プロジェクト: Plankankul/SpecSharp
        public IEGraph Join(IEGraph g2, CfgBlock joinPoint, out IMergeInfo mergeInfo)
        {
            EGraph eg1 = this;
            EGraph eg2 = (EGraph)g2;

            int    updateSize;
            EGraph common = ComputeCommonTail(eg1, eg2, out updateSize);

            EGraph result;
            bool   doReplay = true;

            if (common == null)
            {
                doReplay     = false;
                result       = new EGraph(eg1.elementLattice);
                result.Block = joinPoint;
            }
            else
            {
                result = new EGraph(common, joinPoint);
            }

            if (Analyzer.Debug)
            {
                Console.WriteLine("Last common symbol: {0}", common.idCounter);
            }
            if (Analyzer.Statistics)
            {
                Console.WriteLine("G1:{0} G2:{1} Tail:{2} UpdateSize:{3}", eg1.historySize, eg2.historySize, result.historySize, updateSize);
            }

            MergeState ms = new MergeState(result, eg1, eg2);

            // Heuristic for using Replay vs. full update
            doReplay &= (common != eg1.root);
            doReplay &= (eg1.historySize > 3);
            doReplay &= (eg2.historySize > 3);

            if (doReplay)
            {
                ms.Replay(common);
            }
            else
            {
                ms.AddMapping(eg1.constRoot, eg2.constRoot, result.constRoot);
                ms.JoinSymbolicValue(eg1.constRoot, eg2.constRoot, result.constRoot);
            }
            mergeInfo = ms;
            return(result);
        }
コード例 #15
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
        /// <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);
            }
        }
コード例 #16
0
        /// <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);
        }
コード例 #17
0
 public IStronglyConnectedComponent SccForBlock(CfgBlock block)
 {
     if (this.sccMap == null)
     {
         this.sccMap = new Hashtable();
         foreach (StronglyConnectedComponent /*<CfgBlock>*/ scc in this.sccs)
         {
             foreach (CfgBlock iblock in scc.Nodes)
             {
                 this.sccMap[iblock] = scc;
             }
         }
     }
     return((StronglyConnectedComponent)this.sccMap[(block)]);
 }
コード例 #18
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
        /// <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);
            }
        }
コード例 #19
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
        /// <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);
        }
コード例 #20
0
ファイル: EGraph.cs プロジェクト: Plankankul/SpecSharp
        /// <summary>
        /// Copy constructor
        /// </summary>
        /// <param name="from"></param>
        private EGraph(EGraph from, CfgBlock at)
        {
            this.constRoot      = from.constRoot;
            this.termMap        = from.termMap;
            this.idCounter      = from.idCounter;
            this.absMap         = from.absMap;
            this.elementLattice = from.elementLattice;
            this.forwMap        = from.forwMap;
            this.eqTermMap      = from.eqTermMap;

            // keep history
            this.updates     = from.updates;
            this.parent      = from;
            this.root        = from.root;
            this.historySize = from.historySize + 1;
            this.Block       = at;

            // set from to constant
            from.constant = true;
        }
コード例 #21
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);
        }
コード例 #22
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
        /// <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;
            }
        }
コード例 #23
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
        /// <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
        }
コード例 #24
0
        /// <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));
        }
コード例 #25
0
    /// <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;
    }
コード例 #26
0
    public static InitializedVariables Merge(InitializedVariables atMerge, InitializedVariables incoming, CfgBlock joinPoint) {
      bool unchanged;
      IEGraph result = atMerge.egraph.Join(incoming.egraph, joinPoint, out unchanged);

      if (unchanged) return null;
      return new InitializedVariables(incoming.analyzer, result, atMerge.referenceStatus);
    }
コード例 #27
0
    private void PushDepth(CfgBlock succ, int depth) {
      int olddepth = block2depth[succ.Index];

      if (visited[succ.Index]) {
        //System.Diagnostics.Debug.Assert( olddepth == depth, "Stack depth differs" );
        return;
      }
      visited[succ.Index] = true;
      block2depth[succ.Index] = depth;
    }
コード例 #28
0
 protected override IDataFlowState VisitBlock(CfgBlock block, IDataFlowState stateOnEntry)
 {
     //if (IsInstrumentationCode(block))
     //    return stateOnEntry;
     return base.VisitBlock(block, stateOnEntry);
 }
コード例 #29
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);
 }
コード例 #30
0
    public IEGraph Join(IEGraph g2, CfgBlock joinPoint, out IMergeInfo mergeInfo) {
      EGraph eg1 = this;
      EGraph eg2 = (EGraph)g2;

      int updateSize;
      EGraph common = ComputeCommonTail(eg1, eg2, out updateSize);

      EGraph result;
      bool doReplay = true;

      if (common == null) {
        doReplay = false;
        result = new EGraph(eg1.elementLattice);
        result.Block = joinPoint;
      }
      else {
        result = new EGraph(common, joinPoint);
      }

      if (Analyzer.Debug) {
        Console.WriteLine("Last common symbol: {0}", common.idCounter);
      }
      if (Analyzer.Statistics) {
        Console.WriteLine("G1:{0} G2:{1} Tail:{2} UpdateSize:{3}", eg1.historySize, eg2.historySize, result.historySize, updateSize);
      }

      MergeState ms = new MergeState(result, eg1, eg2);

      // Heuristic for using Replay vs. full update
      doReplay &= (common != eg1.root);
      doReplay &= (eg1.historySize > 3);
      doReplay &= (eg2.historySize > 3);

      if (doReplay) {
        ms.Replay(common);
      }
      else {
        ms.AddMapping(eg1.constRoot, eg2.constRoot, result.constRoot);
        ms.JoinSymbolicValue(eg1.constRoot, eg2.constRoot, result.constRoot);
      }
      mergeInfo = ms;
      return result;
    }
コード例 #31
0
ファイル: PointsToAnalysis.cs プロジェクト: hesam/SketchSharp
    /// <summary>
    /// Exception management
    /// Need Checking!
    /// </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)
    {
      System.Diagnostics.Debug.Assert(currentHandlerState != null, "Internal error in Purity Analysis");

      PointsToState state = (PointsToState)currentHandlerState;

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

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

      // This is
      if (!(handler[0] is Catch))
      {
        // everything sticks 
        nextHandlerState = null;
        return;
      }

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

      if (state.currentException == null)
      {
        nextHandlerState = null;
        return;
      }


      System.Diagnostics.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 = (state).Copy();
        state.currentException = c.Type;
        currentHandlerState = state;
      }
      else
      {
        // nothing stick all goes to next handler
        nextHandlerState = state;
        currentHandlerState = null;
      }
      return;
    }
コード例 #32
0
    /// <summary>
    /// Copy constructor
    /// </summary>
    /// <param name="from"></param>
    private EGraph(EGraph from, CfgBlock at) {
      this.constRoot = from.constRoot;
      this.termMap = from.termMap;
      this.idCounter = from.idCounter;
      this.absMap = from.absMap;
      this.elementLattice = from.elementLattice;
      this.forwMap = from.forwMap;
      this.eqTermMap = from.eqTermMap;
      
      // keep history
      this.updates = from.updates;
      this.parent = from;
      this.root = from.root;
      this.historySize = from.historySize+1;
      this.Block = at;

      // set from to constant
      from.constant = true;
    }
コード例 #33
0
 public IEGraph Clone(CfgBlock at) {
   return new EGraph(this, at);
 }
コード例 #34
0
    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);

    }
コード例 #35
0
 protected override void SplitExceptions(CfgBlock handler, ref IDataFlowState currentHandlerState, out IDataFlowState nextHandlerState) {
   nextHandlerState = null;
   return;
 }
コード例 #36
0
ファイル: PointsToAnalysis.cs プロジェクト: hesam/SketchSharp
    /// <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;
    }
コード例 #37
0
ファイル: PointsToAnalysis.cs プロジェクト: hesam/SketchSharp
    /// <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;
    }
コード例 #38
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
 /// <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
     );
コード例 #39
0
 internal static bool IsInstrumentationCode(CfgBlock block)
 {
     if (block.ExceptionHandler != null)
     {
         for (CfgBlock handler = block.ExceptionHandler; handler != null;
             handler = handler.ExceptionHandler)
         {
             Catch catchStmt = handler[0] as Catch;
             if (catchStmt == null) { continue; }
             TypeNode exnType = catchStmt.Type;
             if (exnType == null) { continue; }
             if (Equals(exnType.FullName, "Microsoft.Contracts.ContractMarkerException"))
             {
                 return true;
             }
         }
     }
     return false;
 }
コード例 #40
0
ファイル: CFGanalysis.cs プロジェクト: Plankankul/SpecSharp
 private IDataFlowState PendingState(CfgBlock block)
 {
     return(pendingStates[block.Index]);
 }
コード例 #41
0
 protected override void SplitExceptions(CfgBlock handler, ref IDataFlowState currentHandlerState,
                                         out IDataFlowState nextHandlerState)
 {
     nextHandlerState = null;
 }
コード例 #42
0
ファイル: PointsToAnalysis.cs プロジェクト: hesam/SketchSharp
    // 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;
    }
コード例 #43
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);
        }
コード例 #44
0
 protected override IDataFlowState VisitBlock(CfgBlock block, IDataFlowState stateOnEntry)
 {
     //if (IsInstrumentationCode(block))
     //    return stateOnEntry;
     return(base.VisitBlock(block, stateOnEntry));
 }
コード例 #45
0
    private int InitialDepthOfBlock(CfgBlock block, ControlFlowGraph cfg) {
      int sd = block2depth[block.Index];

      if (this.visited[block.Index]) return sd;

      this.visited[block.Index] = true;
      int depth;

      ExceptionHandler eh = cfg.HandlerThatStartsAtBlock(block);
      if (eh == null) {
        // if we haven't seen this block and it is not the entry block
        // nor the Exception Exit of the method
        // it is unreachable
        if (block == cfg.Entry) {
          depth = 0;
        }
        else if (block == cfg.ExceptionExit) {
          depth = 0;
        }
        else {
          depth = -1;
        }
      }
      else {
        switch (eh.HandlerType) {
          case NodeType.Catch:
          case NodeType.FaultHandler:
          case NodeType.Filter:
            depth = 1;
            break;
          case NodeType.Finally:
            depth = 0;
            break;
          default:
            throw new ApplicationException("unknown handler type");
        }
      }
      block2depth[block.Index] = depth;
      return depth;
    }
コード例 #46
0
 /// <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);
 }
コード例 #47
0
 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;
 }
コード例 #48
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)
 {
     PointsToAndWriteEffects ptwe = (PointsToAndWriteEffects)dfstate;
     // PointsToAndWriteEffects ptweOld = new PointsToAndWriteEffects(ptwe);
     IDataFlowState res = base.VisitStatement(block, statement, dfstate);
     return res;
     
 }
コード例 #49
0
 protected override void Run(ControlFlowGraph cfg, CfgBlock startBlock, IDataFlowState startState) {
   base.Run(cfg, startBlock, startState);
 }
コード例 #50
0
        /// <summary>
        /// Returns null, if result of Join is the same as atMerge.
        /// </summary>
        public static ExposureState Join(ExposureState atMerge, ExposureState incoming, CfgBlock joinPoint)
        {
            bool    unchanged;
            IEGraph merged = atMerge.egraph.Join(incoming.egraph, joinPoint, out unchanged);

            TypeNode currentException = (atMerge.currentException != null)?
                                        ((incoming.currentException != null)? CciHelper.LeastCommonAncestor(atMerge.currentException, incoming.currentException) : null) : null;

            if (atMerge.currentException != currentException || !unchanged)
            {
                return(new ExposureState(merged, currentException, atMerge.typeSystem));
            }
            return(null);
        }
コード例 #51
0
    /// <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;
    }
コード例 #52
0
 // Visit the block in the CFG 
 protected override IDataFlowState VisitBlock(CfgBlock block, IDataFlowState stateOnEntry)
 {
     return base.VisitBlock(block, stateOnEntry);
 }
コード例 #53
0
    /// <summary>
    /// TODO: The set of vars/fields that are created only/committed must agree
    /// </summary>
    /// <returns></returns>
    public static NNArrayStatus Merge(NNArrayStatus atMerge, NNArrayStatus incoming, CfgBlock joinPoint) {
      Debug.Assert(atMerge != null && incoming != null);   
      // if (atMerge == incoming) return null;
      InitializedVariables result = InitializedVariables.Merge(atMerge.ivs, incoming.ivs, joinPoint);
      if (result == null
        && atMerge.vars.Equals(incoming.vars)
        && atMerge.fields.Equals(incoming.fields)
        && atMerge.zeroInts.Equals(incoming.zeroInts)
        ) 
        return null;

      if (result == null) result = atMerge.ivs; 

      return new NNArrayStatus(result, (HashSet)Set.Union(atMerge.vars, incoming.vars),  
        Set.Union(atMerge.fields,incoming.fields) as HashSet, 
        Set.Intersect(atMerge.zeroInts, incoming.zeroInts) as HashSet,
        mergeStack(atMerge.stack, incoming.stack, result));
    }
コード例 #54
0
 public IEGraph Join(IEGraph g2, CfgBlock joinPoint, out bool resultIsomorphicToThis) {
   IMergeInfo minfo;
   IEGraph result = Join(g2, joinPoint, out minfo);
   resultIsomorphicToThis = !minfo.Changed;
   return result;
 }