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