diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index de0d92edb550d..035eaae58965a 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -864,6 +864,17 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity, WarnIfMissingField &= SemaRef.getLangOpts().CPlusPlus || !hasAnyDesignatedInits(SForm); + if (OuterILE) { + // When nested designators are present, there might be two nested init + // lists created and only outer will contain designated initializer + // expression, so check outer list as well. + InitListExpr *OuterSForm = OuterILE->isSyntacticForm() + ? OuterILE + : OuterILE->getSyntacticForm(); + WarnIfMissingField &= SemaRef.getLangOpts().CPlusPlus || + !hasAnyDesignatedInits(OuterSForm); + } + unsigned NumElems = numStructUnionElements(ILE->getType()); if (!RDecl->isUnion() && RDecl->hasFlexibleArrayMember()) ++NumElems; diff --git a/clang/test/Sema/missing-field-initializers.c b/clang/test/Sema/missing-field-initializers.c index 8653591ff1187..8dc8288ad92e6 100644 --- a/clang/test/Sema/missing-field-initializers.c +++ b/clang/test/Sema/missing-field-initializers.c @@ -61,3 +61,26 @@ struct S { // f1, now we no longer issue that warning (note, this code is still unsafe // because of the buffer overrun). struct S s = {1, {1, 2}}; + +struct S1 { + long int l; + struct { int a, b; } d1; +}; + +struct S1 s01 = { 1, {1} }; // expected-warning {{missing field 'b' initializer}} +struct S1 s02 = { .d1.a = 1 }; // designator avoids MFI warning + +union U1 { + long int l; + struct { int a, b; } d1; +}; + +union U1 u01 = { 1 }; +union U1 u02 = { .d1.a = 1 }; // designator avoids MFI warning + +struct S2 { + long int l; + struct { int a, b; struct {int c; } d2; } d1; +}; + +struct S2 s22 = { .d1.d2.c = 1 }; // designator avoids MFI warning