[clang] [Clang] Fixed a crash when instantiating an invalid out-of-line static data member definition in a local class (PR #196772)
via cfe-commits
cfe-commits at lists.llvm.org
Sat May 9 20:05:59 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: TPPPP (TPPPP72)
<details>
<summary>Changes</summary>
Add check before the function that cause assertion.
Fix #<!-- -->176152, Fix #<!-- -->195416
---
Full diff: https://github.com/llvm/llvm-project/pull/196772.diff
4 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+1-1)
- (modified) clang/lib/Sema/SemaDecl.cpp (+1)
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+8)
- (added) clang/test/SemaTemplate/gh176152.cpp (+13)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c17143e3c0398..06adba419b192 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -581,7 +581,7 @@ Bug Fixes to C++ Support
- Fixed a crash on ``typeid`` of incomplete local types during template instantiation. (#GH63242), (#GH176397)
- Fixed a crash when an immediate-invoked ``consteval`` lambda is used as an invalid initializer. (#GH185270)
- Fixed an assertion failure when using a global destructor with a target with a non-default program address space. (#GH186484)
-
+- Fixed a crash when instantiating an invalid out-of-line static data member definition in a local class. (#GH176152)
- Inherited constructors in ``dllexport`` classes are now exported for ABI-compatible cases, matching
MSVC behavior. Constructors with variadic arguments or callee-cleanup parameters are not yet supported
and produce a warning. (#GH162640)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a9a4cb89d115f..d9ba3b30dcca9 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7948,6 +7948,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
Diag(D.getIdentifierLoc(),
diag::err_static_data_member_not_allowed_in_local_class)
<< Name << RD->getDeclName() << RD->getTagKind();
+ Invalid = true;
} else if (AnonStruct) {
// C++ [class.static.data]p4: Unnamed classes and classes contained
// directly or indirectly within unnamed classes shall not contain
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index c9bc613a7c4ea..2a4f459dbe40f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1799,6 +1799,14 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D,
if (SemaRef.getLangOpts().OpenCL)
SemaRef.deduceOpenCLAddressSpace(Var);
+ if (D->getQualifierLoc()) {
+ if (D->getLexicalDeclContext()->isDependentContext() &&
+ DC->isFunctionOrMethod()) {
+ Var->setInvalidDecl();
+ return nullptr;
+ }
+ }
+
// Substitute the nested name specifier, if any.
if (SubstQualifier(D, Var))
return nullptr;
diff --git a/clang/test/SemaTemplate/gh176152.cpp b/clang/test/SemaTemplate/gh176152.cpp
new file mode 100644
index 0000000000000..feae5d0f0a825
--- /dev/null
+++ b/clang/test/SemaTemplate/gh176152.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <class T> int f(T) {
+ struct A {
+ static int B;
+ // expected-error at -1 {{static data member 'staticField' not allowed in local struct 'MyClass'}}
+ };
+ int A::B;
+ int A::B = 1;
+ return 0;
+}
+
+int x = f(0);
\ No newline at end of file
``````````
</details>
https://github.com/llvm/llvm-project/pull/196772
More information about the cfe-commits
mailing list