[clang] [clang] Fix C++20 list initialization of const references to arrays of unknown bound (PR #218225)

Ahmed Zihan Hossain via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 30 09:41:01 PDT 2026


================
@@ -5004,18 +5004,20 @@ static void TryReferenceListInitialization(Sema &S,
       Sequence.AddReferenceBindingStep(cv1T1IgnoreAS,
                                        /*BindingTemporary=*/true);
       if (S.getLangOpts().CPlusPlus20 &&
-          isa<IncompleteArrayType>(T1->getUnqualifiedDesugaredType()) &&
-          DestType->isRValueReferenceType()) {
+          isa<IncompleteArrayType>(T1->getUnqualifiedDesugaredType())) {
         // C++20 [dcl.init.list]p3.10:
         // List-initialization of an object or reference of type T is defined as
         // follows:
         // ..., unless T is “reference to array of unknown bound of U”, in which
         // case the type of the prvalue is the type of x in the declaration U
         // x[] H, where H is the initializer list.
 
-        // The call to AddReferenceBindingStep above converts the rvalue to an
-        // xvalue. Convert that xvalue to the incomplete array type.
-        Sequence.AddQualificationConversionStep(cv1T1, clang::VK_XValue);
+        // The call to AddReferenceBindingStep above materialized a temporary
+        // with the deduced bound. Convert it to the incomplete array type so
+        // that the expression type matches the referenced type. The temporary
+        // is an lvalue when bound to an lvalue reference, an xvalue otherwise.
+        Sequence.AddQualificationConversionStep(
+            cv1T1, DestType->isRValueReferenceType() ? VK_XValue : VK_LValue);
----------------
zihan001 wrote:

The prvalue is the initializer-list result before the temporary is materialized. At this point the temporary is already an lvalue or xvalue. I updated the comment to make that clearer.

https://github.com/llvm/llvm-project/pull/218225


More information about the cfe-commits mailing list