예제 #1
0
        /// <summary>
        /// Given an underlying analysis and generator for a bottom value, this method computes a mapping between a state of
        /// the iterator and fixpoint information computed by the underlying analysis for the slice that corresponds to that
        /// state.
        ///
        /// The analysis runs the underlying analyzer on state 0, the initial state, first. The state from the return point
        /// of this state will be the current value of the invariant candidate.
        /// Then for every continuing state (the state from which a new item is generated for the ienumerable result), we map
        /// the current invariant candidate and map it to the entry of the method, and run the underlying analysis for that
        /// state. Running the underlying analysis for a particular state requires a set of program points, which are the entry
        /// points of other slices. The underlying analysis will mark those program points as unreachable. The exit abstract
        /// state will become the current invariant candidate. This process finishes when a fixedpoint is reached.
        /// </summary>
        /// <typeparam name="MyDomain">The domain of the underlying analysis.</typeparam>
        /// <param name="analysis">The underlying analysis.</param>
        /// <param name="bv">A delegate that generates a bottom value for MyDomain.</param>
        /// <returns></returns>
        public IFactQuery <BoxedExpression, Variable> Analyze <MyDomain>(
            IAbstractAnalysis <Local, Parameter, Method, Field, Property, Type, Expression, Attribute, Assembly, MyDomain, Variable> analysis
            )
        {
            // Fix point computation: fixpoint of the iterator analysis is a mapping: answers.
            if (stateInfo == null)
            {
                return(null);
            }
            bool     fixedpointReached = false;
            MyDomain d = default(MyDomain), oldd = default(MyDomain);
            var      answers = (IFunctionalMap <int, IFixpointInfo <APC, MyDomain> >)FunctionalMap <int, IFixpointInfo <APC, MyDomain> > .Empty;
            Dictionary <int, MyDomain> invariantCandidate = new Dictionary <int, MyDomain>();

            int pass = 0;

            while (!fixedpointReached)
            {
                fixedpointReached = true;
                // Going through every state of the state machine, if the final states changes at least once
                // then fixpoint is not reached.
                foreach (int state in stateInfo.OrderedVisibleStates)
                {
                    // The initial state is only analyzed once.
                    if (state < 0)
                    {
                        continue;
                    }
                    if (state == 0 && pass > 0)
                    {
                        continue;
                    }
                    // Initial value for one pass, either TOP, if we analyze it for the first time
                    // or the invariantCandidate.
                    if (!invariantCandidate.ContainsKey(state))
                    {
                        invariantCandidate[state] = d = analysis.GetTopValue();
                    }
                    else
                    {
                        d = analysis.MutableVersion(invariantCandidate[state]);
                    }

                    // Call the underlying analysis for one pass
                    Set <APC> cutOffPCs = GetStateEntriesOtherThan(stateInfo, state);
                    var       fixpoint  = driver.CreateForwardForIterator(analysis, () => analysis.GetBottomValue(), cutOffPCs)(d);
                    // Fill the result table with the most recent fixpoint information.
                    answers = answers.Add(state, fixpoint);

                    // Getting the state from the return point of the most recent pass, map it
                    // to the entry point, and join it with the current invariant candidate
                    bool changed  = false;
                    var  fakeEdge = new Pair <APC, APC>(driver.CFG.NormalExit, driver.CFG.Entry);
                    foreach (int possibleNextState in stateInfo.OrderedVisibleStates)
                    {
                        bool     isBottom;
                        MyDomain newInvariantState = GetReturnState(fixpoint, analysis, possibleNextState, out isBottom, analysis.GetTopValue());
                        if (invariantCandidate.ContainsKey(possibleNextState))
                        {
                            oldd = invariantCandidate[possibleNextState];
                            // TODO: use a more sophisticated widenning strategy.
                            bool toWiden = (pass > 2) ? true : false;
                            if (isBottom)
                            {
                                d = oldd;
                            }
                            else
                            {
                                d = analysis.Join(fakeEdge, newInvariantState, oldd, out changed, toWiden);
                            }
                            if (changed)
                            {
                                invariantCandidate[possibleNextState] = d;
                            }
                        }
                        else
                        {
                            if (!isBottom)
                            {
                                changed = true;
                                invariantCandidate[possibleNextState] = newInvariantState;
                            }
                        }
                        if (changed)
                        {
                            fixedpointReached = false;
                        }
                    }
                }
                pass++;
            }
            var result = new DisjunctionFactQuery <Variable>(this.driver.ValueLayer.Decoder.IsUnreachable);

            answers.Visit((statekey, fixpoint) => { result.Add(analysis.FactQuery(fixpoint)); return(VisitStatus.ContinueVisit); });
            return(result);
        }
