Exemplo n.º 1
0
        MyDomain GetReturnState <MyDomain>(IFixpointInfo <APC, MyDomain> fixpoint, IAbstractAnalysis <Local, Parameter, Method, Field, Property, Type, Expression, Attribute, Assembly, MyDomain, Variable> analysis, int state, out bool isBottom, MyDomain defaultValue)
        {
            MyDomain returnState = defaultValue;
            var      fakeEdge    = new Pair <APC, APC>(driver.CFG.NormalExit, driver.CFG.Entry);

            if (stateInfo.StateReturnPoints == null || !stateInfo.StateReturnPoints.ContainsKey(state))
            {
                isBottom = true;
            }
            else
            {
                bool first = true;
                isBottom = true;
                foreach (APC returnPoint in stateInfo.StateReturnPoints[state])
                {
                    MyDomain tmp;
                    if (fixpoint.PostState(returnPoint, out tmp) && !analysis.IsBottom(returnPoint, tmp))
                    {
                        isBottom = false;
                        var edge = new Pair <APC, APC>(returnPoint, driver.CFG.Entry.Post());
                        IFunctionalMap <Variable, FList <Variable> > mapping = GetFieldMapping(driver, returnPoint, driver.CFG.Entry.Post());
                        MyDomain newState = analysis.EdgeConversion(fakeEdge.One, fakeEdge.Two, true, mapping, tmp);
                        bool     ignore;
                        if (first)
                        {
                            returnState = newState;
                            first       = false;
                        }
                        else
                        {
                            returnState = analysis.Join(edge, newState, returnState, out ignore, false);
                        }
                    }
                }
            }
            return(returnState);
        }
Exemplo n.º 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 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);
        }