/// \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,
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);
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))
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)
case SK_ArrayLoopIndex:
case SK_ArrayLoopInit:
case SK_ArrayInit:
+ case SK_GNUArrayInit:
case SK_ParenthesizedArrayInit:
case SK_PassByIndirectCopyRestore:
case SK_PassByIndirectRestore:
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);
}
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;
}
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
case SK_ArrayLoopIndex:
case SK_ArrayLoopInit:
case SK_ArrayInit:
+ case SK_GNUArrayInit:
case SK_ParenthesizedArrayInit:
case SK_PassByIndirectCopyRestore:
case SK_PassByIndirectRestore:
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) {
OS << "array initialization";
break;
+ case SK_GNUArrayInit:
+ OS << "array initialization (GNU extension)";
+ break;
+
case SK_ParenthesizedArrayInit:
OS << "parenthesized array initialization";
break;
-// 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}}
<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>