https://github.com/efriedma-quic updated 
https://github.com/llvm/llvm-project/pull/149227

>From 9ce04c82fdeb47e337ba47655fd8f626b57313c2 Mon Sep 17 00:00:00 2001
From: Eli Friedman <efrie...@quicinc.com>
Date: Wed, 16 Jul 2025 16:58:03 -0700
Subject: [PATCH 1/2] [clang] Fix potential constant expression checking with
 constexpr-unknown.

071765749a70b22fb62f2efc07a3f242ff5b4c52 improved constexpr-unkown
diagnostics, but potential constant expression checking broke in the
process: we produce diagnostics in more cases.  Supress the diagnostics
as appropriate.

This fix affects -Winvalid-constexpr and the enable_if attribute.  (The
-Winvalid-constexpr diagnostic isn't really important right now, but it
will become important if we allow constexpr-unknown with pre-C++23
standards.)

Fixes #149041.  Fixes #149188.
---
 clang/lib/AST/ExprConstant.cpp                | 11 +++++----
 .../SemaCXX/constant-expression-p2280r4.cpp   | 24 +++++++++++++++++++
 .../test/SemaCXX/constexpr-never-constant.cpp |  5 ++++
 3 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 767cc4c3b19eb..8797eaddd0e18 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4450,7 +4450,8 @@ static CompleteObject findCompleteObject(EvalInfo &Info, 
const Expr *E,
         }
       } else if (!IsAccess) {
         return CompleteObject(LVal.getLValueBase(), nullptr, BaseType);
-      } else if (IsConstant && Info.checkingPotentialConstantExpression() &&
+      } else if ((IsConstant || BaseType->isReferenceType()) &&
+                 Info.checkingPotentialConstantExpression() &&
                  BaseType->isLiteralType(Info.Ctx) && !VD->hasDefinition()) {
         // This variable might end up being constexpr. Don't diagnose it yet.
       } else if (IsConstant) {
@@ -4491,9 +4492,11 @@ static CompleteObject findCompleteObject(EvalInfo &Info, 
const Expr *E,
     // a null BaseVal. Any constexpr-unknown variable seen here is an error:
     // we can't access a constexpr-unknown object.
     if (AK != clang::AK_Dereference && !BaseVal) {
-      Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
-          << AK << VD;
-      Info.Note(VD->getLocation(), diag::note_declared_at);
+      if (!Info.checkingPotentialConstantExpression()) {
+        Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
+            << AK << VD;
+        Info.Note(VD->getLocation(), diag::note_declared_at);
+      }
       return CompleteObject();
     }
   } else if (DynamicAllocLValue DA = LVal.Base.dyn_cast<DynamicAllocLValue>()) 
{
diff --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp 
b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
index 03fea91169787..979d29476c119 100644
--- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp
+++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
@@ -357,3 +357,27 @@ namespace pointer_comparisons {
   static_assert(!f4()); // expected-error {{static assertion expression is not 
an integral constant expression}} \
                         // expected-note {{in call to 'f4()'}}
 }
+
+namespace enable_if_1 {
+  template <__SIZE_TYPE__ N>
+  constexpr void foo(const char (&Str)[N])
+  __attribute((enable_if(__builtin_strlen(Str), ""))) {}
+
+  void x() {
+      foo("1234");
+  }
+}
+
+namespace enable_if_2 {
+  constexpr const char (&f())[];
+  extern const char (&Str)[];
+  constexpr int foo()
+  __attribute((enable_if(__builtin_strlen(Str), "")))
+  {return __builtin_strlen(Str);}
+
+  constexpr const char (&f())[] {return "a";}
+  constexpr const char (&Str)[] = f();
+  void x() {
+      constexpr int x = foo();
+  }
+}
diff --git a/clang/test/SemaCXX/constexpr-never-constant.cpp 
b/clang/test/SemaCXX/constexpr-never-constant.cpp
index 307810ee263dd..ca6dff22275d5 100644
--- a/clang/test/SemaCXX/constexpr-never-constant.cpp
+++ b/clang/test/SemaCXX/constexpr-never-constant.cpp
@@ -24,3 +24,8 @@ constexpr void other_func() {
 
   throw 12;
 }
+
+// Make sure these don't trigger the diagnostic.
+extern const bool& b;
+constexpr bool fun1() { return b; }
+constexpr bool fun2(const bool& b) { return b; }

>From 05e1a7d4e97c7bfc1ac00f0fdeaa0ef78473c2ae Mon Sep 17 00:00:00 2001
From: Eli Friedman <efrie...@quicinc.com>
Date: Thu, 17 Jul 2025 11:47:51 -0700
Subject: [PATCH 2/2] Note bug numbers in tests.

---
 clang/test/SemaCXX/constant-expression-p2280r4.cpp |  2 ++
 clang/test/SemaCXX/constexpr-never-constant.cpp    | 10 ++++++----
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp 
b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
index 979d29476c119..16f5f823d26c1 100644
--- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp
+++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
@@ -358,6 +358,7 @@ namespace pointer_comparisons {
                         // expected-note {{in call to 'f4()'}}
 }
 
+namespace GH149188 {
 namespace enable_if_1 {
   template <__SIZE_TYPE__ N>
   constexpr void foo(const char (&Str)[N])
@@ -381,3 +382,4 @@ namespace enable_if_2 {
       constexpr int x = foo();
   }
 }
+}
diff --git a/clang/test/SemaCXX/constexpr-never-constant.cpp 
b/clang/test/SemaCXX/constexpr-never-constant.cpp
index ca6dff22275d5..5756bb647ce88 100644
--- a/clang/test/SemaCXX/constexpr-never-constant.cpp
+++ b/clang/test/SemaCXX/constexpr-never-constant.cpp
@@ -25,7 +25,9 @@ constexpr void other_func() {
   throw 12;
 }
 
-// Make sure these don't trigger the diagnostic.
-extern const bool& b;
-constexpr bool fun1() { return b; }
-constexpr bool fun2(const bool& b) { return b; }
+namespace GH149041 {
+  // Make sure these don't trigger the diagnostic.
+  extern const bool& b;
+  constexpr bool fun1() { return b; }
+  constexpr bool fun2(const bool& b) { return b; }
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to