예제 #1
0
        /// <summary>
        /// Refines the given state according to the knowledge stored in the egraph about sv
        ///
        /// In addition, the state can be null when the knowledge is inconsistent.
        /// </summary>
        /// <param name="cv">symbolic value we assume to be non-null (true)</param>
        /// <param name="state">state if sv is non-null (true)</param>
        private static void AssumeTrue(ISymValue cv, ref ExposureState state)
        {
            if (state == null)
            {
                return;
            }

            foreach (EGraphTerm t in state.egraph.EqTerms(cv))
            {
                ISymValue op = t.Args[0];
                if (t.Function == ExposureState.EqIsExposedId)
                {
                    // EqIsExposed(op) == true, therefore op *is* exposed
                    state.AssignFrameForExposed(op);
                }
                else if (t.Function == ExposureState.EqIsExposableId)
                {
                    state.AssignFrameForExposable(op);
                }
            }
        }
예제 #2
0
        protected override object VisitCall(Variable dest, Variable receiver, Method callee, ExpressionList arguments, bool virtcall, Statement stat, object arg)
        {
            ExposureState estate = (ExposureState)arg;

            if (callee.CciKind == Cci.CciMemberKind.FrameGuardGetter)
            {
                // associate dest with receiver, because unpack is going to happen with dest as receiver
                estate.AssignFrameFor(dest, receiver, callee.DeclaringType); // receiver could be a subtype of the type that the frame guard is for
            }
            else if (callee == UnpackMethod)
            {
                if (estate.IsFrameExposable(receiver))
                {
                    // BUGBUG: Using CopyVariable encodes the assumption that StartWritingTransitively returns itself!!! It may not!
                    estate.CopyVariable(receiver, dest);
                    estate.AssignFrameForExposed(dest);
                }
                else
                {
                    TypeNode t = estate.LowerBoundOfObjectPointedToByFrame(receiver);
                    if (t == null) // BUGBUG: is this the same as it being Top?
                    {
                        HandleError(stat, stat, Error.DontKnowIfCanExposeObject);
                    }
                    else
                    {
                        HandleError(stat, stat, Error.ExposingExposedObject);
                    }
                    return(null);
                }
            }
            else if (callee == PackMethod)
            {
                estate.AssignFrameForNotExposed(receiver);
            }
            else if (callee == IsExposableMethod)
            {
                estate.AssignFunctionLink(ExposureState.EqIsExposableId, dest, receiver);
            }
            else if (callee == IsExposedMethod)
            {
                estate.AssignEqIsExposed(dest, receiver);
            }
            else if (callee == AssertMethod)
            {
                Variable v = arguments[0] as Variable;
                if (v != null && estate.IsFalse(v))
                {
                    return(null);
                }
            }

            // Push possible exceptions to handlers.
            for (int i = 0; i < callee.Contract.Ensures.Count; i++)
            {
                EnsuresExceptional e = callee.Contract.Ensures[i] as EnsuresExceptional;
                if (e != null)
                {
                    ExposureState newnn = new ExposureState(estate);
                    newnn.currentException = e.Type;
                    ExposureChecker.PushExceptionState(ExposureChecker.currBlock, newnn);
                }
            }

            return(arg);
        }