[clang] [clang][Sema] Fix crash on designated initializer of union member in subobject (PR #167171)
Naveen Seth Hanig via cfe-commits
cfe-commits at lists.llvm.org
Sat Nov 8 12:03:45 PST 2025
https://github.com/naveen-seth updated https://github.com/llvm/llvm-project/pull/167171
>From afcda23927bb79dfd7446aa90bfc741d5254c2e2 Mon Sep 17 00:00:00 2001
From: naveen-seth <naveen.hanig at outlook.com>
Date: Sat, 8 Nov 2025 19:53:08 +0100
Subject: [PATCH 1/2] [clang][Sema] Fix crash on designated initializer of
union member in subobject
Fixes #166327
Clang previously hit an assertion in C++ mode when a nested
initializer list was followed by a designated initializer that
referred to a union member of the same subobject.
This fixes the assertion.
---
clang/lib/Sema/SemaInit.cpp | 5 +++-
.../crash-union-designated-initializer.cpp | 23 +++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
create mode 100644 clang/test/SemaCXX/crash-union-designated-initializer.cpp
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index cc6ddf568d346..13fb22ebfe0ef 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -2402,8 +2402,11 @@ void InitListChecker::CheckStructUnionTypes(
CheckEmptyInitializable(
InitializedEntity::InitializeMember(*Field, &Entity),
IList->getEndLoc());
- if (StructuredList)
+ if (StructuredList) {
StructuredList->setInitializedFieldInUnion(*Field);
+ StructuredList->resizeInits(SemaRef.Context,
+ StructuredList->getNumInits() + 1);
+ }
break;
}
}
diff --git a/clang/test/SemaCXX/crash-union-designated-initializer.cpp b/clang/test/SemaCXX/crash-union-designated-initializer.cpp
new file mode 100644
index 0000000000000..7ba40311eac0b
--- /dev/null
+++ b/clang/test/SemaCXX/crash-union-designated-initializer.cpp
@@ -0,0 +1,23 @@
+// Ensures that Clang does not crash in C++ mode, when a nested initializer
+// is followed by a designated initializer for a union member of that same
+// subobject.
+// See issue #166327.
+
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+auto main(void) -> int {
+ struct Point {
+ float x;
+ float y;
+ union {
+ int idx;
+ char label;
+ } extra;
+ };
+
+ struct SavePoint {
+ struct Point p;
+ };
+
+ SavePoint save = {.p = {.x = 3.0, .y = 4.0}, .p.extra.label = 'p'}; // expected-warning {{nested designators are a C99 extension}}
+}
>From 3fbca9a0595292e9309747b29a27cace266c2b84 Mon Sep 17 00:00:00 2001
From: naveen-seth <naveen.hanig at outlook.com>
Date: Sat, 8 Nov 2025 21:02:47 +0100
Subject: [PATCH 2/2] Revert back to previous strategy to fix failing tests
---
clang/lib/Sema/SemaInit.cpp | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 13fb22ebfe0ef..11cb9527525a9 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -2402,11 +2402,8 @@ void InitListChecker::CheckStructUnionTypes(
CheckEmptyInitializable(
InitializedEntity::InitializeMember(*Field, &Entity),
IList->getEndLoc());
- if (StructuredList) {
+ if (StructuredList)
StructuredList->setInitializedFieldInUnion(*Field);
- StructuredList->resizeInits(SemaRef.Context,
- StructuredList->getNumInits() + 1);
- }
break;
}
}
@@ -3032,10 +3029,11 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
if (StructuredList) {
FieldDecl *CurrentField = StructuredList->getInitializedFieldInUnion();
if (CurrentField && !declaresSameEntity(CurrentField, *Field)) {
- assert(StructuredList->getNumInits() == 1
- && "A union should never have more than one initializer!");
+ const auto NumInits = StructuredList->getNumInits();
+ assert(StructuredList->getNumInits() <= 1 &&
+ "A union should never have more than one initializer!");
- Expr *ExistingInit = StructuredList->getInit(0);
+ Expr *ExistingInit = NumInits ? StructuredList->getInit(0) : nullptr;
if (ExistingInit) {
// We're about to throw away an initializer, emit warning.
diagnoseInitOverride(
More information about the cfe-commits
mailing list