[clang] [clang] fix nested tags of the same name not being included in their … (PR #155965)

via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 28 20:09:33 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Matheus Izvekov (mizvekov)

<details>
<summary>Changes</summary>

…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

---
Full diff: https://github.com/llvm/llvm-project/pull/155965.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaDecl.cpp (+2-1) 
- (modified) clang/test/AST/ast-dump-decl.cpp (+15) 


``````````diff
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

``````````

</details>


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


More information about the cfe-commits mailing list