[clang] [Clang] Fix misleading diagnostic for pointer const type static data member (PR #223596)

via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 14 21:13:33 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Alexsander Borges Damaceno (AlexsanderDamaceno)

<details>
<summary>Changes</summary>

For a static data member of pointer-to-const type (e.g. 'const char *'), Clang emits:

` error: non-const static data member must be initialized out of line
`

This message is misleading. The most appropriate diagnostic here would be:

`error: in-class initializer for static data member of type '....' requires 'constexpr' specifier`

GCC reports similar to the above message sugesting add 'constexpr'

The constexpr expression diagnostic was never reached because the preceding
check only verified `!DclT.isConstQualified(),` which excludes this pointer
case.

For `const char *`, the const qualifier binds to the pointee (char), not
to the pointer itself. Therefore, the pointer's own type is not
const-qualified, causing the "non-const" branch to fire first before the
constexpr-related diagnostics can be reached.

This patch adds  check to const case, so a pointer whose pointee is const no longer takes the `non-const`  diag branch , letting it fall through to the existing constexpr-related diagnostics instead.

---
Full diff: https://github.com/llvm/llvm-project/pull/223596.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaDecl.cpp (+3-1) 
- (modified) clang/test/CXX/class/class.static/class.static.data/p3.cpp (+3) 


``````````diff
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 7e1b23c971a9c..140bb22f2a4e2 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14333,7 +14333,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
     } else if (VDecl->isConstexpr()) {
 
     // Require constness.
-    } else if (!DclT.isConstQualified()) {
+    } else if (!DclT.isConstQualified() &&
+               !(DclT->isPointerType() &&
+                 DclT->getPointeeType().isConstQualified())) {
       Diag(VDecl->getLocation(), diag::err_in_class_initializer_non_const)
         << Init->getSourceRange();
       VDecl->setInvalidDecl();
diff --git a/clang/test/CXX/class/class.static/class.static.data/p3.cpp b/clang/test/CXX/class/class.static/class.static.data/p3.cpp
index 5640bc30ad4c7..81844d90d6516 100644
--- a/clang/test/CXX/class/class.static/class.static.data/p3.cpp
+++ b/clang/test/CXX/class/class.static/class.static.data/p3.cpp
@@ -18,6 +18,9 @@ struct S {
   static char *const g = 0; // expected-error {{requires 'constexpr' specifier}}
   static const NonLit h = NonLit(); // expected-error {{must be initialized out of line}}
 
+  static const char *aaa = "aaa"; // expected-error {{requires 'constexpr' specifier}}
+  static int *i2 = 0; // expected-error {{non-const static data member must be initialized out of line}}
+
   static inline int i; // expected-note {{previous}} expected-warning 0-1{{extension}}
   static inline int j; // expected-note {{previous}} expected-warning 0-1{{extension}}
   static constexpr int k = 0;

``````````

</details>


https://github.com/llvm/llvm-project/pull/223596


More information about the cfe-commits mailing list