Skip to content

Commit ac23f74

Browse files
authored
[clang] fix nested tags of the same name not being included in their context (#155965)
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, 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. Since this regression was never released, there are no release notes. Fixes #155936
1 parent 88d0751 commit ac23f74

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18050,7 +18050,8 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
1805018050
}
1805118051
}
1805218052
} else if (auto *RD = dyn_cast<CXXRecordDecl>(PrevDecl);
18053-
RD && RD->isInjectedClassName()) {
18053+
TUK == TagUseKind::Reference && RD &&
18054+
RD->isInjectedClassName()) {
1805418055
// If lookup found the injected class name, the previous declaration is
1805518056
// the class being injected into.
1805618057
PrevDecl = cast<TagDecl>(RD->getDeclContext());

clang/test/AST/ast-dump-decl.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,3 +990,18 @@ namespace TestInjectedClassName {
990990
// CHECK-NEXT: `-RecordType [[TestInjectedClassName_RT]] 'A' injected
991991
// CHECK-NEXT: `-CXXRecord [[TestInjectedClassName_RD]] 'A'
992992
} // namespace InjectedClassName
993+
994+
namespace TestGH155936 {
995+
struct Foo {
996+
struct A {
997+
struct Foo {};
998+
};
999+
};
1000+
// CHECK-LABEL: Dumping TestGH155936:
1001+
// CHECK: CXXRecordDecl 0x{{.+}} <{{.+}}> line:[[@LINE-6]]:10 struct Foo definition
1002+
// CHECK: CXXRecordDecl 0x{{.+}} <col:3, col:10> col:10 implicit struct Foo
1003+
// CHECK: CXXRecordDecl 0x{{.+}} <{{.+}}> line:[[@LINE-7]]:12 struct A definition
1004+
// CHECK: CXXRecordDecl 0x{{.+}} <col:5, col:12> col:12 implicit struct A
1005+
// CHECK: CXXRecordDecl 0x{{.+}} <line:[[@LINE-8]]:7, col:19> col:14 struct Foo definition
1006+
// CHECH: CXXRecordDecl 0x{{.+}} <col:9, col:16> col:16 implicit struct Foo
1007+
} // namspace GH155936

0 commit comments

Comments
 (0)