Skip to content

Commit

Permalink
[Clang][Sema] set declaration invalid earlier to prevent crash in cal…
Browse files Browse the repository at this point in the history
…culating 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>
  • Loading branch information
jcsxky committed Apr 18, 2024
1 parent 823eb1a commit 156ab4d
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 0 deletions.
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Sema/Scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions clang/test/SemaCXX/PR75221.cpp
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit 156ab4d

Please sign in to comment.