Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 3 additions & 2 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4861,8 +4861,9 @@ static void TryListInitialization(Sema &S,
S.Context.hasSameUnqualifiedType(SubInit[0]->getType(), DestType) &&
"Deduced to other type?");
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
21 changes: 10 additions & 11 deletions clang/test/SemaCXX/cxx1z-decomposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,38 +200,37 @@ 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);
auto [a2, b2]{ec_arr};

int arr[3]{1, 2, 3};
auto [a2, b2, c2](arr);
auto [a3, b3, c3](arr);
auto [a4, b4, c4]{arr}; // GH31813
arr[0]--;
return a2 + b2 + c2 + arr[0];
return a3 + b3 + c3 + a4 + b4 + c4 + arr[0];
}
static_assert(direct_initialization_for_elements() == 6);
static_assert(direct_initialization_for_elements() == 12);

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 a1 + b1 + arr[0];
}
static_assert(copy_initialization_for_elements() == 18);
static_assert(copy_initialization_for_elements() == 9);

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]'}}

// Test prvalue
using T = explicit_copy[2];
auto [a3, b3] = T{};
auto [a4, b4]{T{}};
auto [a2, b2] = T{};
}
} // namespace by_value_array_copy