template <typename T> 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';",
TypeInstantiation = Type | Instantiation,
ValueInstantiation = Value | Instantiation,
TypeValueInstantiation = Type | Value | Instantiation,
+ ErrorDependent = Error | ValueInstantiation,
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
};
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);
// 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())
FillInEmptyInitializations(Entity, FullyStructuredList,
RequiresSecondPass, nullptr, 0);
}
+ if (hadError && FullyStructuredList)
+ FullyStructuredList->markError();
}
int InitListChecker::numArrayElements(QualType DeclType) {