@@ -4091,6 +4091,16 @@ void InitializationSequence::AddParenthesizedListInitStep(QualType T) {
4091
4091
Steps.push_back (S);
4092
4092
}
4093
4093
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
+
4094
4104
void InitializationSequence::RewrapReferenceInitList (QualType T,
4095
4105
InitListExpr *Syntactic) {
4096
4106
assert (Syntactic->getNumInits () == 1 &&
@@ -4167,6 +4177,33 @@ static void MaybeProduceObjCObject(Sema &S,
4167
4177
}
4168
4178
}
4169
4179
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
+
4170
4207
static void TryListInitialization (Sema &S,
4171
4208
const InitializedEntity &Entity,
4172
4209
const InitializationKind &Kind,
@@ -4775,6 +4812,31 @@ static void TryListInitialization(Sema &S,
4775
4812
}
4776
4813
if (const ArrayType *DestAT = S.Context .getAsArrayType (DestType)) {
4777
4814
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
+
4778
4840
if (!isa<VariableArrayType>(DestAT) &&
4779
4841
IsStringInit (SubInit[0 ], DestAT, S.Context ) == SIF_None) {
4780
4842
InitializationKind SubKind =
@@ -6461,25 +6523,8 @@ void InitializationSequence::InitializeFrom(Sema &S,
6461
6523
S.Context .hasSameUnqualifiedType (Initializer->getType (),
6462
6524
Entity.getType ()) &&
6463
6525
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);
6483
6528
return ;
6484
6529
}
6485
6530
0 commit comments