[clang] [clang] Fix a crash issue that caused by handling of fields with initializers in nested anonymous unions (PR #113049)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 19 09:17:31 PDT 2024
https://github.com/yronglin created https://github.com/llvm/llvm-project/pull/113049
Fix a crash issue that caused by handling of fields with initializers in nested anonymous unions.
If my thinking is wrong, I apologize, and IIUC seems it's caused by 5ae5774fb0b5cac11af479b0905dfdd5255b4047.
>From 57293112bb238ae6ac1d0dea9dafba72fa5e9fed Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Sun, 20 Oct 2024 00:12:00 +0800
Subject: [PATCH] [clang] Fix a crash issue that caused by handling of of
fields with initializers in nested anonymous unions
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
clang/lib/Sema/SemaInit.cpp | 15 ++++++++++-----
.../test/SemaCXX/cxx1y-initializer-aggregates.cpp | 11 +++++++++++
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index f560865681fa5a..4878dcb5d2c8e0 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -868,13 +868,19 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
const RecordDecl *RDecl = RType->getDecl();
- if (RDecl->isUnion() && ILE->getInitializedFieldInUnion()) {
+ if (RDecl->isUnion() && ILE->getInitializedFieldInUnion())
FillInEmptyInitForField(0, ILE->getInitializedFieldInUnion(), Entity, ILE,
RequiresSecondPass, FillWithNoInit);
+ else if (RDecl->isUnion() && isa<CXXRecordDecl>(RDecl) &&
+ cast<CXXRecordDecl>(RDecl)->hasInClassInitializer()) {
+ for (auto *Field : RDecl->fields()) {
+ if (Field->hasInClassInitializer()) {
+ FillInEmptyInitForField(0, Field, Entity, ILE, RequiresSecondPass,
+ FillWithNoInit);
+ break;
+ }
+ }
} else {
- assert((!RDecl->isUnion() || !isa<CXXRecordDecl>(RDecl) ||
- !cast<CXXRecordDecl>(RDecl)->hasInClassInitializer()) &&
- "We should have computed initialized fields already");
// The fields beyond ILE->getNumInits() are default initialized, so in
// order to leave them uninitialized, the ILE is expanded and the extra
// fields are then filled with NoInitExpr.
@@ -2296,7 +2302,6 @@ void InitListChecker::CheckStructUnionTypes(
return;
}
}
- llvm_unreachable("Couldn't find in-class initializer");
}
// Value-initialize the first member of the union that isn't an unnamed
diff --git a/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp b/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp
index 03a6800898d18f..8360b8fd7d8ee2 100644
--- a/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp
+++ b/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp
@@ -115,3 +115,14 @@ namespace nested_union {
// of Test3, or we should exclude f(Test3) as a candidate.
static_assert(f({1}) == 2, ""); // expected-error {{call to 'f' is ambiguous}}
}
+
+// Fix crash issue https://github.com/llvm/llvm-project/issues/112560.
+// Make sure clang compiles the following code without crashing:
+namespace GH112560 {
+union U {
+ int f = ; // expected-error {{expected expression}}
+};
+void foo() {
+ U g{};
+}
+} // namespace GH112560
More information about the cfe-commits
mailing list