[clang] [clang-tools-extra] [llvm] [clang] Fix false positive -Wmissing-field-initializer for anonymous unions (PR #70829)

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 6 13:55:25 PST 2023


================
@@ -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


More information about the cfe-commits mailing list