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