diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Sema/Initialization.h | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 12 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 20 | ||||
| -rw-r--r-- | clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp | 17 | ||||
| -rw-r--r-- | clang/www/cxx_status.html | 4 | 
5 files changed, 40 insertions, 18 deletions
| diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index ab108c8e35d..c2795fcaf3a 100644 --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -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); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 15c664a062e..692853fd146 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 291feea780b..6ece7c8d784 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -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; diff --git a/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp b/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp index 639aff64dfc..211719a7e9c 100644 --- a/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp +++ b/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp @@ -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}} diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index 9e6b675227d..2e1156682a7 100644 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -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> | 

