]> granicus.if.org Git - clang/commitdiff
Move the error checking for variable-sized objects so we don't
authorEli Friedman <eli.friedman@gmail.com>
Sun, 25 May 2008 13:22:35 +0000 (13:22 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sun, 25 May 2008 13:22:35 +0000 (13:22 +0000)
double-report errors; fixes PR2362.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51555 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaInit.cpp
test/Sema/array-init.c

index 20fa50731d0a3f7b276abe992667f34e9ea49d1d..35dda28d4adfd55bd2befa7e107610149ae42ebe 100644 (file)
@@ -28,22 +28,9 @@ InitListChecker::InitListChecker(Sema *S, InitListExpr *IL, QualType &T) {
 }
 
 int InitListChecker::numArrayElements(QualType DeclType) {
-  int maxElements;
-  if (DeclType->isIncompleteArrayType()) {
-    // FIXME: use a proper constant
-    maxElements = 0x7FFFFFFF;
-  } else if (const VariableArrayType *VAT =
-             DeclType->getAsVariableArrayType()) {
-    // Check for VLAs; in standard C it would be possible to check this
-    // earlier, but I don't know where clang accepts VLAs (gcc accepts
-    // them in all sorts of strange places).
-    SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
-                  diag::err_variable_object_no_init,
-                  VAT->getSizeExpr()->getSourceRange());
-    hadError = true;
-    maxElements = 0x7FFFFFFF;
-  } else {
-    const ConstantArrayType *CAT = DeclType->getAsConstantArrayType();
+  // FIXME: use a proper constant
+  int maxElements = 0x7FFFFFFF;
+  if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {
     maxElements = static_cast<int>(CAT->getSize().getZExtValue());
   }
   return maxElements;
@@ -101,8 +88,10 @@ void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
 
   CheckListElementTypes(IList, T, Index);
   IList->setType(T);
+  if (hadError)
+    return;
 
-  if (!hadError && (Index < IList->getNumInits())) {
+  if (Index < IList->getNumInits()) {
     // We have leftover initializers
     if (IList->getNumInits() > 0 &&
         SemaRef->IsStringLiteralInit(IList->getInit(Index), T)) {
@@ -119,7 +108,7 @@ void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
     }
   }
 
-  if (!hadError && T->isScalarType())
+  if (T->isScalarType())
     SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init, 
                   IList->getSourceRange());
 }
@@ -165,8 +154,7 @@ void InitListChecker::CheckSubElementType(InitListExpr *IList,
   } else if (ElemType->isScalarType()) {
     CheckScalarType(IList, ElemType, Index);
   } else if (expr->getType()->getAsRecordType() &&
-             SemaRef->Context.typesAreCompatible(
-                  IList->getInit(Index)->getType(), ElemType)) {
+             SemaRef->Context.typesAreCompatible(expr->getType(), ElemType)) {
     Index++;
     // FIXME: Add checking
   } else {
@@ -230,6 +218,17 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
       return;
     }
   }
+  if (const VariableArrayType *VAT = DeclType->getAsVariableArrayType()) {
+    // Check for VLAs; in standard C it would be possible to check this
+    // earlier, but I don't know where clang accepts VLAs (gcc accepts
+    // them in all sorts of strange places).
+    SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
+                  diag::err_variable_object_no_init,
+                  VAT->getSizeExpr()->getSourceRange());
+    hadError = true;
+    return;
+  }
+
   int maxElements = numArrayElements(DeclType);
   QualType elementType = DeclType->getAsArrayType()->getElementType();
   int numElements = 0;
index 2ddd2459351e78653ab7f4fbc136b860dcb95551..a7f27b68f86b0ea239ffc19a7f0dd800f43d2aeb 100644 (file)
@@ -208,3 +208,7 @@ struct bittest bittestvar = {1, 2, 3, 4}; //expected-warning{{excess elements in
 int u1 = {}; //expected-warning{{use of GNU empty initializer extension}} expected-error{{scalar initializer cannot be empty}}
 int u2 = {{3}}; //expected-error{{too many braces around scalar initializer}}
 
+// PR2362
+void varArray() {
+  int c[][x] = { 0 }; //expected-error{{variable-sized object may not be initialized}}
+}