diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index ecf8754143a49..92c47be67339e 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7056,11 +7056,16 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) { if (!RD->hasConstexprDestructor()) return false; + QualType CanUnqualT = T.getCanonicalType().getUnqualifiedType(); for (const CXXBaseSpecifier &B : RD->bases()) - if (!Check(B.getType(), Check)) + if (B.getType().getCanonicalType().getUnqualifiedType() != + CanUnqualT && + !Check(B.getType(), Check)) return false; for (const FieldDecl *FD : RD->fields()) - if (!Check(FD->getType(), Check)) + if (FD->getType().getCanonicalType().getUnqualifiedType() != + CanUnqualT && + !Check(FD->getType(), Check)) return false; return true; }; diff --git a/clang/test/SemaCXX/gh102293.cpp b/clang/test/SemaCXX/gh102293.cpp index 30629fc03bf6a..d4218cc13dcec 100644 --- a/clang/test/SemaCXX/gh102293.cpp +++ b/clang/test/SemaCXX/gh102293.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s -// expected-no-diagnostics template static void destroy() { T t; @@ -20,3 +19,29 @@ struct S : HasVT { HasD<> v; }; +// Ensure we don't get infinite recursion from the check, however. See GH104802 +namespace GH104802 { +class foo { // expected-note {{definition of 'GH104802::foo' is not complete until the closing '}'}} + foo a; // expected-error {{field has incomplete type 'foo'}} + + virtual int c(); +}; + +class bar { // expected-note {{definition of 'GH104802::bar' is not complete until the closing '}'}} + const bar a; // expected-error {{field has incomplete type 'const bar'}} + + virtual int c(); +}; + +class baz { // expected-note {{definition of 'GH104802::baz' is not complete until the closing '}'}} + typedef class baz blech; + blech a; // expected-error {{field has incomplete type 'blech' (aka 'GH104802::baz')}} + + virtual int c(); +}; + +class quux : quux { // expected-error {{base class has incomplete type}} \ + expected-note {{definition of 'GH104802::quux' is not complete until the closing '}'}} + virtual int c(); +}; +}