[clang] 156ab4d - [Clang][Sema] set declaration invalid earlier to prevent crash in calculating record layout (#87173)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 17 17:52:28 PDT 2024
Author: Qizhi Hu
Date: 2024-04-18T08:52:25+08:00
New Revision: 156ab4d4fb06be93b0cfce675e4cf86d330d879c
URL: https://github.com/llvm/llvm-project/commit/156ab4d4fb06be93b0cfce675e4cf86d330d879c
DIFF: https://github.com/llvm/llvm-project/commit/156ab4d4fb06be93b0cfce675e4cf86d330d879c.diff
LOG: [Clang][Sema] set declaration invalid earlier to prevent crash in calculating record layout (#87173)
Try to fix https://github.com/llvm/llvm-project/issues/75221
This crash caused by calculating record layout which contains a field
declaration with dependent type. Make it invalid before it is a complete
definition to prevent this crash. Define a new scope type to record this
type alias and set the record declaration invalid when it is defined in
a type alias template.
Co-authored-by: huqizhi <836744285 at qq.com>
Added:
clang/test/SemaCXX/PR75221.cpp
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Sema/Scope.h
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Sema/SemaDecl.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c19ad9fba58f37..6c51c2d1f483ce 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -536,6 +536,8 @@ Bug Fixes to C++ Support
Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), (#GH86398), and (#GH86399).
- Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329).
- Fix a crash in requires expression with templated base class member function. Fixes (#GH84020).
+- Fix a crash caused by defined struct in a type alias template when the structure
+ has fields with dependent type. Fixes (#GH75221).
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index 099c2739e8603a..1752a25111a775 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -156,6 +156,9 @@ class Scope {
/// This is the scope of an OpenACC Compute Construct, which restricts
/// jumping into/out of it.
OpenACCComputeConstructScope = 0x10000000,
+
+ /// This is a scope of type alias declaration.
+ TypeAliasScope = 0x20000000,
};
private:
@@ -580,6 +583,9 @@ class Scope {
/// if/switch/while/for statement.
bool isControlScope() const { return getFlags() & Scope::ControlScope; }
+ /// Determine whether this scope is a type alias scope.
+ bool isTypeAliasScope() const { return getFlags() & Scope::TypeAliasScope; }
+
/// Returns if rhs has a higher scope depth than this.
///
/// The caller is responsible for calling this only if one of the two scopes
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 51fd64b2d01aa7..8e0e8682482933 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -799,6 +799,11 @@ Parser::DeclGroupPtrTy Parser::ParseUsingDeclaration(
ProhibitAttributes(PrefixAttrs);
Decl *DeclFromDeclSpec = nullptr;
+ Scope *CurScope = getCurScope();
+ if (CurScope)
+ CurScope->setFlags(Scope::ScopeFlags::TypeAliasScope |
+ CurScope->getFlags());
+
Decl *AD = ParseAliasDeclarationAfterDeclarator(
TemplateInfo, UsingLoc, D, DeclEnd, AS, Attrs, &DeclFromDeclSpec);
return Actions.ConvertDeclToDeclGroup(AD, DeclFromDeclSpec);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1bde99d6fce740..356abe09a5ca62 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -19529,6 +19529,13 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
// Okay, we successfully defined 'Record'.
if (Record) {
bool Completed = false;
+ if (S) {
+ Scope *Parent = S->getParent();
+ if (Parent && Parent->isTypeAliasScope() &&
+ Parent->isTemplateParamScope())
+ Record->setInvalidDecl();
+ }
+
if (CXXRecord) {
if (!CXXRecord->isInvalidDecl()) {
// Set access bits correctly on the directly-declared conversions.
diff --git a/clang/test/SemaCXX/PR75221.cpp b/clang/test/SemaCXX/PR75221.cpp
new file mode 100644
index 00000000000000..b342e347c5606a
--- /dev/null
+++ b/clang/test/SemaCXX/PR75221.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -verify -std=c++11 -fsyntax-only %s
+
+template <class T> using foo = struct foo { // expected-error {{'foo' cannot be defined in a type alias template}}
+ T size = 0;
+};
+foo a;
More information about the cfe-commits
mailing list