private List <BoxedExpression> GetForAllVisibleOutsideOfTheMethod(
                    BoxedVariable <Variable> array,
                    ArraySegmentation <FlatAbstractDomainOfBoolsWithRenaming <BoxedVariable <Variable> >, BoxedVariable <Variable>, BoxedExpression> segmentation)
                {
                    Contract.Requires(array != null);
                    Contract.Requires(segmentation != null);

                    var result = new List <BoxedExpression>();

                    var arrayBE = ReadVariableInPreStateForRequires(this.Context.MethodContext.CFG.EntryAfterRequires, array);

                    if (arrayBE != null)
                    {
                        var boundVar   = BoxedExpression.Var("i");
                        var arrayindex = new BoxedExpression.ArrayIndexExpression <Type>(arrayBE, boundVar, this.DecoderForMetaData.System_Object);
                        var factory    = new BoxedExpressionFactory <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly, Variable>(
                            boundVar, arrayindex,
                            (v => ReadVariableInPreStateForRequires(this.Context.MethodContext.CFG.EntryAfterRequires, v)),
                            this.DecoderForMetaData, null);
                        var formula = segmentation.To(factory);
                        if (formula != null)
                        {
                            result.AddRange(factory.SplitAnd(formula));
                        }
                    }

                    return(result);
                }
                public override ArrayState Ldelem(APC pc, Type type, Variable dest, Variable array, Variable index, ArrayState data)
                {
                    var mySubState = Select(data);
                    var bArray     = new BoxedVariable <Variable>(array);
                    ArraySegmentation <NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression>, BoxedVariable <Variable>, BoxedExpression>
                    existentialSegmentation;

                    var noConstraints = SetOfConstraints <BoxedVariable <Variable> > .Unknown;
                    var newElement    = new NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression>(DisInterval.UnknownInterval, SymbolicExpressionTracker <BoxedVariable <Variable>, BoxedExpression> .Unknown,
                                                                                                                      new SetOfConstraints <BoxedVariable <Variable> >(new BoxedVariable <Variable>(dest)),
                                                                                                                      noConstraints, noConstraints, noConstraints, noConstraints);


                    if (mySubState.TryGetValue(bArray, out existentialSegmentation))
                    {
                        if (existentialSegmentation.IsNormal())
                        {
                            var newSegmentation = new ArraySegmentation <NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression>, BoxedVariable <Variable>, BoxedExpression>
                                                      (new NonNullList <SegmentLimit <BoxedVariable <Variable> > >()
                            {
                                existentialSegmentation.Limits.AsIndexable()[0], existentialSegmentation.LastLimit
                            },
                                                      new NonNullList <NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression> >()
                            {
                                newElement
                            },
                                                      existentialSegmentation.Elements.AsIndexable()[0].Bottom, this.ExpressionManager);

                            var meet = existentialSegmentation.Meet(newSegmentation);

                            mySubState.Update(bArray, meet);

                            return(data.UpdatePluginAt(this.Id, mySubState));
                        }
                    }
                    else // materialize
                    {
                        existentialSegmentation = MaterializeArray(this.Context.MethodContext.CFG.Post(pc),
                                                                   mySubState, data.Numerical.CheckIfNonZero, array, newElement, newElement.Bottom);

                        // Segmentation may fail
                        if (existentialSegmentation != null)
                        {
                            mySubState.Update(bArray, existentialSegmentation);

                            return(data.UpdatePluginAt(this.Id, mySubState));
                        }
                    }

                    return(data);
                }
                protected ArraySegmentation <Elements, BoxedVariable <Variable>, BoxedExpression> MaterializeArray <Elements>(
                    APC postPC, ArraySegmentationEnvironment <Elements, BoxedVariable <Variable>, BoxedExpression> preState,
                    Func <BoxedExpression, FlatAbstractDomain <bool> > CheckIfNonZero, Variable arrayValue, Elements initialValue, Elements bottom)
                    where Elements : class, IAbstractDomainForArraySegmentationAbstraction <Elements, BoxedVariable <Variable> >
                {
                    Contract.Requires(preState != null);
                    Contract.Requires(initialValue != null);

                    var boxSym = new BoxedVariable <Variable>(arrayValue);

                    ArraySegmentation <Elements, BoxedVariable <Variable>, BoxedExpression> arraySegment;

                    if (preState.TryGetValue(boxSym, out arraySegment))
                    {
                        return(arraySegment); // already materialized
                    }

                    Variable array_Length;

                    if (this.Context.ValueContext.TryGetArrayLength(postPC, arrayValue, out array_Length))
                    {
                        var isNonEmpty = CheckIfNonZero(this.ToBoxedExpression(postPC, array_Length)).IsTrue();

                        var limits = new NonNullList <SegmentLimit <BoxedVariable <Variable> > >()
                        {
                            new SegmentLimit <BoxedVariable <Variable> >(NormalizedExpression <BoxedVariable <Variable> > .For(0), false),                                               // { 0 }
                            new SegmentLimit <BoxedVariable <Variable> >(NormalizedExpression <BoxedVariable <Variable> > .For(new BoxedVariable <Variable>(array_Length)), !isNonEmpty) // { symb.Length }
                        };

                        var elements = new NonNullList <Elements>()
                        {
                            initialValue
                        };

                        var newSegment = new ArraySegmentation <Elements, BoxedVariable <Variable>, BoxedExpression>(
                            limits, elements,
                            bottom,
                            this.ExpressionManager);

                        preState.AddElement(new BoxedVariable <Variable>(arrayValue), newSegment);

                        return(newSegment);
                    }

                    return(null);
                }
                private bool AllSegmentsUnmodified(
                    ArraySegmentation <TwoValuesLattice <BoxedVariable <Variable> >, BoxedVariable <Variable>, BoxedExpression> arraySegmentation)
                {
                    Contract.Requires(arraySegmentation != null);
                    if (arraySegmentation.IsEmptyArray || !arraySegmentation.IsNormal)
                    {
                        return(false);
                    }

                    foreach (var segment in arraySegmentation.Elements)
                    {
                        if (segment.IsTop)
                        {
                            return(false);
                        }
                    }

                    return(true);
                }
