Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ Bug Fixes to Attribute Support
Bug Fixes to C++ Support
^^^^^^^^^^^^^^^^^^^^^^^^

- The initialization kind of elements of structured bindings
direct-list-initialized from an array is corrected to direct-initialization.

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
8 changes: 6 additions & 2 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
Comment on lines +4869 to +4871
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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. Otherwise, e is defined as-if by

So I think

auto [_]{a}; // direct-initialization
auto [_](a); // copy-initializer

Is my understanding correct that we need that we need to look at Kind.getKind() and call either CreateCopy or CreateDirect?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think your understanding is correct.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks correct to me as well, can we come up w/ a test case where it makes a difference though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... Is my understanding correct that we need that we need to look at Kind.getKind() and call either CreateCopy or CreateDirect?

This part of code is in function trylistinitialization. The function handles list-initialization (for structured bindings, it must be direct-list-initialization here) only.

This looks correct to me as well, can we come up w/ a test case where it makes a difference though.

I believe I have added these tests. I will make these tests more clear.

Entity, SubInit[0], DestType, Sequence,
TreatUnavailableAsInvalid);
if (Sequence)
Expand Down
42 changes: 18 additions & 24 deletions clang/test/SemaCXX/cxx1z-decomposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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