Split out incomplete arrays from VariableArrayType into 
IncompleteArrayType.  This should make code dealing with both incomplete 
and variable length arrays much more readable, plus it allows properly 
making the distinction between isVariableArrayType() and 
isVariablyModifiedType().  The patch is a little big, but it's 
strightforward. so I don't think there should be any issues.




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47165 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 2358bdf..81d4c9e 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -412,13 +412,13 @@
 }
 
 bool Sema::CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT) {
-  if (const VariableArrayType *VAT = DeclT->getAsIncompleteArrayType()) {
+  if (const IncompleteArrayType *IAT = DeclT->getAsIncompleteArrayType()) {
     // C99 6.7.8p14. We have an array of character type with unknown size 
     // being initialized to a string literal.
     llvm::APSInt ConstVal(32);
     ConstVal = strLiteral->getByteLength() + 1;
     // Return a new array type (C99 6.7.8p22).
-    DeclT = Context.getConstantArrayType(VAT->getElementType(), ConstVal, 
+    DeclT = Context.getConstantArrayType(IAT->getElementType(), ConstVal, 
                                          ArrayType::Normal, 0);
   } else if (const ConstantArrayType *CAT = DeclT->getAsConstantArrayType()) {
     // C99 6.7.8p14. We have an array of character type with known size.
@@ -564,17 +564,18 @@
         }
       }
       int maxElements;
-      if (const VariableArrayType *VAT = DeclType->getAsVariableArrayType()) {
+      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).
-        if (const Expr *expr = VAT->getSizeExpr()) {
-          Diag(expr->getLocStart(), diag::err_variable_object_no_init,
-               expr->getSourceRange());
-          hadError = true;
-        }
+        Diag(VAT->getSizeExpr()->getLocStart(),
+             diag::err_variable_object_no_init,
+             VAT->getSizeExpr()->getSourceRange());
+        hadError = true;
+        maxElements = 0x7FFFFFFF;
       } else {
         const ConstantArrayType *CAT = DeclType->getAsConstantArrayType();
         maxElements = static_cast<int>(CAT->getSize().getZExtValue());
@@ -638,7 +639,7 @@
 bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType) {  
   // 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->getAsVariablyModifiedType())
+  if (const VariableArrayType *VAT = DeclType->getAsVariableArrayType())
     return Diag(VAT->getSizeExpr()->getLocStart(), 
                 diag::err_variable_object_no_init, 
                 VAT->getSizeExpr()->getSourceRange());
@@ -897,10 +898,8 @@
     // static storage duration, it shall not have a variable length array.
     if ((FVD || BVD) && IDecl->getStorageClass() == VarDecl::Static) {
       if (const VariableArrayType *VLA = T->getAsVariableArrayType()) {
-        if (VLA->getSizeExpr()) {  
-          Diag(IDecl->getLocation(), diag::err_typecheck_illegal_vla);
-          IDecl->setInvalidDecl();
-        }
+        Diag(IDecl->getLocation(), diag::err_typecheck_illegal_vla);
+        IDecl->setInvalidDecl();
       }
     }
     // Block scope. C99 6.7p7: If an identifier for an object is declared with
diff --git a/Sema/SemaType.cpp b/Sema/SemaType.cpp
index 5ba2586..58d7019 100644
--- a/Sema/SemaType.cpp
+++ b/Sema/SemaType.cpp
@@ -231,9 +231,11 @@
       }
       llvm::APSInt ConstVal(32);
       // If no expression was provided, we consider it a VLA.
-      if (!ArraySize || !ArraySize->isIntegerConstantExpr(ConstVal, Context))
+      if (!ArraySize) {
+        T = Context.getIncompleteArrayType(T, ASM, ATI.TypeQuals);
+      } else if (!ArraySize->isIntegerConstantExpr(ConstVal, Context)) {
         T = Context.getVariableArrayType(T, ArraySize, ASM, ATI.TypeQuals);
-      else {
+      } else {
         // C99 6.7.5.2p1: If the expression is a constant expression, it shall
         // have a value greater than zero.
         if (ConstVal.isSigned()) {