More progress on array initializers.
- Added Expr::isConstantExpr().
- Added type checking for InitListExpr elements.
- Added diagnostic for trying to initialize a variable sized object.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41674 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 5eac645..c2f03a3 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -289,19 +289,21 @@
return false;
}
-bool Sema::RequireConstantExprs(InitListExpr *IList) {
+bool Sema::CheckInitList(InitListExpr *IList, QualType DType, bool isStatic) {
bool hadError = false;
for (unsigned i = 0; i < IList->getNumInits(); i++) {
Expr *expr = IList->getInit(i);
if (InitListExpr *InitList = dyn_cast<InitListExpr>(expr))
- RequireConstantExprs(InitList);
+ CheckInitList(InitList, DType, isStatic);
else {
SourceLocation loc;
- // FIXME: should be isConstantExpr()...
- if (!expr->isIntegerConstantExpr(Context, &loc)) {
+
+ if (isStatic && !expr->isConstantExpr(Context, &loc)) { // C99 6.7.8p4.
Diag(loc, diag::err_init_element_not_constant, expr->getSourceRange());
hadError = true;
+ } else if (CheckSingleInitializer(expr, DType)) {
+ hadError = true; // types didn't match.
}
}
}
@@ -316,10 +318,27 @@
// We have an InitListExpr, make sure we set the type.
Init->setType(DeclType);
- if (isStatic) // C99 6.7.8p4.
- RequireConstantExprs(InitList);
-
- // FIXME: Lot of checking still to do...
+ // C99 6.7.8p3: The type of the entity to be initialized shall be an array
+ // of unknown size ("[]") or an object type that is not a variable array type.
+ if (const VariableArrayType *VAT = DeclType->getAsVariableArrayType()) {
+ Expr *expr = VAT->getSizeExpr();
+ if (expr) {
+ Diag(expr->getLocStart(), diag::err_variable_object_no_init,
+ expr->getSourceRange());
+ return QualType();
+ }
+ }
+ if (const ArrayType *Ary = DeclType->getAsArrayType()) {
+ // We have a ConstantArrayType or VariableArrayType with unknown size.
+ QualType ElmtType = Ary->getElementType();
+
+ // If we have a multi-dimensional array, navigate to the base type.
+ while ((Ary = ElmtType->getAsArrayType()))
+ ElmtType = Ary->getElementType();
+
+ CheckInitList(InitList, ElmtType, isStatic);
+ }
+ // FIXME: Handle struct/union types.
return DeclType;
}