Author: nicholas Date: Wed May 17 18:56:54 2017 New Revision: 303317 URL: http://llvm.org/viewvc/llvm-project?rev=303317&view=rev Log: The constant expression evaluator should examine function arguments for non-constexpr function calls unless the EvalInfo says to stop.
Modified: cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/test/Sema/integer-overflow.c Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=303317&r1=303316&r2=303317&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Wed May 17 18:56:54 2017 @@ -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; Modified: cfe/trunk/test/Sema/integer-overflow.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-overflow.c?rev=303317&r1=303316&r2=303317&view=diff ============================================================================== --- cfe/trunk/test/Sema/integer-overflow.c (original) +++ cfe/trunk/test/Sema/integer-overflow.c Wed May 17 18:56:54 2017 @@ -151,6 +151,14 @@ uint64_t check_integer_overflows(int i) 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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits