Author: rsmith Date: Tue Dec 13 21:22:16 2016 New Revision: 289630 URL: http://llvm.org/viewvc/llvm-project?rev=289630&view=rev Log: [c++1z] P0217R3: Allow by-value structured binding of arrays.
Modified: cfe/trunk/include/clang/Sema/Initialization.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaInit.cpp cfe/trunk/test/CXX/dcl.decl/dcl.decomp/p2.cpp cfe/trunk/www/cxx_status.html Modified: cfe/trunk/include/clang/Sema/Initialization.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=289630&r1=289629&r2=289630&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Initialization.h (original) +++ cfe/trunk/include/clang/Sema/Initialization.h Tue Dec 13 21:22:16 2016 @@ -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); Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=289630&r1=289629&r2=289630&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Dec 13 21:22:16 2016 @@ -9653,9 +9653,6 @@ QualType Sema::deduceVarTypeFromInitiali 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::deduceVarTypeFromInitiali 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) Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=289630&r1=289629&r2=289630&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Dec 13 21:22:16 2016 @@ -3068,6 +3068,7 @@ void InitializationSequence::Step::Destr 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::AddObjCObje 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::InitializeF 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::InitializeF 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_os OS << "array initialization"; break; + case SK_GNUArrayInit: + OS << "array initialization (GNU extension)"; + break; + case SK_ParenthesizedArrayInit: OS << "parenthesized array initialization"; break; Modified: cfe/trunk/test/CXX/dcl.decl/dcl.decomp/p2.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.decomp/p2.cpp?rev=289630&r1=289629&r2=289630&view=diff ============================================================================== --- cfe/trunk/test/CXX/dcl.decl/dcl.decomp/p2.cpp (original) +++ cfe/trunk/test/CXX/dcl.decl/dcl.decomp/p2.cpp Tue Dec 13 21:22:16 2016 @@ -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}} Modified: cfe/trunk/www/cxx_status.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=289630&r1=289629&r2=289630&view=diff ============================================================================== --- cfe/trunk/www/cxx_status.html (original) +++ cfe/trunk/www/cxx_status.html Tue Dec 13 21:22:16 2016 @@ -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> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits