Skip to content

Commit 6f241e3

Browse files
authored
[Clang][Sema] Fix wrong initialization kind when handling initializing structured bindings from an array with direct-list-initialization (#124793)
In 377257f, 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}; ```
1 parent e0a21e2 commit 6f241e3

File tree

3 files changed

+26
-26
lines changed

3 files changed

+26
-26
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ Bug Fixes to C++ Support
151151
^^^^^^^^^^^^^^^^^^^^^^^^
152152

153153
- Clang is now better at keeping track of friend function template instance contexts. (#GH55509)
154+
- The initialization kind of elements of structured bindings
155+
direct-list-initialized from an array is corrected to direct-initialization.
154156

155157
Bug Fixes to AST Handling
156158
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaInit.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4862,9 +4862,13 @@ static void TryListInitialization(Sema &S,
48624862
assert(
48634863
S.Context.hasSameUnqualifiedType(SubInit[0]->getType(), DestType) &&
48644864
"Deduced to other type?");
4865+
assert(Kind.getKind() == clang::InitializationKind::IK_DirectList &&
4866+
"List-initialize structured bindings but not "
4867+
"direct-list-initialization?");
48654868
TryArrayCopy(S,
4866-
InitializationKind::CreateCopy(Kind.getLocation(),
4867-
InitList->getLBraceLoc()),
4869+
InitializationKind::CreateDirect(Kind.getLocation(),
4870+
InitList->getLBraceLoc(),
4871+
InitList->getRBraceLoc()),
48684872
Entity, SubInit[0], DestType, Sequence,
48694873
TreatUnavailableAsInvalid);
48704874
if (Sequence)

clang/test/SemaCXX/cxx1z-decomposition.cpp

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -200,38 +200,32 @@ namespace lambdas {
200200

201201
namespace by_value_array_copy {
202202
struct explicit_copy {
203-
explicit_copy() = default; // expected-note 2{{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
204-
explicit explicit_copy(const explicit_copy&) = default; // expected-note 2{{explicit constructor is not a candidate}}
203+
explicit_copy() = default; // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
204+
explicit explicit_copy(const explicit_copy&) = default; // expected-note {{explicit constructor is not a candidate}}
205205
};
206206

207-
constexpr int direct_initialization_for_elements() {
208-
explicit_copy ec_arr[2];
209-
auto [a1, b1](ec_arr);
207+
constexpr int simple_array_elements() {
208+
int arr[2]{1, 2};
210209

211-
int arr[3]{1, 2, 3};
212-
auto [a2, b2, c2](arr);
213-
arr[0]--;
214-
return a2 + b2 + c2 + arr[0];
215-
}
216-
static_assert(direct_initialization_for_elements() == 6);
210+
auto [a1, a2] = arr;
211+
auto [b1, b2](arr);
212+
auto [c1, c2]{arr}; // GH31813
217213

218-
constexpr int copy_initialization_for_elements() {
219-
int arr[2]{4, 5};
220-
auto [a1, b1] = arr;
221-
auto [a2, b2]{arr}; // GH31813
222214
arr[0] = 0;
223-
return a1 + b1 + a2 + b2 + arr[0];
215+
return arr[0] + a1 + a2 + b1 + b2 + c1 + c2;
224216
}
225-
static_assert(copy_initialization_for_elements() == 18);
217+
static_assert(simple_array_elements() == 9);
218+
219+
void explicit_copy_ctor_array_elements() {
220+
explicit_copy ec_arr[1];
226221

227-
void copy_initialization_for_elements_with_explicit_copy_ctor() {
228-
explicit_copy ec_arr[2];
229-
auto [a1, b1] = ec_arr; // expected-error {{no matching constructor for initialization of 'explicit_copy[2]'}}
230-
auto [a2, b2]{ec_arr}; // expected-error {{no matching constructor for initialization of 'explicit_copy[2]'}}
222+
auto [a] = ec_arr; // expected-error {{no matching constructor for initialization of 'explicit_copy[1]'}}
223+
auto [b](ec_arr);
224+
auto [c]{ec_arr};
231225

232226
// Test prvalue
233-
using T = explicit_copy[2];
234-
auto [a3, b3] = T{};
235-
auto [a4, b4]{T{}};
227+
using T = explicit_copy[1];
228+
auto [d] = T{};
236229
}
230+
237231
} // namespace by_value_array_copy

0 commit comments

Comments
 (0)