Beispiel #1
0
                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);
                }
Beispiel #2
0
                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);
                }