[clang] c68baa7 - [clang] Fix incorrect constant folding of `if consteval`

Corentin Jabot via cfe-commits cfe-commits at lists.llvm.org
Sun Jul 24 07:18:17 PDT 2022


Author: Corentin Jabot
Date: 2022-07-24T16:18:12+02:00
New Revision: c68baa73eb437556cd8abe40902182a6034930ac

URL: https://github.com/llvm/llvm-project/commit/c68baa73eb437556cd8abe40902182a6034930ac
DIFF: https://github.com/llvm/llvm-project/commit/c68baa73eb437556cd8abe40902182a6034930ac.diff

LOG: [clang] Fix incorrect constant folding of `if consteval`

Fixes https://github.com/llvm/llvm-project/issues/55638.

`if consteval` was evaluated incorrectly when in a
non-constant context that could be constant-folded.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D130437

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/ExprConstant.cpp
    clang/test/CodeGenCXX/cxx2b-consteval-if.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ac6c5bb543121..af64152666757 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -194,6 +194,8 @@ Bug Fixes
   move assignment operator. Fixes `Issue 56456 <https://github.com/llvm/llvm-project/issues/56456>`_.
 - Fixed a crash when a variable with a bool enum type that has no definition
   used in comparison operators. Fixes `Issue 56560 <https://github.com/llvm/llvm-project/issues/56560>`_.
+- Fix that ``if consteval`` could evaluate to ``true`` at runtime because it was incorrectly
+  constant folded. Fixes `Issue 55638 <https://github.com/llvm/llvm-project/issues/55638>`_.
 
 Improvements to Clang's diagnostics
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6ffb65d8e71d3..9d92c848ccb84 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -5266,10 +5266,14 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
       }
     }
     bool Cond;
-    if (IS->isConsteval())
+    if (IS->isConsteval()) {
       Cond = IS->isNonNegatedConsteval();
-    else if (!EvaluateCond(Info, IS->getConditionVariable(), IS->getCond(),
-                           Cond))
+      // If we are not in a constant context, if consteval should not evaluate
+      // to true.
+      if (!Info.InConstantContext)
+        Cond = !Cond;
+    } else if (!EvaluateCond(Info, IS->getConditionVariable(), IS->getCond(),
+                             Cond))
       return ESR_Failed;
 
     if (const Stmt *SubStmt = Cond ? IS->getThen() : IS->getElse()) {

diff  --git a/clang/test/CodeGenCXX/cxx2b-consteval-if.cpp b/clang/test/CodeGenCXX/cxx2b-consteval-if.cpp
index 2e38ce0e63639..a69a2271f661b 100644
--- a/clang/test/CodeGenCXX/cxx2b-consteval-if.cpp
+++ b/clang/test/CodeGenCXX/cxx2b-consteval-if.cpp
@@ -26,3 +26,30 @@ constexpr void f() {
 void g() {
   f();
 }
+
+namespace GH55638 {
+
+constexpr bool is_constant_evaluated() noexcept {
+  if consteval { return true; } else { return false; }
+}
+
+constexpr int compiletime(int) {
+   return 2;
+}
+
+constexpr int runtime(int) {
+   return 1;
+}
+
+constexpr int test(int x) {
+  if(is_constant_evaluated())
+    return compiletime(x);  // CHECK-NOT: call {{.*}}compiletime
+   return runtime(x);  // CHECK: call {{.*}}runtime
+}
+
+int f(int x) {
+  x = test(x);
+  return x;
+}
+
+}


        


More information about the cfe-commits mailing list