llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: None (yronglin) <details> <summary>Changes</summary> 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. --- Full diff: https://github.com/llvm/llvm-project/pull/113049.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaInit.cpp (+10-5) - (modified) clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp (+11) ``````````diff 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 `````````` </details> https://github.com/llvm/llvm-project/pull/113049 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits