@@ -4091,6 +4091,16 @@ void InitializationSequence::AddParenthesizedListInitStep(QualType T) {
40914091 Steps.push_back (S);
40924092}
40934093
4094+ void InitializationSequence::AddUnwrapInitListInitStep (
4095+ InitListExpr *Syntactic) {
4096+ assert (Syntactic->getNumInits () == 1 &&
4097+ " Can only unwrap trivial init lists." );
4098+ Step S;
4099+ S.Kind = SK_UnwrapInitList;
4100+ S.Type = Syntactic->getInit (0 )->getType ();
4101+ Steps.insert (Steps.begin (), S);
4102+ }
4103+
40944104void InitializationSequence::RewrapReferenceInitList (QualType T,
40954105 InitListExpr *Syntactic) {
40964106 assert (Syntactic->getNumInits () == 1 &&
@@ -4167,6 +4177,33 @@ static void MaybeProduceObjCObject(Sema &S,
41674177 }
41684178}
41694179
4180+ // / Initialize an array from another array
4181+ static void TryArrayCopy (Sema &S, const InitializationKind &Kind,
4182+ const InitializedEntity &Entity, Expr *Initializer,
4183+ QualType DestType, InitializationSequence &Sequence,
4184+ bool TreatUnavailableAsInvalid) {
4185+ // If source is a prvalue, use it directly.
4186+ if (Initializer->isPRValue ()) {
4187+ Sequence.AddArrayInitStep (DestType, /* IsGNUExtension*/ false );
4188+ return ;
4189+ }
4190+
4191+ // Emit element-at-a-time copy loop.
4192+ InitializedEntity Element =
4193+ InitializedEntity::InitializeElement (S.Context , 0 , Entity);
4194+ QualType InitEltT =
4195+ S.Context .getAsArrayType (Initializer->getType ())->getElementType ();
4196+ OpaqueValueExpr OVE (Initializer->getExprLoc (), InitEltT,
4197+ Initializer->getValueKind (),
4198+ Initializer->getObjectKind ());
4199+ Expr *OVEAsExpr = &OVE;
4200+ Sequence.InitializeFrom (S, Element, Kind, OVEAsExpr,
4201+ /* TopLevelOfInitList*/ false ,
4202+ TreatUnavailableAsInvalid);
4203+ if (Sequence)
4204+ Sequence.AddArrayInitLoopStep (Entity.getType (), InitEltT);
4205+ }
4206+
41704207static void TryListInitialization (Sema &S,
41714208 const InitializedEntity &Entity,
41724209 const InitializationKind &Kind,
@@ -4775,6 +4812,31 @@ static void TryListInitialization(Sema &S,
47754812 }
47764813 if (const ArrayType *DestAT = S.Context .getAsArrayType (DestType)) {
47774814 Expr *SubInit[1 ] = {InitList->getInit (0 )};
4815+
4816+ // C++17 [dcl.struct.bind]p1:
4817+ // ... If the assignment-expression in the initializer has array type A
4818+ // and no ref-qualifier is present, e has type cv A and each element is
4819+ // copy-initialized or direct-initialized from the corresponding element
4820+ // of the assignment-expression as specified by the form of the
4821+ // initializer. ...
4822+ //
4823+ // This is a special case not following list-initialization.
4824+ if (isa<ConstantArrayType>(DestAT) &&
4825+ Entity.getKind () == InitializedEntity::EK_Variable &&
4826+ isa<DecompositionDecl>(Entity.getDecl ())) {
4827+ assert (
4828+ S.Context .hasSameUnqualifiedType (SubInit[0 ]->getType (), DestType) &&
4829+ " Deduced to other type?" );
4830+ TryArrayCopy (S,
4831+ InitializationKind::CreateCopy (Kind.getLocation (),
4832+ InitList->getLBraceLoc ()),
4833+ Entity, SubInit[0 ], DestType, Sequence,
4834+ TreatUnavailableAsInvalid);
4835+ if (Sequence)
4836+ Sequence.AddUnwrapInitListInitStep (InitList);
4837+ return ;
4838+ }
4839+
47784840 if (!isa<VariableArrayType>(DestAT) &&
47794841 IsStringInit (SubInit[0 ], DestAT, S.Context ) == SIF_None) {
47804842 InitializationKind SubKind =
@@ -6461,25 +6523,8 @@ void InitializationSequence::InitializeFrom(Sema &S,
64616523 S.Context .hasSameUnqualifiedType (Initializer->getType (),
64626524 Entity.getType ()) &&
64636525 canPerformArrayCopy (Entity)) {
6464- // If source is a prvalue, use it directly.
6465- if (Initializer->isPRValue ()) {
6466- AddArrayInitStep (DestType, /* IsGNUExtension*/ false );
6467- return ;
6468- }
6469-
6470- // Emit element-at-a-time copy loop.
6471- InitializedEntity Element =
6472- InitializedEntity::InitializeElement (S.Context , 0 , Entity);
6473- QualType InitEltT =
6474- Context.getAsArrayType (Initializer->getType ())->getElementType ();
6475- OpaqueValueExpr OVE (Initializer->getExprLoc (), InitEltT,
6476- Initializer->getValueKind (),
6477- Initializer->getObjectKind ());
6478- Expr *OVEAsExpr = &OVE;
6479- InitializeFrom (S, Element, Kind, OVEAsExpr, TopLevelOfInitList,
6480- TreatUnavailableAsInvalid);
6481- if (!Failed ())
6482- AddArrayInitLoopStep (Entity.getType (), InitEltT);
6526+ TryArrayCopy (S, Kind, Entity, Initializer, DestType, *this ,
6527+ TreatUnavailableAsInvalid);
64836528 return ;
64846529 }
64856530
0 commit comments