Skip to content

Commit b5211f3

Browse files
Backl1ghttomtor
authored andcommitted
[clang] fix infinite recursion (llvm#143244)
fix llvm#141789 The direct cause of infinite recursion is that `T` is changing from `struct X` and `S<X>` infinitely, this pr add a check that if `T` visited before then return false directly. ```plaintext /home/backlight/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp:7196] FD->getType().getAsString()=struct X, T.getAsString()=S<X>, FD->getType().getCanonicalType().getUnqualifiedType().getAsString()=struct X, CanUnqualT.getAsString()=struct S<struct X>, /home/backlight/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp:7196] FD->getType().getAsString()=S<X>, T.getAsString()=struct X, FD->getType().getCanonicalType().getUnqualifiedType().getAsString()=struct S<struct X>, CanUnqualT.getAsString()=struct X, ``` llvm#104829 fix similar infinite recursion, but I think it is no longer needed so I kind of revert it.
1 parent 455b4f2 commit b5211f3

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,7 @@ Bug Fixes in This Version
703703
the second clause of a C-style ``for`` loop. (#GH139818)
704704
- Fixed a bug with constexpr evaluation for structs containing unions in case of C++ modules. (#GH143168)
705705
- Fixed incorrect token location when emitting diagnostics for tokens expanded from macros. (#GH143216)
706+
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
706707

707708
Bug Fixes to Compiler Builtins
708709
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7159,7 +7159,10 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
71597159
// "effectively constexpr" for better compatibility.
71607160
// See https://github.com/llvm/llvm-project/issues/102293 for more info.
71617161
if (isa<CXXDestructorDecl>(M)) {
7162-
auto Check = [](QualType T, auto &&Check) -> bool {
7162+
llvm::SmallDenseSet<QualType> Visited;
7163+
auto Check = [&Visited](QualType T, auto &&Check) -> bool {
7164+
if (!Visited.insert(T->getCanonicalTypeUnqualified()).second)
7165+
return false;
71637166
const CXXRecordDecl *RD =
71647167
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
71657168
if (!RD || !RD->isCompleteDefinition())
@@ -7168,16 +7171,11 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
71687171
if (!RD->hasConstexprDestructor())
71697172
return false;
71707173

7171-
QualType CanUnqualT = T.getCanonicalType().getUnqualifiedType();
71727174
for (const CXXBaseSpecifier &B : RD->bases())
7173-
if (B.getType().getCanonicalType().getUnqualifiedType() !=
7174-
CanUnqualT &&
7175-
!Check(B.getType(), Check))
7175+
if (!Check(B.getType(), Check))
71767176
return false;
71777177
for (const FieldDecl *FD : RD->fields())
7178-
if (FD->getType().getCanonicalType().getUnqualifiedType() !=
7179-
CanUnqualT &&
7180-
!Check(FD->getType(), Check))
7178+
if (!Check(FD->getType(), Check))
71817179
return false;
71827180
return true;
71837181
};

clang/test/SemaCXX/gh102293.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,20 @@ class quux : quux { // expected-error {{base class has incomplete type}} \
4545
virtual int c();
4646
};
4747
}
48+
49+
// Ensure we don't get infinite recursion from the check, however. See GH141789
50+
namespace GH141789 {
51+
template <typename Ty>
52+
struct S {
53+
Ty t; // expected-error {{field has incomplete type 'GH141789::X'}}
54+
};
55+
56+
struct T {
57+
~T();
58+
};
59+
60+
struct X { // expected-note {{definition of 'GH141789::X' is not complete until the closing '}'}}
61+
S<X> next; // expected-note {{in instantiation of template class 'GH141789::S<GH141789::X>' requested here}}
62+
T m;
63+
};
64+
}

0 commit comments

Comments
 (0)