Author: Yanzuo Liu
Date: 2025-02-08T14:31:47+08:00
New Revision: 6f241e36831927e3aea113cfc017c34fdeda340a

URL: 
https://github.com/llvm/llvm-project/commit/6f241e36831927e3aea113cfc017c34fdeda340a
DIFF: 
https://github.com/llvm/llvm-project/commit/6f241e36831927e3aea113cfc017c34fdeda340a.diff

LOG: [Clang][Sema] Fix wrong initialization kind when handling initializing 
structured bindings from an array with direct-list-initialization (#124793)

In 377257f063c, elements of structured bindings are copy-initialized.
They should be direct-initialized because the form of the initializer of
the whole structured bindings is a direct-list-initialization.

> [dcl.struct.bind]/1:
> ... and each element is copy-initialized or direct-initialized from
the corresponding element of the assignment-expression as specified by
the form of the initializer. ...

For example,

```cpp
  int arr[2]{};
  // elements of `[a, b]` should be direct-initialized
  auto [a, b]{arr};
```

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaInit.cpp
    clang/test/SemaCXX/cxx1z-decomposition.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 03997395f56d84..50d3bbbc97e919 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -151,6 +151,8 @@ Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
 - Clang is now better at keeping track of friend function template instance 
contexts. (#GH55509)
+- The initialization kind of elements of structured bindings
+  direct-list-initialized from an array is corrected to direct-initialization.
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index f206cd57eca898..308222a79d920c 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -4862,9 +4862,13 @@ static void TryListInitialization(Sema &S,
         assert(
             S.Context.hasSameUnqualifiedType(SubInit[0]->getType(), DestType) 
&&
             "Deduced to other type?");
+        assert(Kind.getKind() == clang::InitializationKind::IK_DirectList &&
+               "List-initialize structured bindings but not "
+               "direct-list-initialization?");
         TryArrayCopy(S,
-                     InitializationKind::CreateCopy(Kind.getLocation(),
-                                                    InitList->getLBraceLoc()),
+                     InitializationKind::CreateDirect(Kind.getLocation(),
+                                                      InitList->getLBraceLoc(),
+                                                      
InitList->getRBraceLoc()),
                      Entity, SubInit[0], DestType, Sequence,
                      TreatUnavailableAsInvalid);
         if (Sequence)

diff  --git a/clang/test/SemaCXX/cxx1z-decomposition.cpp 
b/clang/test/SemaCXX/cxx1z-decomposition.cpp
index a8914fe4e9cd82..95c64bc3b8bff6 100644
--- a/clang/test/SemaCXX/cxx1z-decomposition.cpp
+++ b/clang/test/SemaCXX/cxx1z-decomposition.cpp
@@ -200,38 +200,32 @@ namespace lambdas {
 
 namespace by_value_array_copy {
   struct explicit_copy {
-    explicit_copy() = default; // expected-note 2{{candidate constructor not 
viable: requires 0 arguments, but 1 was provided}}
-    explicit explicit_copy(const explicit_copy&) = default; // expected-note 
2{{explicit constructor is not a candidate}}
+    explicit_copy() = default; // expected-note {{candidate constructor not 
viable: requires 0 arguments, but 1 was provided}}
+    explicit explicit_copy(const explicit_copy&) = default; // expected-note 
{{explicit constructor is not a candidate}}
   };
 
-  constexpr int direct_initialization_for_elements() {
-    explicit_copy ec_arr[2];
-    auto [a1, b1](ec_arr);
+  constexpr int simple_array_elements() {
+    int arr[2]{1, 2};
 
-    int arr[3]{1, 2, 3};
-    auto [a2, b2, c2](arr);
-    arr[0]--;
-    return a2 + b2 + c2 + arr[0];
-  }
-  static_assert(direct_initialization_for_elements() == 6);
+    auto [a1, a2] = arr;
+    auto [b1, b2](arr);
+    auto [c1, c2]{arr}; // GH31813
 
-  constexpr int copy_initialization_for_elements() {
-    int arr[2]{4, 5};
-    auto [a1, b1] = arr;
-    auto [a2, b2]{arr}; // GH31813
     arr[0] = 0;
-    return a1 + b1 + a2 + b2 + arr[0];
+    return arr[0] + a1 + a2 + b1 + b2 + c1 + c2;
   }
-  static_assert(copy_initialization_for_elements() == 18);
+  static_assert(simple_array_elements() == 9);
+
+  void explicit_copy_ctor_array_elements() {
+    explicit_copy ec_arr[1];
 
-  void copy_initialization_for_elements_with_explicit_copy_ctor() {
-    explicit_copy ec_arr[2];
-    auto [a1, b1] = ec_arr; // expected-error {{no matching constructor for 
initialization of 'explicit_copy[2]'}}
-    auto [a2, b2]{ec_arr}; // expected-error {{no matching constructor for 
initialization of 'explicit_copy[2]'}}
+    auto [a] = ec_arr; // expected-error {{no matching constructor for 
initialization of 'explicit_copy[1]'}}
+    auto [b](ec_arr);
+    auto [c]{ec_arr};
 
     // Test prvalue
-    using T = explicit_copy[2];
-    auto [a3, b3] = T{};
-    auto [a4, b4]{T{}};
+    using T = explicit_copy[1];
+    auto [d] = T{};
   }
+
 } // namespace by_value_array_copy


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to