예제 #2
0
        /// <summary>
        /// Given an underlying analysis and generator for a bottom value, this method computes a mapping between a state of
        /// the iterator and fixpoint information computed by the underlying analysis for the slice that corresponds to that
        /// state.
        ///
        /// The analysis runs the underlying analyzer on state 0, the initial state, first. The state from the return point
        /// of this state will be the current value of the invariant candidate.
        /// Then for every continuing state (the state from which a new item is generated for the ienumerable result), we map
        /// the current invariant candidate and map it to the entry of the method, and run the underlying analysis for that
        /// state. Running the underlying analysis for a particular state requires a set of program points, which are the entry
        /// points of other slices. The underlying analysis will mark those program points as unreachable. The exit abstract
        /// state will become the current invariant candidate. This process finishes when a fixedpoint is reached.
        /// </summary>
        /// <typeparam name="MyDomain">The domain of the underlying analysis.</typeparam>
        /// <param name="analysis">The underlying analysis.</param>
        /// <param name="bv">A delegate that generates a bottom value for MyDomain.</param>
        /// <returns></returns>
        public FunctionalMap <int, IMethodAnalysisFixPoint <Variable> > Analyze <MyDomain>(
            IMoveNextOnePassAnalysis <Local, Parameter, Method, Field, Property, Type, Expression, Attribute, Assembly, MyDomain, Variable> analysis,
            StateGenerator <MyDomain> bv)
        {
            // Use a pre-analysis to collect information regarding the state machine.
            MoveNextStateAnalyzer           preAnalyzer = new MoveNextStateAnalyzer();
            StateMachineInformation <Local> stateInfo   = preAnalyzer.AnalyzeMoveNext("MoveNext", driver);

            // If we are not able
            if (stateInfo.OrderedVisibleStates == null || stateInfo.OrderedVisibleStates.Count() == 0)
            {
                throw new ArgumentException("Argument error with MoveNext method: Cannot analyze the state machine.");
            }

            // Fix point computation: fixpoint of the iterator analysis is a mapping: answers.
            bool     fixedpointReached = false;
            MyDomain d = default(MyDomain), oldd = default(MyDomain);
            FunctionalMap <int, IMethodAnalysisFixPoint <Variable> > answers = FunctionalMap <int, IMethodAnalysisFixPoint <Variable> > .Empty;
            MyDomain invariantCandidate   = default(MyDomain);
            Converter <Variable, int> key = driver.KeyNumber;

            int pass = 0;

            while (!fixedpointReached)
            {
                fixedpointReached = true;
                // Going through every state of the state machine, if the final states changes at least once
                // then fixpoint is not reached.
                foreach (int state in stateInfo.OrderedVisibleStates)
                {
                    // The initial state is only analyzed once.
                    if (state < 0)
                    {
                        continue;
                    }
                    if (state == 0 && pass > 0)
                    {
                        continue;
                    }

                    // Initial value for one pass, either TOP, if we analyze it for the first time
                    // or the invariantCandidate.
                    if (invariantCandidate == null || invariantCandidate.Equals(default(MyDomain)))
                    {
                        d = analysis.GetInitialValue(key);
                    }
                    else
                    {
                        d = analysis.MutableVersion(invariantCandidate);
                    }

                    // Call the underlying analysis for one pass
                    Set <APC> cutOffPCs = GetStateEntriesOtherThan(stateInfo, state);
                    driver.CreateForwardForIterator(analysis, bv, cutOffPCs)(d);

                    // Getting the state from the return point of the most recent pass, map it
                    // to the entry point, and join it with the current invariant candidate
                    IFunctionalMap <Variable, FList <Variable> > mapping = GetFieldMapping(driver);
                    var      fakeEdge    = new Pair <APC, APC>(driver.CFG.NormalExit, driver.CFG.Entry);
                    MyDomain returnState = analysis.ReturnState;
                    MyDomain newState    = analysis.ParallelAssign(fakeEdge, mapping, returnState);
                    bool     changed     = false;
                    if (invariantCandidate != null && !invariantCandidate.Equals(default(MyDomain)))
                    {
                        oldd = invariantCandidate;
                        // TODO: use a more sophisticated widenning strategy.
                        bool toWiden = (pass > 2) ? true : false;
                        d = analysis.Join(fakeEdge, newState, oldd, out changed, toWiden);
                        if (changed)
                        {
                            invariantCandidate = d;
                        }
                    }
                    else
                    {
                        changed            = true;
                        invariantCandidate = newState;
                    }
                    if (changed)
                    {
                        fixedpointReached = false;
                    }

                    // Fill the result table with the most recent fixpoint information.
                    answers  = (FunctionalMap <int, IMethodAnalysisFixPoint <Variable> >)answers.Add(state, analysis.ExtractResult());
                    analysis = analysis.Duplicate();
                }
                pass++;
            }
            return(answers);
        }