diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11514,16 +11514,21 @@ if (CXXConstructorDecl *Constructor = dyn_cast(NewFD)) { CheckConstructor(Constructor); } else if (CXXDestructorDecl *Destructor = - dyn_cast(NewFD)) { - CXXRecordDecl *Record = Destructor->getParent(); - QualType ClassType = Context.getTypeDeclType(Record); - - DeclarationName Name = Context.DeclarationNames.getCXXDestructorName( - Context.getCanonicalType(ClassType)); - if (NewFD->getDeclName() != Name) { - Diag(NewFD->getLocation(), diag::err_destructor_name); - NewFD->setInvalidDecl(); - return Redeclaration; + dyn_cast(NewFD)) { + // FIXME: We still don't diagnose on this case + // template + // struct A { friend T::S::~V(); }; + if (NewFD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None || + !NewFD->isDependentContext()) { + QualType ClassType = Destructor->getThisObjectType(); + + DeclarationName Name = Context.DeclarationNames.getCXXDestructorName( + Context.getCanonicalType(ClassType)); + if (NewFD->getDeclName() != Name) { + Diag(NewFD->getLocation(), diag::err_destructor_name); + NewFD->setInvalidDecl(); + return Redeclaration; + } } } else if (auto *Guide = dyn_cast(NewFD)) { if (auto *TD = Guide->getDescribedFunctionTemplate()) diff --git a/clang/test/SemaCXX/member-class-11.cpp b/clang/test/SemaCXX/member-class-11.cpp --- a/clang/test/SemaCXX/member-class-11.cpp +++ b/clang/test/SemaCXX/member-class-11.cpp @@ -26,4 +26,35 @@ ~B(); // expected-error {{expected the class name after '~' to name the enclosing class}} }; +template +struct D { + friend T::S::~S(); +private: + static constexpr int secret = 42; +}; + +// FIXME: We should diagnose here. +template +struct E { + friend T::S::~V(); +}; + +struct Q { + struct S { ~S(); }; +}; + +Q::S::~S() { + void foo(int); + foo(D::secret); +} + +struct X { + ~X(); +}; +struct Y; + +struct Z { + friend X::~Y(); // expected-error {{expected the class name after '~' to name the enclosing class}} +}; + }