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