================ @@ -727,6 +729,44 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, if (hadError || VerifyOnly) { // Do nothing } else if (Init < NumInits) { + if (MaybeEmitMFIWarning) { + auto CheckAnonMember = [&](const FieldDecl *FD, + auto &&CheckAnonMember) -> bool { + FieldDecl *FirstUninitialized = nullptr; + RecordDecl *RD = FD->getType()->getAsRecordDecl(); + assert(RD && "Not anonymous member checked?"); + for (auto *F : RD->fields()) { + bool AllSet = false; + if (F->isAnonymousStructOrUnion()) + AllSet = CheckAnonMember(F, CheckAnonMember); + + if (AllSet || F->hasInClassInitializer()) { + if (RD->isUnion()) + return true; + continue; + } + + if (!F->isUnnamedBitfield() && + !F->getType()->isIncompleteArrayType() && + !F->isAnonymousStructOrUnion() && !FirstUninitialized) + FirstUninitialized = F; + } + + if (FirstUninitialized) { + SemaRef.Diag(Loc, diag::warn_missing_field_initializers) + << FirstUninitialized; + return false; ---------------- zygoloid wrote:
I think you should return `FirstUninitialized` here, and produce the warning at the top level if necessary. Right now it looks like this would produce a bogus warning for: ``` struct A { union { struct { int n; }; int m = 0; }; int z; }; A a = {.z = 1}; ``` ... because you'd visit the anonymous union, then recurse to the anonymous struct, then warn about `n`, then return to the anonymous union and find it's actually initialized. https://github.com/llvm/llvm-project/pull/70829 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits