@@ -2252,6 +2252,8 @@ void InitListChecker::CheckStructUnionTypes(
2252
2252
!IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts());
2253
2253
bool HasDesignatedInit = false;
2254
2254
2255
+ llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
2256
+
2255
2257
while (Index < IList->getNumInits()) {
2256
2258
Expr *Init = IList->getInit(Index);
2257
2259
SourceLocation InitLoc = Init->getBeginLoc();
@@ -2267,28 +2269,32 @@ void InitListChecker::CheckStructUnionTypes(
2267
2269
2268
2270
// Handle this designated initializer. Field will be updated to
2269
2271
// the next field that we'll be initializing.
2270
- if (CheckDesignatedInitializer(Entity, IList, DIE, 0,
2271
- DeclType, &Field, nullptr, Index,
2272
- StructuredList, StructuredIndex,
2273
- true, TopLevelObject) )
2272
+ bool DesignatedInitFailed = CheckDesignatedInitializer(
2273
+ Entity, IList, DIE, 0, DeclType, &Field, nullptr, Index,
2274
+ StructuredList, StructuredIndex, true, TopLevelObject);
2275
+ if (DesignatedInitFailed )
2274
2276
hadError = true;
2275
- else if (!VerifyOnly) {
2276
- // Find the field named by the designated initializer.
2277
- RecordDecl::field_iterator F = RD->field_begin();
2278
- while (std::next(F) != Field)
2279
- ++F;
2280
- QualType ET = SemaRef.Context.getBaseElementType(F->getType());
2281
- if (checkDestructorReference(ET, InitLoc, SemaRef)) {
2282
- hadError = true;
2283
- return;
2277
+
2278
+ // Find the field named by the designated initializer.
2279
+ DesignatedInitExpr::Designator *D = DIE->getDesignator(0);
2280
+ if (!VerifyOnly && D->isFieldDesignator()) {
2281
+ FieldDecl *F = D->getFieldDecl();
2282
+ InitializedFields.insert(F);
2283
+ if (!DesignatedInitFailed) {
2284
+ QualType ET = SemaRef.Context.getBaseElementType(F->getType());
2285
+ if (checkDestructorReference(ET, InitLoc, SemaRef)) {
2286
+ hadError = true;
2287
+ return;
2288
+ }
2284
2289
}
2285
2290
}
2286
2291
2287
2292
InitializedSomething = true;
2288
2293
2289
2294
// Disable check for missing fields when designators are used.
2290
2295
// This matches gcc behaviour.
2291
- CheckForMissingFields = false;
2296
+ if (!SemaRef.getLangOpts().CPlusPlus)
2297
+ CheckForMissingFields = false;
2292
2298
continue;
2293
2299
}
2294
2300
@@ -2367,6 +2373,7 @@ void InitListChecker::CheckStructUnionTypes(
2367
2373
CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
2368
2374
StructuredList, StructuredIndex);
2369
2375
InitializedSomething = true;
2376
+ InitializedFields.insert(*Field);
2370
2377
2371
2378
if (RD->isUnion() && StructuredList) {
2372
2379
// Initialize the first field within the union.
@@ -2378,15 +2385,20 @@ void InitListChecker::CheckStructUnionTypes(
2378
2385
2379
2386
// Emit warnings for missing struct field initializers.
2380
2387
if (!VerifyOnly && InitializedSomething && CheckForMissingFields &&
2381
- Field != FieldEnd && !Field->getType()->isIncompleteArrayType() &&
2382
2388
!RD->isUnion()) {
2383
2389
// It is possible we have one or more unnamed bitfields remaining.
2384
2390
// Find first (if any) named field and emit warning.
2385
- for (RecordDecl::field_iterator it = Field, end = RD->field_end();
2391
+ for (RecordDecl::field_iterator it = HasDesignatedInit ? RD->field_begin()
2392
+ : Field,
2393
+ end = RD->field_end();
2386
2394
it != end; ++it) {
2395
+ if (HasDesignatedInit && InitializedFields.count(*it))
2396
+ continue;
2397
+
2387
2398
if (!it->isUnnamedBitfield() && !it->hasInClassInitializer()) {
2388
2399
SemaRef.Diag(IList->getSourceRange().getEnd(),
2389
- diag::warn_missing_field_initializers) << *it;
2400
+ diag::warn_missing_field_initializers)
2401
+ << *it;
2390
2402
break;
2391
2403
}
2392
2404
}
0 commit comments