-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[clang][Sema] Fix crash on designated initializer of union member in subobject #167171
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
base: main
Are you sure you want to change the base?
[clang][Sema] Fix crash on designated initializer of union member in subobject #167171
Conversation
|
@llvm/pr-subscribers-clang Author: Naveen Seth Hanig (naveen-seth) ChangesFixes #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. The assertions failing this were logically sound, and this change ensures that such initializations are handled correctly during semantic analysis to avoid failing any assertion. Full diff: https://github.com/llvm/llvm-project/pull/167171.diff 2 Files Affected:
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}}
+}
|
…subobject Fixes llvm#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.
c896266 to
3fbca9a
Compare
Fznamznon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, thank you for this patch!
However I think there might be a bug/confustion somewhere else. Why would getInitializedFieldInUnion return non null when there is no initializer stored? Was it forgotten somewhere else? I would be more comfortable accepting this if we could explain why this happens.
|
I tried a different approach earlier in afcda23, which I believed was the correct fix. However, it caused test failures in I think I should have updated the failing tests instead of reverting to this workaround. My apologies, I will do that now. |
Yeah, that’s what I would usually assume if you get test failures related to AST dumping. |
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.