diff options
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 75bb0cac51b83..bd8b3abd92758 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -4579,7 +4579,7 @@ public: } bool handleCallExpr(const CallExpr *E, APValue &Result, - const LValue *ResultSlot) { + const LValue *ResultSlot) { const Expr *Callee = E->getCallee()->IgnoreParens(); QualType CalleeType = Callee->getType(); @@ -4588,6 +4588,23 @@ public: auto Args = llvm::makeArrayRef(E->getArgs(), E->getNumArgs()); bool HasQualifier = false; + struct EvaluateIgnoredRAII { + public: + EvaluateIgnoredRAII(EvalInfo &Info, llvm::ArrayRef<const Expr*> ToEval) + : Info(Info), ToEval(ToEval) {} + ~EvaluateIgnoredRAII() { + if (Info.noteFailure()) { + for (auto E : ToEval) + EvaluateIgnoredValue(Info, E); + } + } + void cancel() { ToEval = {}; } + void drop_front() { ToEval = ToEval.drop_front(); } + private: + EvalInfo &Info; + llvm::ArrayRef<const Expr*> ToEval; + } EvalArguments(Info, Args); + // Extract function decl and 'this' pointer from the callee. if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) { const ValueDecl *Member = nullptr; @@ -4637,10 +4654,12 @@ public: if (Args.empty()) return Error(E); - if (!EvaluateObjectArgument(Info, Args[0], ThisVal)) + const Expr *FirstArg = Args[0]; + Args = Args.drop_front(); + EvalArguments.drop_front(); + if (!EvaluateObjectArgument(Info, FirstArg, ThisVal)) return false; This = &ThisVal; - Args = Args.slice(1); } else if (MD && MD->isLambdaStaticInvoker()) { // Map the static invoker for the lambda back to the call operator. // Conveniently, we don't have to slice out the 'this' argument (as is @@ -4692,8 +4711,12 @@ public: const FunctionDecl *Definition = nullptr; Stmt *Body = FD->getBody(Definition); - if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body) || - !HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, Info, + if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body)) + return false; + + EvalArguments.cancel(); + + if (!HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, Info, Result, ResultSlot)) return false; |