hvdijk wrote:

The problem with `union { char x[]; } x = {0};` is in 
`ConstStructBuilder::Build` ( `clang/lib/CodeGen/CGExprConstant.cpp`). It does:
```diff
    // If this is a union, skip all the fields that aren't being initialized.
    if (RD->isUnion() &&
        !declaresSameEntity(ILE->getInitializedFieldInUnion(), Field))
      continue;
```
But `ILE->getInitializedFieldInUnion()` returns `nullptr` so this skips all 
fields. `nullptr` is returned because `InitListChecker::CheckStructUnionTypes` 
never calls `StructuredList->setInitializedFieldInUnion`. If that gets called, 
then things work.

I think things can be simplified a bit further: if we do
```diff
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 79cf2eed46fe..3fcdf9118468 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -2332,7 +2332,7 @@ void InitListChecker::CheckStructUnionTypes(
 
     // We've already initialized a member of a union. We're done.
     if (InitializedSomething && RD->isUnion())
-      break;
+      return;
 
     // If we've hit the flexible array member at the end, we're done.
     if (Field->getType()->isIncompleteArrayType())
```
Then the tests still pass and we can remove or simplify some of the later 
checks for unions.

https://github.com/llvm/llvm-project/pull/84428
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to