public void IsInst <Type>(Type type, BoxedExpression argument, BoxedExpression original) { argument.Dispatch(this); if (this.PartialResult != null) { NotifyOkAndSetResult(ClousotExpression <Type> .MakeIsInst(type, this.PartialResult)); } else { NotifyNotOk(original); } }
/// <summary> /// If failIfCannotReplaceVarsWithAccessPaths is true, whenever we cannot convert a variable into an expression, we return null. /// Otherwise (when failIfCannotReplaceVarsWithAccessPaths is false), then we return the same expression /// </summary> public BoxedExpression ReadAt(APC pc, BoxedExpression exp, bool failIfCannotReplaceVarsWithAccessPaths = true, Typ allowReturnValue = default(Typ)) { Contract.Requires(exp != null); if (this.boundVariables.Contains(exp)) { return(exp); } if (exp.IsVariable) { Variable var; if (exp.TryGetFrameworkVariable(out var)) { var accessPath = context.ValueContext.AccessPathList(pc, var, true, true, allowReturnValue); if (accessPath != null) { return(BoxedExpression.Var(var, accessPath)); } Contract.Assert(accessPath == null, "Just for readibility: we are here if we do not have an access path for the variable"); return(failIfCannotReplaceVarsWithAccessPaths ? null : exp); } return(null); } BinaryOperator bop; BoxedExpression left, right; if (exp.IsBinaryExpression(out bop, out left, out right)) { Variable leftVar, rightVar; if (left.TryGetFrameworkVariable(out leftVar) && right.IsConstant) { var typeLeft = this.context.ValueContext.GetType(pc, leftVar); if (typeLeft.IsNormal && IsInterestingBoundFromTheTypeRange(right, typeLeft.Value)) { var recurse = ReadAt(pc, left, failIfCannotReplaceVarsWithAccessPaths, allowReturnValue); if (recurse != null) { return(BoxedExpression.Binary(bop, recurse, right)); } } return(null); } if (left.IsConstant && right.TryGetFrameworkVariable(out rightVar)) { var typeRight = this.context.ValueContext.GetType(pc, rightVar); if (typeRight.IsNormal && IsInterestingBoundFromTheTypeRange(left, typeRight.Value)) { var recurse = ReadAt(pc, right, failIfCannotReplaceVarsWithAccessPaths, allowReturnValue); if (recurse != null) { return(BoxedExpression.Binary(bop, left, recurse)); } } return(null); } var recurseLeft = ReadAt(pc, left, failIfCannotReplaceVarsWithAccessPaths, allowReturnValue); var recurseRight = ReadAt(pc, right, failIfCannotReplaceVarsWithAccessPaths, allowReturnValue); if (recurseLeft != null && recurseRight != null) { return(BoxedExpression.Binary(bop, recurseLeft, recurseRight)); } else { return(null); } } UnaryOperator uop; if (exp.IsUnaryExpression(out uop, out left)) { var recurse = ReadAt(pc, left, failIfCannotReplaceVarsWithAccessPaths, allowReturnValue); if (recurse != null) { return(BoxedExpression.Unary(uop, recurse)); } return(null); } object type; if (exp.IsIsInstExpression(out left, out type)) { var recurse = ReadAt(pc, left, failIfCannotReplaceVarsWithAccessPaths, allowReturnValue); if (recurse != null) { return(ClousotExpression <Type> .MakeIsInst((Type)type, recurse)); } return(null); } bool isForAll; BoxedExpression boundVar, inf, sup, body; if (exp.IsQuantifiedExpression(out isForAll, out boundVar, out inf, out sup, out body)) { Contract.Assert(boundVar != null); Contract.Assert(inf != null); Contract.Assert(sup != null); Contract.Assert(body != null); this.boundVariables.Add(boundVar); var infRec = ReadAt(pc, inf, failIfCannotReplaceVarsWithAccessPaths, allowReturnValue); if (infRec != null) { var supRec = ReadAt(pc, sup, failIfCannotReplaceVarsWithAccessPaths, allowReturnValue); if (supRec != null) { var bodyRec = ReadAt(pc, body, failIfCannotReplaceVarsWithAccessPaths, allowReturnValue); if (bodyRec != null) { this.boundVariables.Remove(boundVar); if (isForAll) { return(new ForAllIndexedExpression(null, boundVar, infRec, supRec, bodyRec)); } else { return(new ExistsIndexedExpression(null, boundVar, infRec, supRec, bodyRec)); } } } } return(null); } object t; BoxedExpression array, index; if (exp.IsArrayIndexExpression(out array, out index, out t) && t is Typ) { var arrayRec = ReadAt(pc, array, failIfCannotReplaceVarsWithAccessPaths, allowReturnValue); if (arrayRec != null) { var indexRec = ReadAt(pc, index, failIfCannotReplaceVarsWithAccessPaths, allowReturnValue); if (indexRec != null) { return(new BoxedExpression.ArrayIndexExpression <Typ>(arrayRec, indexRec, (Typ)t)); } } } return(exp); }