private FList <Variable> AddVariablesForsArrayLengths(APC pc, FList <Variable> variables) { Contract.Ensures(variables == null || Contract.Result <FList <Variable> >() != null); if (variables == FList <Variable> .Empty) { return(variables); } var postPC = pc.Post(); var arrayLenghts = FList <Variable> .Empty; foreach (var v in variables.GetEnumerable()) { Variable vLength; if (this.mDriver.Context.ValueContext.TryGetArrayLength(postPC, v, out vLength)) { arrayLenghts = arrayLenghts.Cons(vLength); } } if (!arrayLenghts.IsEmpty()) { variables = variables.Append(arrayLenghts); Contract.Assert(variables != null); } return(variables); }
private EnumDefined <BoxedVariable <Variable>, Type, BoxedExpression> AssumeIfEnumType(APC pc, Variable dest, EnumDefined <BoxedVariable <Variable>, Type, BoxedExpression> data) { var type = this.Context.ValueContext.GetType(pc.Post(), dest); if (type.IsNormal) { return(this.AssumeIfEnumType(type.Value, dest, data)); } return(data); }
public override DisjunctiveRefinement Call <TypeList, ArgList>(APC pc, Method method, bool tail, bool virt, TypeList extraVarargs, Variable dest, ArgList args, DisjunctiveRefinement data) { this.InferExceptionHandlers(pc); var asForAll = this.MethodDriver.AsForAllIndexed(pc.Post(), dest); if (asForAll != null) { data[new BoxedVariable <Variable>(dest)] = new SetOfConstraints <BoxedExpression>(asForAll); } else { this.MethodCalls.Add(new MethodCallInfo <Method, Variable>(pc, method, args.Enumerate().ToList())); } return(data); }
public override ArrayState Call <TypeList, ArgList>(APC pc, Method method, bool tail, bool virt, TypeList extraVarargs, Variable dest, ArgList args, ArrayState data) { Contract.Assume(data != null); var mdd = this.DecoderForMetaData; var methodname = mdd.Name(method); Contract.Assert(methodname != null); var containingType = mdd.DeclaringType(method); var containingTypeName = mdd.Name(containingType); var nsName = mdd.Namespace(containingType); if (nsName != null && /* && methodname != null */ nsName.Equals("System") && methodname.Equals("GetTypeFromHandle")) { Type runtimeType; if (Context.ValueContext.IsRuntimeType(this.Context.MethodContext.CFG.Post(pc), dest, out runtimeType)) // Get the type { return(data.UpdatePluginAt(this.Id, Select(data).Update(dest, runtimeType))); } return(data); } if (nsName != null && nsName.Equals("System") && methodname.Equals("get_GenericTypeArguments")) { var runtimeTypes = Select(data); Contract.Assume(args.Count > 0); var key = args[0]; Type t; if (runtimeTypes.TryGetValue(key, out t)) { IIndexable <Type> typeList; Variable len; if (this.DecoderForMetaData.IsGeneric(t, out typeList, false) && this.MethodDriver.Context.ValueContext.TryGetArrayLength(pc.Post(), dest, out len)) { // assume lenght == typeList.Count + 1 var range = DisInterval.For(typeList.Count + 1); data.Numerical.AssumeInDisInterval(new BoxedVariable <Variable>(len), range); // unfortunately with side-effects ... } } return(data); } if (nsName != null && containingTypeName != null && nsName.Equals("System") && containingTypeName.Equals("Enum")) { Type type; if (args.Count == 2 && methodname == "IsDefined" && Select(data).TryGetValue(args[0], out type)) { var enumvalues = new List <int>(); if (mdd.TryGetEnumValues(type, out enumvalues)) { Variable unboxed; // We check if it is the right integer if (this.Context.ValueContext.TryUnbox(pc, args[1], out unboxed)) { var bounds = data.Numerical.BoundsFor(ToBoxedExpression(pc, unboxed)); var enumValues = DisInterval.For(enumvalues.ConvertAll(y => Interval.For(y))); if (bounds.LessEqual(enumValues)) { var guard = ToBoxedExpression(pc, dest); if (guard == null) { return(data); } var newNumerical = data.Numerical.TestTrue(guard) as INumericalAbstractDomain <BoxedVariable <Variable>, BoxedExpression>; Contract.Assume(newNumerical != null); return(data.UpdateNumerical(newNumerical)); } else if (bounds.Meet(enumValues).IsBottom) { var exp = ToBoxedExpression(pc, dest); if (exp == null) { return(data); } var newNumerical = data.Numerical.TestFalse(exp) as INumericalAbstractDomain <BoxedVariable <Variable>, BoxedExpression>; Contract.Assume(newNumerical != null); return(data.UpdateNumerical(newNumerical)); } } // Otherwise we check if it is used by name object value; Type typeValue; if (this.Context.ValueContext.IsConstant(pc, args[1], out typeValue, out value) && this.DecoderForMetaData.System_String.Equals(typeValue)) { List <string> enumFields; if (this.DecoderForMetaData.TryGetEnumFields(type, out enumFields)) { var enumFieldName = value as string; Contract.Assume(enumFieldName != null); if (enumFields.Contains(enumFieldName)) { var exp = ToBoxedExpression(pc, dest); if (exp == null) { return(data); } var newNumerical = data.Numerical.TestTrue(exp) as INumericalAbstractDomain <BoxedVariable <Variable>, BoxedExpression>; Contract.Assume(newNumerical != null); return(data.UpdateNumerical(newNumerical)); } else { var exp = ToBoxedExpression(pc, dest); if (exp == null) { return(data); } var newNumerical = data.Numerical.TestFalse(exp) as INumericalAbstractDomain <BoxedVariable <Variable>, BoxedExpression>; Contract.Assume(newNumerical != null); return(data.UpdateNumerical(newNumerical)); } } } } } } return(data); }