[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