Skip to content

[clang] Fix assertion failure when initializing union with FAM #77298

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 9, 2024

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Jan 8, 2024

When initializing a union that constrain a struct with a flexible array member, and the initializer list is empty, we currently trigger an assertion failure. This happens because getFlexibleArrayInitChars() assumes that the initializer list is non-empty.

The relevant code is only executed in assertion-enabled builds: https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CodeGenModule.cpp#L5318-L5324

Fixes #77085.

When initializing a union that constrain a struct with a flexible
array member, and the initializer list is empty, we currently
trigger an assertion failure. This happens because
getFlexibleArrayInitChars() assumes that the initializer list is
non-empty.

Fixes llvm#77085.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jan 8, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 8, 2024

@llvm/pr-subscribers-clang

Author: Nikita Popov (nikic)

Changes

When initializing a union that constrain a struct with a flexible array member, and the initializer list is empty, we currently trigger an assertion failure. This happens because getFlexibleArrayInitChars() assumes that the initializer list is non-empty.

The relevant code is only executed in assertion-enabled builds: https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CodeGenModule.cpp#L5318-L5324

Fixes #77085.


Full diff: https://github.com/llvm/llvm-project/pull/77298.diff

2 Files Affected:

  • (modified) clang/lib/AST/Decl.cpp (+1-1)
  • (modified) clang/test/CodeGen/flexible-array-init.c (+8)
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 12e0a6faa4c33d..e1440e5183a4e6 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2835,7 +2835,7 @@ CharUnits VarDecl::getFlexibleArrayInitChars(const ASTContext &Ctx) const {
   if (!Ty || !Ty->getDecl()->hasFlexibleArrayMember())
     return CharUnits::Zero();
   auto *List = dyn_cast<InitListExpr>(getInit()->IgnoreParens());
-  if (!List)
+  if (!List || List->getNumInits() == 0)
     return CharUnits::Zero();
   const Expr *FlexibleInit = List->getInit(List->getNumInits() - 1);
   auto InitTy = Ctx.getAsConstantArrayType(FlexibleInit->getType());
diff --git a/clang/test/CodeGen/flexible-array-init.c b/clang/test/CodeGen/flexible-array-init.c
index b2cf959f7e1220..bae926da5feb07 100644
--- a/clang/test/CodeGen/flexible-array-init.c
+++ b/clang/test/CodeGen/flexible-array-init.c
@@ -20,3 +20,11 @@ struct __attribute((packed, aligned(4))) { char a; int x; char z[]; } e = { 1, 2
 
 struct { int x; char y[]; } f = { 1, { 13, 15 } };
 // CHECK: @f ={{.*}} global <{ i32, [2 x i8] }> <{ i32 1, [2 x i8] c"\0D\0F" }>
+
+union {
+  struct {
+    int a;
+    char b[];
+  } x;
+} in_union = {};
+// CHECK: @in_union ={{.*}} global %union.anon zeroinitializer

@tbaederr
Copy link
Contributor

tbaederr commented Jan 8, 2024

Needs a short release note.

@@ -696,6 +696,9 @@ Bug Fixes in This Version
- Clang now accepts recursive non-dependent calls to functions with deduced
return type.
Fixes (`#71015 <https://github.com/llvm/llvm-project/issues/71015>`_)
- Fix assertion failure when initializing union containing struct with
flexible array member using empty initializer list.
Fixes (`#77085 <https://github.com/llvm/llvm-project/issues/77085>`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the _ was necessary but the documentation builder seems to be happy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the underscore to be safe. Wasn't intentional to drop it.

@nikic nikic merged commit c6bb89f into llvm:main Jan 9, 2024
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
…77298)

When initializing a union that constrain a struct with a flexible array
member, and the initializer list is empty, we currently trigger an
assertion failure. This happens because getFlexibleArrayInitChars()
assumes that the initializer list is non-empty.

Fixes llvm#77085.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Initializing union containing struct with flexible array member asserts
4 participants