Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -4579,7 +4579,7 @@ } 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 @@ auto Args = llvm::makeArrayRef(E->getArgs(), E->getNumArgs()); bool HasQualifier = false; + struct EvaluateIgnoredRAII { + public: + EvaluateIgnoredRAII(EvalInfo &Info, llvm::ArrayRef 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 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 @@ 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 @@ 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; Index: test/Sema/integer-overflow.c =================================================================== --- test/Sema/integer-overflow.c +++ test/Sema/integer-overflow.c @@ -151,6 +151,14 @@ uint64_t *b; uint64_t b2 = b[4608 * 1024 * 1024] + 1; +// expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}} + f0(4608 * 1024 * 1024); + f0(4608ul * 1024 * 1024); +// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} + f1(4608 * 1024 * 1024, 4608 * 1024 * 1024); +// expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} + f2(4608 * 1024 * 1024, 4608 * 1024 * 1024); + // expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}} int j1 = i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024);