https://github.com/kodlan updated https://github.com/llvm/llvm-project/pull/221488
>From 519cbbb9201da965e87fabc4188de4b5a6618210 Mon Sep 17 00:00:00 2001 From: Stanislav Bardyuk <[email protected]> Date: Mon, 19 Oct 2026 15:21:43 +0000 Subject: [PATCH] [Clang] Complete the element type when list-initializing an array of unknown bound List-initializing a temporary array of unknown bound from an empty initializer list creates a zero-length array whose elements are never initialized, so nothing ever completes the element type. If that type is a class template specialization that has not been instantiated yet (or a forward-declared class), the destructor lookup for the temporary in MaybeBindToTemporary runs on a record without a definition and trips the CanDeclareSpecialMemberFunction assertion in LookupSpecialMember. TryListInitialization already requires a record destination type to be complete. Extend that check to the base element type of an incomplete array destination, mirroring what TryListConversion does in overload resolution. The specialization gets instantiated and the program is accepted (as with GCC); a forward-declared element type is now diagnosed as an incomplete type instead of crashing. Fixes #217883 --- clang/docs/ReleaseNotes.md | 3 ++ clang/lib/Sema/SemaInit.cpp | 12 ++++++-- .../test/SemaCXX/cxx20-p0388-unbound-ary.cpp | 28 +++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 44f30666457f94..eea352013100e6 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -1051,6 +1051,9 @@ documentation](CIR/index.md) for more information regarding ClangIR's status and (#GH214128) - Fixed a crash when a coroutine keyword appeared inside a mem-initializer on a function that is not a constructor. (#GH194298) +- Fixed a crash when list-initializing an array of unknown bound from an empty + initializer list whose element type is an uninstantiated class template + specialization or an incomplete class. (#GH217883) - Fixed an assertion when a defaulted comparison operator was synthesized for a class with an invalid non-static data member, such as one qualified with an diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index fa4ef1ce57f172..f3328377f17983 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -5080,9 +5080,15 @@ static void TryListInitialization(Sema &S, return; } - if (DestType->isRecordType() && - !S.isCompleteType(InitList->getBeginLoc(), DestType)) { - Sequence.setIncompleteTypeFailure(DestType); + // For an array of unknown bound (C++20), the base element type must be + // complete: an empty list creates a zero-length array whose elements are + // never initialized, so nothing else would complete it. + QualType InitTy = DestType; + if (const auto *IAT = S.Context.getAsIncompleteArrayType(DestType)) + InitTy = S.Context.getBaseElementType(IAT); + if (InitTy->isRecordType() && + !S.isCompleteType(InitList->getBeginLoc(), InitTy)) { + Sequence.setIncompleteTypeFailure(InitTy); return; } diff --git a/clang/test/SemaCXX/cxx20-p0388-unbound-ary.cpp b/clang/test/SemaCXX/cxx20-p0388-unbound-ary.cpp index f2d5cabad235d0..7ac0204e612b0d 100644 --- a/clang/test/SemaCXX/cxx20-p0388-unbound-ary.cpp +++ b/clang/test/SemaCXX/cxx20-p0388-unbound-ary.cpp @@ -171,3 +171,31 @@ void g3() { } // namespace Eight #endif + +namespace gh217883 { +template <typename> struct Q {}; + +const Q<int> (&r1)[] = {}; +Q<int> (&&r2)[] = {}; +const Q<int> (&r3)[][2] = {}; + +void call(void (*f)(const Q<int> (&)[])) { f({}); } +void call_rvalue(void (*f)(Q<int> (&&)[])) { f({}); } +void call_nested(void (*f)(const Q<int> (&)[][2])) { f({}); } + +#if __cplusplus >= 202002 +static_assert(requires(void f(const Q<int> (&)[])) { f({}); }); +#endif + +template <typename> struct DeletedDtor { ~DeletedDtor() = delete; }; // expected-note {{marked deleted here}} +void call_deleted(void (*f)(const DeletedDtor<int> (&)[])) { + f({}); // expected-error {{attempt to use a deleted function}} +} + +struct Incomplete; // expected-note 3 {{forward declaration of 'gh217883::Incomplete'}} +const Incomplete (&r4)[] = {}; // expected-error {{initialization of incomplete type 'const Incomplete'}} +const Incomplete (&r5)[][2] = {}; // expected-error {{initialization of incomplete type 'const Incomplete'}} +void call_incomplete(void (*f)(const Incomplete (&)[])) { + f({}); // expected-error {{initialization of incomplete type 'const Incomplete'}} +} +} // namespace gh217883 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
