diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -957,6 +957,16 @@ template void foo() { (void)[[size^of]](T); })cpp", + R"cpp(// should not crash on invalid semantic form of init-list-expr. + /*error-ok*/ + struct Foo { + int xyz = 0; + }; + class Bar {}; + constexpr Foo s = ^{ + .xyz = Bar(), + }; + )cpp", // literals "auto x = t^rue;", "auto x = '^A';", diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -4690,6 +4690,14 @@ setDependence(getDependence() | expr->getDependence()); } + /// Mark the semantic form of the InitListExpr as error when the semantic + /// analysis fails. + void markError() { + assert(isSemanticForm()); + setDependence(getDependence() | ExprDependence::Error | + ExprDependence::ValueInstantiation); + } + /// Reserve space for some number of initializers. void reserveInits(const ASTContext &C, unsigned NumInits); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -962,6 +962,8 @@ FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass, nullptr, 0); } + if (hadError && FullyStructuredList) + FullyStructuredList->markError(); } int InitListChecker::numArrayElements(QualType DeclType) {