Ejemplo n.º 5
0
        public void Update(Variable v, ArraySegmentation <AbstractDomain, Variable, Expression> newVal)
        {
            Contract.Requires(newVal != null);

            this[v] = newVal;
        }
                protected bool TryCreateArraySegment(BoxedExpression low, BoxedExpression upp, Variable arrayLen,
                                                     AbstractDomain intv,
                                                     INumericalAbstractDomain <BoxedVariable <Variable>, BoxedExpression> numDom,
                                                     out ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression> arraySegmentation)
                {
                    #region Contracts

                    Contract.Requires(low != null);
                    Contract.Requires(upp != null);
                    Contract.Requires(intv != null);
                    Contract.Requires(arrayLen != null);
                    Contract.Requires(numDom != null);

                    Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out arraySegmentation) != null);

                    #endregion

                    var lowerBounds = new Set <NormalizedExpression <BoxedVariable <Variable> > >();

                    lowerBounds.AddIfNotNull(low.ToNormalizedExpression <Variable>());

                    var upperBounds = new Set <NormalizedExpression <BoxedVariable <Variable> > >();

                    upperBounds.AddIfNotNull(upp.ToNormalizedExpression <Variable>());
                    upperBounds.AddIfNotNull(upp.ToNormalizedExpression <Variable>(true));
                    upperBounds.AddIfNotNull(upp.Simplify(this.DecoderForMetaData).ToNormalizedExpression <Variable>());
                    upperBounds.AddIfNotNull(this.Decoder.Stripped(upp).ToNormalizedExpression <Variable>());

                    if (lowerBounds.Count == 0 || upperBounds.Count == 0)
                    {
                        arraySegmentation = null;
                        return(false);
                    }

                    var segments = new NonNullList <SegmentLimit <BoxedVariable <Variable> > >();

                    var elements = new NonNullList <AbstractDomain>();

                    #region Build the prefix

                    // Check if low is zero
                    int lowValue;
                    if (low.IsConstantInt(out lowValue))
                    {
                        if (lowValue < 0)
                        {
                            arraySegmentation = default(ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression>);
                            return(false);
                        }

                        // { 0 } Top { lowValue }
                        if (lowValue > 0)
                        {
                            segments.Add(new SegmentLimit <BoxedVariable <Variable> >(NormalizedExpression <BoxedVariable <Variable> > .For(0), false));
                            elements.Add((AbstractDomain)intv.Top);
                        }

                        //  .. { lowValue } intv
                        segments.Add(new SegmentLimit <BoxedVariable <Variable> >(lowerBounds, false));
                        elements.Add(intv);
                    }
                    else if (numDom.CheckIfGreaterEqualThanZero(low).IsTrue())
                    {
                        // { 0 } Top { low }?
                        segments.Add(new SegmentLimit <BoxedVariable <Variable> >(NormalizedExpression <BoxedVariable <Variable> > .For(0), false));
                        elements.Add((AbstractDomain)intv.Top);

                        // intv { upp }?
                        segments.Add(new SegmentLimit <BoxedVariable <Variable> >(lowerBounds, true)); // F: we can improve precision by asking if low != 0
                        elements.Add(intv);
                    }
                    else
                    {
                        arraySegmentation = default(ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression>);
                        return(false);
                    }

                    #endregion

                    #region Build the suffix
                    // ... { upperBounds }
                    if (arrayLen.Equals(upp.UnderlyingVariable) || arrayLen.Equals(this.Decoder.Stripped(upp).UnderlyingVariable))
                    {
                        segments.Add(new SegmentLimit <BoxedVariable <Variable> >(upperBounds, false));
                    }
                    else // ... { upperBounds } Top { arrayLen }?
                    {
                        segments.Add(new SegmentLimit <BoxedVariable <Variable> >(upperBounds, false));
                        elements.Add((AbstractDomain)intv.Top);
                        segments.Add(
                            new SegmentLimit <BoxedVariable <Variable> >(
                                NormalizedExpression <BoxedVariable <Variable> > .For(new BoxedVariable <Variable>(arrayLen)), true));
                    }
                    #endregion

                    arraySegmentation = new ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression>(
                        segments, elements,
                        (AbstractDomain)intv.Bottom, this.ExpressionManager);

                    return(true);
                }