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