forked from OSchip/llvm-project
[c++1z] P0217R3: Allow by-value structured binding of arrays.
llvm-svn: 289630
This commit is contained in:
parent
eb6a20e79e
commit
378b8c8f01
|
@ -732,8 +732,9 @@ public:
|
|||
/// \brief Array initialization by elementwise copy.
|
||||
SK_ArrayLoopInit,
|
||||
/// \brief Array initialization (from an array rvalue).
|
||||
/// This is a GNU C extension.
|
||||
SK_ArrayInit,
|
||||
/// \brief Array initialization (from an array rvalue) as a GNU extension.
|
||||
SK_GNUArrayInit,
|
||||
/// \brief Array initialization from a parenthesized initializer list.
|
||||
/// This is a GNU C++ extension.
|
||||
SK_ParenthesizedArrayInit,
|
||||
|
@ -1123,7 +1124,7 @@ public:
|
|||
void AddArrayInitLoopStep(QualType T, QualType EltTy);
|
||||
|
||||
/// \brief Add an array initialization step.
|
||||
void AddArrayInitStep(QualType T);
|
||||
void AddArrayInitStep(QualType T, bool IsGNUExtension);
|
||||
|
||||
/// \brief Add a parenthesized array initialization step.
|
||||
void AddParenthesizedArrayInitStep(QualType T);
|
||||
|
|
|
@ -9653,9 +9653,6 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
|
|||
|
||||
VarDeclOrName VN{VDecl, Name};
|
||||
|
||||
// FIXME: Deduction for a decomposition declaration does weird things if the
|
||||
// initializer is an array.
|
||||
|
||||
ArrayRef<Expr *> DeduceInits = Init;
|
||||
if (DirectInit) {
|
||||
if (auto *PL = dyn_cast<ParenListExpr>(Init))
|
||||
|
@ -9704,6 +9701,15 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
|
|||
DefaultedAnyToId = true;
|
||||
}
|
||||
|
||||
// C++ [dcl.decomp]p1:
|
||||
// If the assignment-expression [...] has array type A and no ref-qualifier
|
||||
// is present, e has type cv A
|
||||
if (VDecl && isa<DecompositionDecl>(VDecl) &&
|
||||
Context.hasSameUnqualifiedType(Type, Context.getAutoDeductType()) &&
|
||||
DeduceInit->getType()->isConstantArrayType())
|
||||
return Context.getQualifiedType(DeduceInit->getType(),
|
||||
Type.getQualifiers());
|
||||
|
||||
QualType DeducedType;
|
||||
if (DeduceAutoType(TSI, DeduceInit, DeducedType) == DAR_Failed) {
|
||||
if (!IsInitCapture)
|
||||
|
|
|
@ -3068,6 +3068,7 @@ void InitializationSequence::Step::Destroy() {
|
|||
case SK_ArrayLoopIndex:
|
||||
case SK_ArrayLoopInit:
|
||||
case SK_ArrayInit:
|
||||
case SK_GNUArrayInit:
|
||||
case SK_ParenthesizedArrayInit:
|
||||
case SK_PassByIndirectCopyRestore:
|
||||
case SK_PassByIndirectRestore:
|
||||
|
@ -3302,9 +3303,9 @@ void InitializationSequence::AddObjCObjectConversionStep(QualType T) {
|
|||
Steps.push_back(S);
|
||||
}
|
||||
|
||||
void InitializationSequence::AddArrayInitStep(QualType T) {
|
||||
void InitializationSequence::AddArrayInitStep(QualType T, bool IsGNUExtension) {
|
||||
Step S;
|
||||
S.Kind = SK_ArrayInit;
|
||||
S.Kind = IsGNUExtension ? SK_GNUArrayInit : SK_ArrayInit;
|
||||
S.Type = T;
|
||||
Steps.push_back(S);
|
||||
}
|
||||
|
@ -5217,8 +5218,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
|
|||
canPerformArrayCopy(Entity)) {
|
||||
// If source is a prvalue, use it directly.
|
||||
if (Initializer->getValueKind() == VK_RValue) {
|
||||
// FIXME: This produces a bogus extwarn
|
||||
AddArrayInitStep(DestType);
|
||||
AddArrayInitStep(DestType, /*IsGNUExtension*/false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5251,7 +5251,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
|
|||
else if (Initializer->HasSideEffects(S.Context))
|
||||
SetFailed(FK_NonConstantArrayInit);
|
||||
else {
|
||||
AddArrayInitStep(DestType);
|
||||
AddArrayInitStep(DestType, /*IsGNUExtension*/true);
|
||||
}
|
||||
}
|
||||
// Note: as a GNU C++ extension, we allow list-initialization of a
|
||||
|
@ -6520,6 +6520,7 @@ InitializationSequence::Perform(Sema &S,
|
|||
case SK_ArrayLoopIndex:
|
||||
case SK_ArrayLoopInit:
|
||||
case SK_ArrayInit:
|
||||
case SK_GNUArrayInit:
|
||||
case SK_ParenthesizedArrayInit:
|
||||
case SK_PassByIndirectCopyRestore:
|
||||
case SK_PassByIndirectRestore:
|
||||
|
@ -7011,13 +7012,14 @@ InitializationSequence::Perform(Sema &S,
|
|||
break;
|
||||
}
|
||||
|
||||
case SK_ArrayInit:
|
||||
case SK_GNUArrayInit:
|
||||
// Okay: we checked everything before creating this step. Note that
|
||||
// this is a GNU extension.
|
||||
S.Diag(Kind.getLocation(), diag::ext_array_init_copy)
|
||||
<< Step->Type << CurInit.get()->getType()
|
||||
<< CurInit.get()->getSourceRange();
|
||||
|
||||
LLVM_FALLTHROUGH;
|
||||
case SK_ArrayInit:
|
||||
// If the destination type is an incomplete array type, update the
|
||||
// type accordingly.
|
||||
if (ResultType) {
|
||||
|
@ -7976,6 +7978,10 @@ void InitializationSequence::dump(raw_ostream &OS) const {
|
|||
OS << "array initialization";
|
||||
break;
|
||||
|
||||
case SK_GNUArrayInit:
|
||||
OS << "array initialization (GNU extension)";
|
||||
break;
|
||||
|
||||
case SK_ParenthesizedArrayInit:
|
||||
OS << "parenthesized array initialization";
|
||||
break;
|
||||
|
|
|
@ -1,9 +1,20 @@
|
|||
// RUN: %clang_cc1 -std=c++1z -verify %s
|
||||
// RUN: %clang_cc1 -std=c++1z -verify %s -Wpedantic
|
||||
|
||||
struct X {
|
||||
X(int);
|
||||
X(const X&) = delete;
|
||||
};
|
||||
|
||||
int array() {
|
||||
static int arr[3] = {};
|
||||
// FIXME: We are supposed to create an array object here and perform elementwise initialization.
|
||||
auto [a, b, c] = arr; // expected-error {{cannot decompose non-class, non-array}}
|
||||
auto [a, b, c] = arr;
|
||||
static_assert(&a != &arr[0]);
|
||||
|
||||
using I3 = int[3];
|
||||
auto [a2, b2, c2] = I3{1, 2, 3};
|
||||
|
||||
using X3 = X[3];
|
||||
auto [a3, b3, c3] = X3{1, 2, 3};
|
||||
|
||||
auto &[d, e] = arr; // expected-error {{type 'int [3]' decomposes into 3 elements, but only 2 names were provided}}
|
||||
auto &[f, g, h, i] = arr; // expected-error {{type 'int [3]' decomposes into 3 elements, but 4 names were provided}}
|
||||
|
|
|
@ -722,9 +722,7 @@ as the draft C++1z standard evolves.
|
|||
<tr>
|
||||
<td>Structured bindings</td>
|
||||
<td><a href="http://wg21.link/p0217r3">P0217R3</a></td>
|
||||
<td class="partial" align="center">Partial</td>
|
||||
<!-- We don't implement structured bindings of arrays yet, anticipating
|
||||
this being removed from the working draft -->
|
||||
<td class="svn" align="center">SVN</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Separate variable and condition for <tt>if</tt> and <tt>switch</tt></td>
|
||||
|
|
Loading…
Reference in New Issue