llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Matheus Izvekov (mizvekov) <details> <summary>Changes</summary> The declaration used to represent an injected class name should never be part of any redeclaration chain. This is a regression since Clang 22, and this will be backported, so no release notes. Fixes #<!-- -->202320 --- Full diff: https://github.com/llvm/llvm-project/pull/207301.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaDecl.cpp (+14-11) - (modified) clang/test/SemaCXX/injected-class-name-crash.cpp (+7) ``````````diff diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index f6d1d7a7877c7..813aebf263f97 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18447,16 +18447,6 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, Previous.resolveKind(); } } - } else if (auto *RD = dyn_cast<CXXRecordDecl>(PrevDecl); - 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()); - Previous.clear(); - Previous.addDecl(PrevDecl); - Previous.resolveKind(); - IsInjectedClassName = true; } } @@ -18488,6 +18478,18 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, if (TUK == TagUseKind::Reference || TUK == TagUseKind::Friend || isDeclInScope(DirectPrevDecl, SearchDC, S, SS.isNotEmpty() || isMemberSpecialization)) { + + if (auto *RD = dyn_cast<CXXRecordDecl>(PrevDecl); + RD && RD->isInjectedClassName()) { + // If lookup found the injected class name, the previous declaration + // is the class being injected into. + Previous.clear(); + PrevDecl = PrevTagDecl = cast<CXXRecordDecl>(RD->getDeclContext()); + Previous.addDecl(PrevDecl); + Previous.resolveKind(); + IsInjectedClassName = true; + } + // Make sure that this wasn't declared as an enum and now used as a // struct or something similar. if (!isAcceptableTagRedeclaration(PrevTagDecl, Kind, @@ -18688,7 +18690,8 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // Okay, we're going to make a redeclaration. If this is some kind // of reference, make sure we build the redeclaration in the same DC // as the original, and ignore the current access specifier. - if (TUK == TagUseKind::Friend || TUK == TagUseKind::Reference) { + if (TUK == TagUseKind::Friend || TUK == TagUseKind::Reference || + IsInjectedClassName) { SearchDC = PrevTagDecl->getDeclContext(); AS = AS_none; } diff --git a/clang/test/SemaCXX/injected-class-name-crash.cpp b/clang/test/SemaCXX/injected-class-name-crash.cpp index a044ba064b58e..141762fe41d93 100644 --- a/clang/test/SemaCXX/injected-class-name-crash.cpp +++ b/clang/test/SemaCXX/injected-class-name-crash.cpp @@ -9,3 +9,10 @@ struct X : public Foo<Bar { // expected-error {{unknown template name 'Foo'}} ex template <class T> X<T>::X() { } + +namespace GH202320 { + struct S { S f(); }; + struct S::S; + // expected-error@-1 {{forward declaration of struct cannot have a nested name specifier}} + S S::f() { return S(); } +} // namespace GH202320 `````````` </details> https://github.com/llvm/llvm-project/pull/207301 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
