[clang] [Sema] Improve diagnostic for volatile static data member initializer… (PR #185021)

via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 6 07:15:54 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Lnk (Lnkqwq)

<details>
<summary>Changes</summary>

… in C++98

Ensure that when a const volatile integer static data member is initialized in C++98 mode, we perform constant expression evaluation and emit the same 'read of volatile-qualified type' note that we do in other contexts (like bit-field widths). This makes the diagnostic behavior consistent across different uses of volatile variables in constant expressions.

Fixes #<!-- -->88603

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


1 Files Affected:

- (modified) clang/lib/Sema/SemaDecl.cpp (+19-4) 


``````````diff
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 405832a446e10..d51a6c9507aec 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14230,11 +14230,26 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
 
     // We allow integer constant expressions in all cases.
     } else if (DclT->isIntegralOrEnumerationType()) {
-      if (getLangOpts().CPlusPlus11 && DclT.isVolatileQualified())
-        // In C++11, a non-constexpr const static data member with an
-        // in-class initializer cannot be volatile.
-        Diag(VDecl->getLocation(), diag::err_in_class_initializer_volatile);
+  if (getLangOpts().CPlusPlus11 && DclT.isVolatileQualified())
+    // In C++11, a non-constexpr const static data member with an
+    // in-class initializer cannot be volatile.
+    Diag(VDecl->getLocation(), diag::err_in_class_initializer_volatile);
+
+  // 新增:检查是否真的是常量表达式(适用于所有语言版本)
+  if (!Init->isValueDependent()) {
+    Expr::EvalResult EvalResult;
+    if (!Init->EvaluateAsConstantExpr(EvalResult, Context)) {
+      // 如果不是常量表达式,报错
+      Diag(Init->getExprLoc(), diag::err_in_class_initializer_non_constant)
+        << Init->getSourceRange();
+      VDecl->setInvalidDecl();
 
+      // 如果求值过程中有附注(比如 volatile 的提示),输出它们
+      if (EvalResult.Diag) {
+        Diag(EvalResult.Diag->first, EvalResult.Diag->second);
+      }
+    }
+  }
     // We allow foldable floating-point constants as an extension.
     } else if (DclT->isFloatingType()) { // also permits complex, which is ok
       // In C++98, this is a GNU extension. In C++11, it is not, but we support

``````````

</details>


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


More information about the cfe-commits mailing list