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

Qizhi Hu via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 8 01:59:12 PDT 2024


https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/87173

>From 599991f3dc24417eb0b74f029b85b47519b6d152 Mon Sep 17 00:00:00 2001
From: huqizhi <huqizhi at feysh.com>
Date: Sun, 31 Mar 2024 09:38:05 +0800
Subject: [PATCH] [Clang][Sema] set declaration invalid earlier to prevent
 crash in calculating record layout

---
 clang/docs/ReleaseNotes.rst      | 2 ++
 clang/include/clang/Sema/Scope.h | 6 ++++++
 clang/lib/Parse/ParseDeclCXX.cpp | 5 +++++
 clang/lib/Sema/SemaDecl.cpp      | 7 +++++++
 clang/test/SemaCXX/PR75221.cpp   | 6 ++++++
 5 files changed, 26 insertions(+)
 create mode 100644 clang/test/SemaCXX/PR75221.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 28e8ddb3c41c3e..1c541af8657dbb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -504,6 +504,8 @@ Bug Fixes to C++ Support
 - Fix crash when inheriting from a cv-qualified type. Fixes:
   (`#35603 <https://github.com/llvm/llvm-project/issues/35603>`_)
 - Fix a crash when the using enum declaration uses an anonymous enumeration. Fixes (#GH86790).
+- 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 861a25dc5103c1..270d09f8c9580c 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 c790dab72dd721..b47824ef3d8498 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -19622,6 +19622,13 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
   // Okay, we successfully defined 'Record'.
   if (Record) {
     bool Completed = false;
+    if (S && S->getParent()) {
+      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