示例#1
0
        public LispList <PathElement> VisibleAccessPathList(APC at, SymbolicValue value)
        {
            Domain domain;

            if (!this.parent.PreStateLookup(at, out domain))
            {
                throw new ArgumentException("pc wasn't visited");
            }

            AccessPathFilter <Method> filter = AccessPathFilter <Method> .FromPrecondition(MethodContext.CurrentMethod);

            return(domain.GetAccessPathList(value.Symbol, filter, false, false));
        }
示例#2
0
        public LispList <PathElement> AccessPathList(APC at, SymbolicValue sv, bool allowLocal, bool preferLocal)
        {
            Domain domain;

            if (!this.parent.PreStateLookup(at, out domain))
            {
                throw new ArgumentException("pc wasn't visited");
            }

            AccessPathFilter <Method> filter = AccessPathFilter <Method> .IsVisibleFrom(MethodContext.CurrentMethod);

            return(domain.GetAccessPathList(sv.Symbol, filter, allowLocal, preferLocal));
        }
        private BoxedExpression ExpressionInPostStateHelper(BoxedExpression exp, bool replaceReturnValue, bool overrideAccessModifiers, bool allowReturnValue, ref Details details)
        {
            if (exp.IsConstant || exp.IsSizeOf /*|| exp.IsNull*/)
            { // Nothing to do
                return(exp);
            }
            if (exp.IsNull)
            {
                return(BoxedExpression.Const(null, this.metaDataDecoder.System_Object, this.metaDataDecoder));
            }
            if (exp.IsVariable)
            {
                if (exp.IsVariableBoundedInQuantifier)
                {
                    return(exp);
                }

                // F: this check is there as there may be slack variables form subpolyhedra

                Variable var;
                if (!exp.TryGetFrameworkVariable(out var))
                {
                    return(null);
                }

                // We want to replace the return variable with the marker for the return value
                if (replaceReturnValue && this.returnVariable.IsValid && var.Equals(this.returnVariable.Value))
                {
                    details.HasVariables      = true;
                    details.HasReturnVariable = true;

                    return(this.returnExpression);
                }

                #region First try: Read it in the post-state
                var accessPath =
                    context.ValueContext.VisibleAccessPathListFromPost(context.MethodContext.CFG.NormalExit, var, allowReturnValue);

#if false
                // F: change!!!!

                // Console.WriteLine("Access paths for sv = {0}", var);
                foreach (var ap in context.ValueContext.AccessPaths(context.MethodContext.CFG.NormalExit, var, AccessPathFilter <Method> .FromPostcondition(this.context.MethodContext.CurrentMethod)))
                {
                    // Console.WriteLine(ap);
                    if (context.ValueContext.PathSuitableInEnsures(context.MethodContext.CFG.NormalExit, ap))
                    {
                        // we found our accesspath
                        accessPath = ap;
                        break;
                    }
                }
#endif
                if (accessPath != null)
                {
                    details.HasVariables = true;

                    details.HasReturnVariable = accessPath.Head.IsReturnValue;

                    if (accessPath.Length() == 1 && accessPath.ToString() == "this")
                    {
                        details.IsThis = true;
                    }

                    if (accessPath.Head.ToString() == "this")
                    {
                        details.IsRootedInThis = true;
                    }

                    // TODO: check possible bug here: this should be var not exp.UnderlyingVariable
                    return(BoxedExpression.Var(var, accessPath));
                }
                #endregion

                #region Second try: Read it in the pre-state
                accessPath =
                    // context.ValueContext.VisibleAccessPathListFromPre(context.MethodContext.CFG.EntryAfterRequires, var);
                    context.ValueContext.AccessPathList(context.MethodContext.CFG.EntryAfterRequires, var, false, false);

                if (accessPath != null)
                {
                    details.HasVariables = true;

                    var type = this.context.ValueContext.GetType(this.context.MethodContext.CFG.NormalExit, var);

                    if (type.IsNormal)
                    {
                        details.HasOldVariable = true;

                        return(BoxedExpression.Old(BoxedExpression.Var(var, accessPath), type.Value));
                    }
                    else
                    {
                        return(null);
                    }
                }
                #endregion

                #region Third try: use the extended refined, if any

                if (this.extendedRefiner != null)
                {
                    BoxedExpression refined;
                    if (this.extendedRefiner.TryRefineExpression(this.context.MethodContext.CFG.NormalExit, var, out refined) &&
                        refined.IsArrayIndex) // F: it seems we generate some recursive expression which causes a stack overflow. Should investigate!!!!
                    {
                        return(ExpressionInPostStateHelper(refined, replaceReturnValue, overrideAccessModifiers, allowReturnValue, ref details));
                    }
                }

                #endregion

                // giving up
                return(null);
            }
            if (exp.IsUnary)
            {
                var rec = ExpressionInPostStateHelper(exp.UnaryArgument, replaceReturnValue, overrideAccessModifiers, allowReturnValue, ref details);
                if (rec == null)
                {
                    return(null);
                }

                // Avoid copying the expression (optimization?)
                if (rec == exp.UnaryArgument)
                {
                    return(exp);
                }
                else
                {
                    return(BoxedExpression.Unary(exp.UnaryOp, rec));
                }
            }
            if (exp.IsBinary)
            {
                if (!exp.BinaryOp.IsComparisonBinaryOperator())
                {
                    details.HasCompoundExp = true;
                }
                var recLeft = ExpressionInPostStateHelper(exp.BinaryLeft, replaceReturnValue, overrideAccessModifiers, allowReturnValue, ref details);
                if (recLeft == null)
                {
                    return(null);
                }

                var recRight = ExpressionInPostStateHelper(exp.BinaryRight, replaceReturnValue, overrideAccessModifiers, allowReturnValue, ref details);
                if (recRight == null)
                {
                    return(null);
                }

                // Heuristics to rule out trivial expressions arr.Length >= 0 or 0 <= arr.Length or this.Count >= 0 or 0 <= this.Count
                int value;
                if ((exp.BinaryOp == BinaryOperator.Cge && recLeft.IsArrayLengthOrThisDotCount(context.MethodContext.CFG.NormalExit, this.context, this.metaDataDecoder) && recRight.IsConstantInt(out value) && value == 0)
                    ||
                    (exp.BinaryOp == BinaryOperator.Cle && recLeft.IsConstantInt(out value) && value == 0 && recRight.IsArrayLengthOrThisDotCount(context.MethodContext.CFG.NormalExit, this.context, this.metaDataDecoder)))
                {
                    return(null);
                }

                if (recLeft == exp.BinaryLeft && recRight == exp.BinaryRight)
                {
                    return(exp);
                }
                else
                {
                    return(BoxedExpression.Binary(exp.BinaryOp, recLeft, recRight));
                }
            }
            object          t;
            BoxedExpression array, index;
            if (exp.IsArrayIndexExpression(out array, out index, out t) && t is Typ)
            {
                // Sanity check. We have a case with post-inference where the array and the index get swapped by the underlying framework
                if (array.UnderlyingVariable is Variable)
                {
                    var type = this.context.ValueContext.GetType(context.MethodContext.CFG.NormalExit, (Variable)array.UnderlyingVariable);
                    if (type.IsNormal && this.metaDataDecoder.IsArray(type.Value))
                    {
                        var arrayRef = ExpressionInPostStateHelper(array, replaceReturnValue, overrideAccessModifiers, allowReturnValue, ref details);
                        if (arrayRef != null)
                        {
                            var indexRef = ExpressionInPostStateHelper(index, replaceReturnValue, overrideAccessModifiers, allowReturnValue, ref details);
                            if (indexRef != null)
                            {
                                return(new BoxedExpression.ArrayIndexExpression <Typ>(arrayRef, indexRef, (Typ)t));
                            }
                        }
                    }
                }

                return(null);
            }

            // Unreachable?
            return(null);
        }
示例#4
0
        public IEnumerable <LispList <PathElement> > AccessPaths(APC at, SymValue value, AccessPathFilter <Method> filter)
        {
            Domain domain;

            if (!this.parent.PreStateLookup(at, out domain))
            {
                throw new ArgumentException("pc wasn't visited");
            }

            return(domain.GetAccessPathsFiltered(value, filter, true).Select(path => path.Coerce <PathElementBase, PathElement> ()));
        }