From: Erich Keane Date: Thu, 5 Jul 2018 15:52:58 +0000 (+0000) Subject: Fix __builtin_*_overflow when out-param isn't constexpr X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=feb79d981fdf259f32f6b6353a20624f580db2c0;p=clang Fix __builtin_*_overflow when out-param isn't constexpr As brought up on cfe-commits[1], r334650 causes the dependency of the out parameter to the __builtin_*_overflow functions to be ignored. The result was a usage that was otherwise constexpr (both operands to the operation were constexpr) would be evaluated, but the out parameter wouldn't be modified, so it would still be 'undef'. This patch correctly handles the return value of handleAssignment to ensure that this value is properly considered/evaluated. [1] http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20180702/233667.html git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@336364 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index c700da635b..828368a3e1 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -8346,7 +8346,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, } APValue APV{Result}; - handleAssignment(Info, E, ResultLValue, ResultType, APV); + if (!handleAssignment(Info, E, ResultLValue, ResultType, APV)) + return false; return Success(DidOverflow, E); } } diff --git a/test/CodeGenCXX/builtins.cpp b/test/CodeGenCXX/builtins.cpp index a49deea252..33c714e9e1 100644 --- a/test/CodeGenCXX/builtins.cpp +++ b/test/CodeGenCXX/builtins.cpp @@ -30,3 +30,19 @@ long y = __builtin_abs(-2l); extern const char char_memchr_arg[32]; char *memchr_result = __builtin_char_memchr(char_memchr_arg, 123, 32); // CHECK: call i8* @memchr(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @char_memchr_arg, i32 0, i32 0), i32 123, i64 32) + +int constexpr_overflow_result() { + constexpr int x = 1; + // CHECK: alloca i32 + constexpr int y = 2; + // CHECK: alloca i32 + int z; + // CHECK: [[Z:%.+]] = alloca i32 + + __builtin_sadd_overflow(x, y, &z); + return z; + // CHECK: [[RET_PTR:%.+]] = extractvalue { i32, i1 } %0, 0 + // CHECK: store i32 [[RET_PTR]], i32* [[Z]] + // CHECK: [[RET_VAL:%.+]] = load i32, i32* [[Z]] + // CHECK: ret i32 [[RET_VAL]] +}