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