https://github.com/mizvekov created 
https://github.com/llvm/llvm-project/pull/155965

…context

Fix an error in the logic meant to handle a redeclaration such as:
```C++
struct A {
  struct __attribute__((foo)) A *ptr;
};
```
In the declaration of ptr, we must introduce a new redeclaration of A in order 
for it to carry the new attribute. This is a redeclaration of the existing A, 
but it is only lexically contained in A, but still semantically belonging to 
the TU. This is the same deal as happens with friend declarations, and the 
logic used to handle that is reused here.

But this was going haywire with a class indirectly nested within a class of the 
same name.

The fix limits this logic to only apply when the tag use is just a simple 
reference.

Fixes #155936

>From 95ed2d03e8dad25d4872fdb21f1d56acf136e383 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <[email protected]>
Date: Thu, 28 Aug 2025 23:50:03 -0300
Subject: [PATCH] [clang] fix nested tags of the same name not being included
 in their context

Fix an error in the logic meant to handle a redeclaration such as:
```C++
struct A {
  struct __attribute__((foo)) A *ptr;
};
```
In the declaration of ptr, we must introduce a new redeclaration of A
in order for it to carry the new attribute. This is a redeclaration of
the existing A, but it is only lexically contained in A, but still
semantically belonging to the TU. This is the same deal as happens with
friend declarations, and the logic used to handle that is reused here.

But this was going haywire with a class indirectly nested within a class
of the same name.

The fix limits this logic to only apply when the tag use is just a simple
reference.

Fixes #155936
---
 clang/lib/Sema/SemaDecl.cpp      |  3 ++-
 clang/test/AST/ast-dump-decl.cpp | 15 +++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0afef106821d9..12bedae05f6f3 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -18050,7 +18050,8 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind 
TUK, SourceLocation KWLoc,
           }
         }
       } else if (auto *RD = dyn_cast<CXXRecordDecl>(PrevDecl);
-                 RD && RD->isInjectedClassName()) {
+                 TUK == TagUseKind::Reference && RD &&
+                 RD->isInjectedClassName()) {
         // If lookup found the injected class name, the previous declaration is
         // the class being injected into.
         PrevDecl = cast<TagDecl>(RD->getDeclContext());
diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp
index 849bfbee2ab21..afb507833d869 100644
--- a/clang/test/AST/ast-dump-decl.cpp
+++ b/clang/test/AST/ast-dump-decl.cpp
@@ -990,3 +990,18 @@ namespace TestInjectedClassName {
   // CHECK-NEXT:    `-RecordType [[TestInjectedClassName_RT]] 'A' injected
   // CHECK-NEXT:      `-CXXRecord [[TestInjectedClassName_RD]] 'A'
 } // namespace InjectedClassName
+
+namespace TestGH155936 {
+  struct Foo {
+    struct A {
+      struct Foo {};
+    };
+  };
+  // CHECK-LABEL: Dumping TestGH155936:
+  // CHECK: CXXRecordDecl 0x{{.+}} <{{.+}}> line:[[@LINE-6]]:10 struct Foo 
definition
+  // CHECK: CXXRecordDecl 0x{{.+}} <col:3, col:10> col:10 implicit struct Foo
+  // CHECK: CXXRecordDecl 0x{{.+}} <{{.+}}> line:[[@LINE-7]]:12 struct A 
definition
+  // CHECK: CXXRecordDecl 0x{{.+}} <col:5, col:12> col:12 implicit struct A
+  // CHECK: CXXRecordDecl 0x{{.+}} <line:[[@LINE-8]]:7, col:19> col:14 struct 
Foo definition
+  // CHECH: CXXRecordDecl 0x{{.+}} <col:9, col:16> col:16 implicit struct Foo
+} // namspace GH155936

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to