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

… 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

>From 4afa64106976ce9faae41bf096c0932feef26d30 Mon Sep 17 00:00:00 2001
From: Lnkqwq <[email protected]>
Date: Fri, 6 Mar 2026 23:08:14 +0800
Subject: [PATCH] [Sema] Improve diagnostic for volatile static data member
 initializer 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
---
 clang/lib/Sema/SemaDecl.cpp | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

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

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

Reply via email to