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/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h --- a/clang/include/clang/AST/DependenceFlags.h +++ b/clang/include/clang/AST/DependenceFlags.h @@ -41,6 +41,7 @@ TypeInstantiation = Type | Instantiation, ValueInstantiation = Value | Instantiation, TypeValueInstantiation = Type | Value | Instantiation, + ErrorDependent = Error | ValueInstantiation, LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) }; 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,13 @@ 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::ErrorDependent); + } + /// Reserve space for some number of initializers. void reserveInits(const ASTContext &C, unsigned NumInits); diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -502,7 +502,7 @@ // dependent type), or the type is known and dependent, or it has // type-dependent subexpressions. auto D = toExprDependence(E->getType()->getDependence()) | - ExprDependence::ValueInstantiation | ExprDependence::Error; + ExprDependence::ErrorDependent; // FIXME: remove the type-dependent bit from subexpressions, if the // RecoveryExpr has a non-dependent type. for (auto *S : E->subExpressions()) 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) {