Skip to content

Commit 156ab4d

Browse files
authored
[Clang][Sema] set declaration invalid earlier to prevent crash in calculating record layout (#87173)
Try to fix #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@qq.com>
1 parent 823eb1a commit 156ab4d

File tree

5 files changed

+26
-0
lines changed

5 files changed

+26
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,8 @@ Bug Fixes to C++ Support
536536
Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), (#GH86398), and (#GH86399).
537537
- Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329).
538538
- Fix a crash in requires expression with templated base class member function. Fixes (#GH84020).
539+
- Fix a crash caused by defined struct in a type alias template when the structure
540+
has fields with dependent type. Fixes (#GH75221).
539541

540542
Bug Fixes to AST Handling
541543
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Sema/Scope.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ class Scope {
156156
/// This is the scope of an OpenACC Compute Construct, which restricts
157157
/// jumping into/out of it.
158158
OpenACCComputeConstructScope = 0x10000000,
159+
160+
/// This is a scope of type alias declaration.
161+
TypeAliasScope = 0x20000000,
159162
};
160163

161164
private:
@@ -580,6 +583,9 @@ class Scope {
580583
/// if/switch/while/for statement.
581584
bool isControlScope() const { return getFlags() & Scope::ControlScope; }
582585

586+
/// Determine whether this scope is a type alias scope.
587+
bool isTypeAliasScope() const { return getFlags() & Scope::TypeAliasScope; }
588+
583589
/// Returns if rhs has a higher scope depth than this.
584590
///
585591
/// The caller is responsible for calling this only if one of the two scopes

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,11 @@ Parser::DeclGroupPtrTy Parser::ParseUsingDeclaration(
799799
ProhibitAttributes(PrefixAttrs);
800800

801801
Decl *DeclFromDeclSpec = nullptr;
802+
Scope *CurScope = getCurScope();
803+
if (CurScope)
804+
CurScope->setFlags(Scope::ScopeFlags::TypeAliasScope |
805+
CurScope->getFlags());
806+
802807
Decl *AD = ParseAliasDeclarationAfterDeclarator(
803808
TemplateInfo, UsingLoc, D, DeclEnd, AS, Attrs, &DeclFromDeclSpec);
804809
return Actions.ConvertDeclToDeclGroup(AD, DeclFromDeclSpec);

clang/lib/Sema/SemaDecl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19529,6 +19529,13 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
1952919529
// Okay, we successfully defined 'Record'.
1953019530
if (Record) {
1953119531
bool Completed = false;
19532+
if (S) {
19533+
Scope *Parent = S->getParent();
19534+
if (Parent && Parent->isTypeAliasScope() &&
19535+
Parent->isTemplateParamScope())
19536+
Record->setInvalidDecl();
19537+
}
19538+
1953219539
if (CXXRecord) {
1953319540
if (!CXXRecord->isInvalidDecl()) {
1953419541
// Set access bits correctly on the directly-declared conversions.

clang/test/SemaCXX/PR75221.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %clang_cc1 -verify -std=c++11 -fsyntax-only %s
2+
3+
template <class T> using foo = struct foo { // expected-error {{'foo' cannot be defined in a type alias template}}
4+
T size = 0;
5+
};
6+
foo a;

0 commit comments

Comments
 (0)