================ @@ -727,6 +734,38 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, if (hadError || VerifyOnly) { // Do nothing } else if (Init < NumInits) { + if (WarnIfMissing) { + auto CheckAnonMember = [&](const FieldDecl *FD, + auto &&CheckAnonMember) -> FieldDecl * { + FieldDecl *Uninitialized = nullptr; + RecordDecl *RD = FD->getType()->getAsRecordDecl(); + assert(RD && "Not anonymous member checked?"); + for (auto *F : RD->fields()) { + if (F->isAnonymousStructOrUnion()) + Uninitialized = CheckAnonMember(F, CheckAnonMember); + else if (!F->isUnnamedBitfield() && + !F->getType()->isIncompleteArrayType() && !Uninitialized && + !F->hasInClassInitializer()) + Uninitialized = F; + + if (RD->isUnion() && (F->hasInClassInitializer() || !Uninitialized)) + return nullptr; + } ---------------- zygoloid wrote:
I think this will not warn on ```c++ struct A { int a; struct { int x; struct { int y = 0; }; }; }; A a = A{.a = 0}; ``` ... because the `Uninitialized` value for `x` will get overwritten by the `nullptr` returned from the struct containing `y`. How about: ```suggestion for (auto *F : RD->fields()) { FieldDecl *UninitializedFieldInF; if (F->isAnonymousStructOrUnion()) UninitializedFieldInF = CheckAnonMember(F, CheckAnonMember); else if (!F->isUnnamedBitfield() && !F->getType()->isIncompleteArrayType() && !F->hasInClassInitializer()) UninitializedFieldInF = F; if (RD->isUnion() && !UninitializedFieldInF) return nullptr; if (!Uninitialized) Uninitialized = UninitializedFieldInF; } ``` 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