[clang] [Clang][Sema]: Allow flexible arrays in unions and alone in structs (PR #84428)

Harald van Dijk via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 20 17:31:32 PDT 2024


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


More information about the cfe-commits mailing list