public Preconditions Ldelem(APC pc, Type type, Variable dest, Variable array, Variable index, Preconditions pre) { BreakHere(pc, pre); if (pre != null) { var result = new Preconditions(); var ldElemExp = new BoxedExpression.ArrayIndexExpression <Type>(BoxedExpression.Var(array), BoxedExpression.Var(index), type); var destExp = BoxedExpression.Var(dest); foreach (var p in pre) { if (p != null) { result.AddIfNotNull(p.Substitute(destExp, ldElemExp)); } } return(result); } else { return(pre); } }
private BoxedExpression GenerateTheExists(APC exitPC, BoxedExpression variable, Type arrayType, BoxedExpression array) { Contract.Requires(variable != null); Contract.Requires(array != null); BoxedExpression newPost = null; var boundedVariable = BoxedExpression.Var("__j__"); var lowerBound = BoxedExpression.Const(0, this.DecoderForMetaData.System_Int32, this.DecoderForMetaData); Variable arrayVar, arrayLength; if (array.TryGetFrameworkVariable(out arrayVar) && this.Context.ValueContext.TryGetArrayLength(exitPC, arrayVar, out arrayLength)) { var upperBound = BoxedExpression.Var(arrayLength, this.Context.ValueContext.VisibleAccessPathListFromPost(exitPC, arrayLength)); // arr[boundedVariable] == variable var arrayLoad = new BoxedExpression.ArrayIndexExpression <Type>(array, boundedVariable, arrayType); var eq = BoxedExpression.Binary(BinaryOperator.Ceq, arrayLoad, variable); newPost = new ExistsIndexedExpression(null, boundedVariable, lowerBound, upperBound, eq); } return(newPost); }
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 bool SuggestAnalysisSpecificPostconditions( ContractInferenceManager inferenceManager, IFixpointInfo <APC, ArrayState> fixpointInfo, List <BoxedExpression> postconditions) { Contract.Assert(this.MethodDriver.CFG != null); var exitPC = this.MethodDriver.CFG.NormalExit; ArrayState exitState; if (fixpointInfo.PostState(exitPC, out exitState)) { var mySubState = Select(exitState); foreach (var pair in mySubState.Elements) { // Try to get a variable name for it var variable = ReadVariableInPostState(exitPC, pair.Key); if (variable == null) { // we fail to get a name in the post state, let us see if it is a constant Int64 k; var intv = exitState.Numerical.BoundsFor(pair.Key); if (intv.IsSingleton && intv.LowerBound.TryInt64(out k)) { variable = BoxedExpression.Const(k, this.DecoderForMetaData.System_Int64, this.DecoderForMetaData); } else { continue; } } Contract.Assert(variable != null); Contract.Assume(pair.Value != null); if (pair.Value.IsNormal() && pair.Value.IsUnmodifiedFromEntry.IsTrue()) { foreach (var arrayBoxed in pair.Value.Left.Values) { Contract.Assume(arrayBoxed != null); var arrayType = GetTypeOrObject(exitPC, arrayBoxed); var array = ReadVariableInPostState(exitPC, arrayBoxed); if (array != null) { // If we have one or more definite values for the index expression, we use them if (pair.Value.Right.IsNormal()) { foreach (var indexBoxed in pair.Value.Right.Values) { BoxedExpression newPost = null; Contract.Assume(indexBoxed != null); var index = ReadVariableInPostState(exitPC, indexBoxed); if (index == null) { newPost = GenerateTheExists(exitPC, variable, arrayType, array); } else { #region Generate arr[index] == variable var arrayLoad = new BoxedExpression.ArrayIndexExpression <Type>(array, index, arrayType); newPost = BoxedExpression.Binary(BinaryOperator.Ceq, arrayLoad, variable); #endregion } postconditions.AddIfNotNull(newPost); } } // else, if we know it is top, we can simp,y project over it else if (pair.Value.Right.IsTop) { postconditions.AddIfNotNull(GenerateTheExists(exitPC, variable, arrayType, array)); } } } } } } return(false); }