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'}}
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to