]> granicus.if.org Git - clang/commitdiff
Fix __builtin_*_overflow when out-param isn't constexpr
authorErich Keane <erich.keane@intel.com>
Thu, 5 Jul 2018 15:52:58 +0000 (15:52 +0000)
committerErich Keane <erich.keane@intel.com>
Thu, 5 Jul 2018 15:52:58 +0000 (15:52 +0000)
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

lib/AST/ExprConstant.cpp
test/CodeGenCXX/builtins.cpp

index c700da635b77d642060773589294d740a7044030..828368a3e12ab9f25c3e827cf888285c39bf9462 100644 (file)
@@ -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);
   }
   }
index a49deea2524c5829012ff2e2af4f38ac6e749f61..33c714e9e1861cea5c926a28c17a8bc96e60b3b8 100644 (file)
@@ -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]]
+}