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
