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); }
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); }