Skip to content

Commit 1214b5d

Browse files
AaronBallmanllvmbot
authored andcommitted
[C++23] Fix infinite recursion (Clang 19.x regression) (#104829)
d469794 was fixing an issue with triggering vtable instantiations, but it accidentally introduced infinite recursion when the type to be checked is the same as the type used in a base specifier or field declaration. Fixes #104802 (cherry picked from commit 435cb0d)
1 parent 6e30268 commit 1214b5d

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7056,11 +7056,16 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
70567056
if (!RD->hasConstexprDestructor())
70577057
return false;
70587058

7059+
QualType CanUnqualT = T.getCanonicalType().getUnqualifiedType();
70597060
for (const CXXBaseSpecifier &B : RD->bases())
7060-
if (!Check(B.getType(), Check))
7061+
if (B.getType().getCanonicalType().getUnqualifiedType() !=
7062+
CanUnqualT &&
7063+
!Check(B.getType(), Check))
70617064
return false;
70627065
for (const FieldDecl *FD : RD->fields())
7063-
if (!Check(FD->getType(), Check))
7066+
if (FD->getType().getCanonicalType().getUnqualifiedType() !=
7067+
CanUnqualT &&
7068+
!Check(FD->getType(), Check))
70647069
return false;
70657070
return true;
70667071
};

clang/test/SemaCXX/gh102293.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
2-
// expected-no-diagnostics
32

43
template <typename T> static void destroy() {
54
T t;
@@ -20,3 +19,29 @@ struct S : HasVT {
2019
HasD<> v;
2120
};
2221

22+
// Ensure we don't get infinite recursion from the check, however. See GH104802
23+
namespace GH104802 {
24+
class foo { // expected-note {{definition of 'GH104802::foo' is not complete until the closing '}'}}
25+
foo a; // expected-error {{field has incomplete type 'foo'}}
26+
27+
virtual int c();
28+
};
29+
30+
class bar { // expected-note {{definition of 'GH104802::bar' is not complete until the closing '}'}}
31+
const bar a; // expected-error {{field has incomplete type 'const bar'}}
32+
33+
virtual int c();
34+
};
35+
36+
class baz { // expected-note {{definition of 'GH104802::baz' is not complete until the closing '}'}}
37+
typedef class baz blech;
38+
blech a; // expected-error {{field has incomplete type 'blech' (aka 'GH104802::baz')}}
39+
40+
virtual int c();
41+
};
42+
43+
class quux : quux { // expected-error {{base class has incomplete type}} \
44+
expected-note {{definition of 'GH104802::quux' is not complete until the closing '}'}}
45+
virtual int c();
46+
};
47+
}

0 commit comments

Comments
 (0)