Skip to content

[Clang][Sema] set declaration invalid earlier to prevent crash in calculating record layout #87173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;