Esempio n. 1
0
        /// <summary>
        /// Copy the source to dest.
        ///
        /// If source is nonnull, no problem.
        /// If source is null and dest is nonnulltype, Error
        /// If source is possible null and dest is nonnulltype, warning.
        /// Else, nothing.
        ///
        /// Need to maintain proper heap transformation.
        /// </summary>
        /// <param name="dest"></param>
        /// <param name="source"></param>
        /// <param name="stat"></param>
        /// <param name="arg"></param>
        /// <returns></returns>
        protected override object VisitCopy(Variable dest, Variable source, Statement stat, object arg)
        {
            ExposureState estate = (ExposureState)arg;

            estate.CopyVariable(source, dest);

            return(arg);
        }
Esempio n. 2
0
        /// <summary>
        /// Note: casts don't require a non-null argument. null value casts always succeed.
        /// </summary>
        protected override object VisitCastClass(Variable dest, TypeNode type, Variable source, Statement stat, object arg)
        {
            ExposureState estate = (ExposureState)arg;

            // acts like a copy retaining null status
            estate.CopyVariable(source, dest);
            return(arg);
        }
Esempio n. 3
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);
        }