[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