[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)

via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 27 05:50:22 PDT 2024


https://github.com/overmighty updated https://github.com/llvm/llvm-project/pull/86742

>From c615f656153fcb1d4158548660f87d1d69960864 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Tue, 26 Mar 2024 21:25:59 +0000
Subject: [PATCH 1/3] [clang][ExprConst] Fix second arg of
 __builtin_{clzg,ctzg} not always being evaluated

---
 clang/lib/AST/ExprConstant.cpp                | 30 +++++++++-----
 .../constant-builtins-all-args-evaluated.cpp  | 39 +++++++++++++++++++
 2 files changed, 59 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/Sema/constant-builtins-all-args-evaluated.cpp

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 5a36621dc5cce2..dae8f32fc02951 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -12361,12 +12361,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     if (!EvaluateInteger(E->getArg(0), Val, Info))
       return false;
 
+    std::optional<APSInt> Fallback;
+    if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) {
+      APSInt FallbackTemp;
+      if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info))
+        return false;
+      Fallback = FallbackTemp;
+    }
+
     if (!Val) {
-      if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) {
-        if (!EvaluateInteger(E->getArg(1), Val, Info))
-          return false;
-        return Success(Val, E);
-      }
+      if (Fallback)
+        return Success(*Fallback, E);
 
       // When the argument is 0, the result of GCC builtins is undefined,
       // whereas for Microsoft intrinsics, the result is the bit-width of the
@@ -12425,12 +12430,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     if (!EvaluateInteger(E->getArg(0), Val, Info))
       return false;
 
+    std::optional<APSInt> Fallback;
+    if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) {
+      APSInt FallbackTemp;
+      if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info))
+        return false;
+      Fallback = FallbackTemp;
+    }
+
     if (!Val) {
-      if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) {
-        if (!EvaluateInteger(E->getArg(1), Val, Info))
-          return false;
-        return Success(Val, E);
-      }
+      if (Fallback)
+        return Success(*Fallback, E);
 
       return Error(E);
     }
diff --git a/clang/test/Sema/constant-builtins-all-args-evaluated.cpp b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp
new file mode 100644
index 00000000000000..0dee74ddf690cf
--- /dev/null
+++ b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+constexpr int increment(int& x) {
+  x++;
+  return x;
+}
+
+constexpr int test_clzg_0() {
+  int x = 0;
+  [[maybe_unused]] int unused = __builtin_clzg(0U, increment(x));
+  return x;
+}
+
+static_assert(test_clzg_0() == 1);
+
+constexpr int test_clzg_1() {
+  int x = 0;
+  [[maybe_unused]] int unused = __builtin_clzg(1U, increment(x));
+  return x;
+}
+
+static_assert(test_clzg_1() == 1);
+
+constexpr int test_ctzg_0() {
+  int x = 0;
+  [[maybe_unused]] int unused = __builtin_ctzg(0U, increment(x));
+  return x;
+}
+
+static_assert(test_ctzg_0() == 1);
+
+constexpr int test_ctzg_1() {
+  int x = 0;
+  [[maybe_unused]] int unused = __builtin_ctzg(1U, increment(x));
+  return x;
+}
+
+static_assert(test_ctzg_1() == 1);

>From a0f90042bea48050e1e23aa95488e315fa3b40a2 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Tue, 26 Mar 2024 23:09:56 +0000
Subject: [PATCH 2/3] fixup! [clang][ExprConst] Fix second arg of
 __builtin_{clzg,ctzg} not always being evaluated

Co-authored-by: Richard Smith <richard at metafoo.co.uk>
---
 clang/test/Sema/constant-builtins-all-args-evaluated.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/Sema/constant-builtins-all-args-evaluated.cpp b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp
index 0dee74ddf690cf..f4452b1478e3fd 100644
--- a/clang/test/Sema/constant-builtins-all-args-evaluated.cpp
+++ b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp
@@ -8,7 +8,7 @@ constexpr int increment(int& x) {
 
 constexpr int test_clzg_0() {
   int x = 0;
-  [[maybe_unused]] int unused = __builtin_clzg(0U, increment(x));
+  (void)__builtin_clzg(0U, increment(x));
   return x;
 }
 
@@ -16,7 +16,7 @@ static_assert(test_clzg_0() == 1);
 
 constexpr int test_clzg_1() {
   int x = 0;
-  [[maybe_unused]] int unused = __builtin_clzg(1U, increment(x));
+  (void)__builtin_clzg(1U, increment(x));
   return x;
 }
 
@@ -24,7 +24,7 @@ static_assert(test_clzg_1() == 1);
 
 constexpr int test_ctzg_0() {
   int x = 0;
-  [[maybe_unused]] int unused = __builtin_ctzg(0U, increment(x));
+  (void)__builtin_ctzg(0U, increment(x));
   return x;
 }
 
@@ -32,7 +32,7 @@ static_assert(test_ctzg_0() == 1);
 
 constexpr int test_ctzg_1() {
   int x = 0;
-  [[maybe_unused]] int unused = __builtin_ctzg(1U, increment(x));
+  (void)__builtin_ctzg(1U, increment(x));
   return x;
 }
 

>From 951e8d28daecc6be17746069452fb6fa9bb27f8c Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Wed, 27 Mar 2024 12:49:27 +0000
Subject: [PATCH 3/3] fixup! [clang][ExprConst] Fix second arg of
 __builtin_{clzg,ctzg} not always being evaluated

---
 .../Sema/constant-builtins-all-args-evaluated.cpp   | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/clang/test/Sema/constant-builtins-all-args-evaluated.cpp b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp
index f4452b1478e3fd..db55e24cecda7a 100644
--- a/clang/test/Sema/constant-builtins-all-args-evaluated.cpp
+++ b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp
@@ -1,14 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 // expected-no-diagnostics
 
-constexpr int increment(int& x) {
-  x++;
-  return x;
-}
-
 constexpr int test_clzg_0() {
   int x = 0;
-  (void)__builtin_clzg(0U, increment(x));
+  (void)__builtin_clzg(0U, ++x);
   return x;
 }
 
@@ -16,7 +11,7 @@ static_assert(test_clzg_0() == 1);
 
 constexpr int test_clzg_1() {
   int x = 0;
-  (void)__builtin_clzg(1U, increment(x));
+  (void)__builtin_clzg(1U, ++x);
   return x;
 }
 
@@ -24,7 +19,7 @@ static_assert(test_clzg_1() == 1);
 
 constexpr int test_ctzg_0() {
   int x = 0;
-  (void)__builtin_ctzg(0U, increment(x));
+  (void)__builtin_ctzg(0U, ++x);
   return x;
 }
 
@@ -32,7 +27,7 @@ static_assert(test_ctzg_0() == 1);
 
 constexpr int test_ctzg_1() {
   int x = 0;
-  (void)__builtin_ctzg(1U, increment(x));
+  (void)__builtin_ctzg(1U, ++x);
   return x;
 }
 



More information about the cfe-commits mailing list