[llvm-branch-commits] [clang] release/19.x: [C++23] Fix infinite recursion (Clang 19.x regression) (#104829) (PR #104858)
Tobias Hieta via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 20 00:21:01 PDT 2024
https://github.com/tru updated https://github.com/llvm/llvm-project/pull/104858
>From 3ffa5421ca657c04d4df170307c1f9a3c6293003 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Mon, 19 Aug 2024 16:54:12 -0400
Subject: [PATCH] [C++23] Fix infinite recursion (Clang 19.x regression)
(#104829)
d469794d0cdfd2fea50a6ce0c0e33abb242d744c 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 435cb0dc5eca08cdd8d9ed0d887fa1693cc2bf33)
---
clang/lib/Sema/SemaDeclCXX.cpp | 9 +++++++--
clang/test/SemaCXX/gh102293.cpp | 27 ++++++++++++++++++++++++++-
2 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index ecf8754143a49e..92c47be67339e9 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 30629fc03bf6a9..d4218cc13dcecd 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 <typename T> 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();
+};
+}
More information about the llvm-branch-commits
mailing list