[clang] e8b509f - [clang] use decl itself in static assert failed boolean condition printer (#203736)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 3 00:25:12 PDT 2026
Author: Fan Mo
Date: 2026-07-03T09:25:07+02:00
New Revision: e8b509f10bf34082b6fb35eb35e34f77ea583bef
URL: https://github.com/llvm/llvm-project/commit/e8b509f10bf34082b6fb35eb35e34f77ea583bef
DIFF: https://github.com/llvm/llvm-project/commit/e8b509f10bf34082b6fb35eb35e34f77ea583bef.diff
LOG: [clang] use decl itself in static assert failed boolean condition printer (#203736)
fixes #203701
`getName()` assumes the decl used in the static asserts has a simple
identifier name, but in some cases like `operator int` don't — they
fails the assertion `Name.isIdentifier() && "Name is not a simple
identifier"` when the `static_assert` failure diagnostic tries to print
the boolean expression.
Switching to getDeclName() handles these special names properly.
Reproducer:
```c++
struct S {
constexpr S(auto) {}
constexpr operator int() const { return 0; }
};
constexpr auto a = [](this S) { return 1; };
static_assert((&decltype(a)::operator())(1) == 42);
```
---
One thing I'm not sure about: the print helper that walks the boolean
expression lives in `SemaTemplate.cpp` (inside
`printTemplateArgumentList` / the DiagRecursiveConstraintEval visitor
area). Is there a historical reason for it being there rather than
somewhere more general like `SemaOverload.cpp` or a shared diagnostic
utility? Happy to move it if that makes more sense.
---
AI used for generating & fixing unit test
Added:
clang/test/SemaCXX/GH203701.cpp
Modified:
clang/lib/Sema/SemaTemplate.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 9fe6a2ae209e8..96c3544847849 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3650,7 +3650,7 @@ class FailedBooleanConditionPrinterHelper : public PrinterHelper {
DR->getQualifier().print(OS, Policy, true);
// Then print the decl itself.
const ValueDecl *VD = DR->getDecl();
- OS << VD->getName();
+ OS << *VD;
if (const auto *IV = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
// This is a template variable, print the expanded template arguments.
printTemplateArgumentList(
diff --git a/clang/test/SemaCXX/GH203701.cpp b/clang/test/SemaCXX/GH203701.cpp
new file mode 100644
index 0000000000000..f583865de9ac4
--- /dev/null
+++ b/clang/test/SemaCXX/GH203701.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify %s
+
+namespace GH203701 {
+ struct S {
+ constexpr S(auto) {}
+ constexpr operator int() const { return 0; }
+ };
+
+ constexpr auto a = [](this S) { return 1; };
+
+ static_assert((&decltype(a)::operator())(1) == 42, ""); // expected-error-re {{static assertion failed due to requirement '(&const GH203701::(lambda at {{.*}})::operator())(1) == 42'{{.*}}}} \
+ // expected-note {{expression evaluates to '1 == 42'}}
+ static_assert((&S::operator int) == nullptr, ""); // expected-error {{static assertion failed due to requirement '(&GH203701::S::operator int) == nullptr'}}
+}
More information about the cfe-commits
mailing list