Clean up the C89/C++ warnings about C99 array features to not 
emit duplicate diags (some in parser and some in sema) and to
warn about use of typequals in array sizes.  This implements 
PR2759.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61197 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def
index 38d084f..39464ef 100644
--- a/include/clang/Basic/DiagnosticKinds.def
+++ b/include/clang/Basic/DiagnosticKinds.def
@@ -310,7 +310,7 @@
 DIAG(ext_ident_list_in_param, EXTENSION,
      "type-less parameter names in function declaration")
 DIAG(ext_c99_array_usage, EXTENSION,
-     "use of C99-specific array features")
+     "use of C99-specific array features, accepted as an extension")
 DIAG(ext_c99_variable_decl_in_for_loop, EXTENSION,
      "variable declaration in for loop is a C99-specific feature")
 DIAG(ext_c99_compound_literal, EXTENSION,
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 1a8e5d9..e31b87b 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1283,7 +1283,7 @@
       DS.AddAttributes(ParseAttributes());
       continue; // do *not* consume the next token!
     }
-    
+
     // If the specifier combination wasn't legal, issue a diagnostic.
     if (isInvalid) {
       assert(PrevSpec && "Method did not return previous specifier!");
@@ -1943,6 +1943,7 @@
     StaticLoc = ConsumeToken();
   
   // If there is a type-qualifier-list, read it now.
+  // Type qualifiers in an array subscript are a C99 feature.
   DeclSpec DS;
   ParseTypeQualifierListOpt(DS);
   
@@ -1962,9 +1963,10 @@
   if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
     ConsumeToken();  // Eat the '*'.
 
-    if (StaticLoc.isValid())
+    if (StaticLoc.isValid()) {
       Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
-    StaticLoc = SourceLocation();  // Drop the static.
+      StaticLoc = SourceLocation();  // Drop the static.
+    }
     isStar = true;
   } else if (Tok.isNot(tok::r_square)) {
     // Parse the assignment-expression now.
@@ -1980,15 +1982,6 @@
   
   MatchRHSPunctuation(tok::r_square, StartLoc);
     
-  // If C99 isn't enabled, emit an ext-warn if the arg list wasn't empty and if
-  // it was not a constant expression.
-  if (!getLang().C99) {
-    // TODO: check C90 array constant exprness.
-    if (isStar || StaticLoc.isValid() ||
-        0/*TODO: NumElts is not a C90 constantexpr */)
-      Diag(StartLoc, diag::ext_c99_array_usage);
-  }
-
   // Remember that we parsed a pointer type, and remember the type-quals.
   D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
                                           StaticLoc.isValid(), isStar,
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 3f911f5..a6441c8 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -416,11 +416,13 @@
         T = Context.getConstantArrayType(T, ConstVal, ASM, ATI.TypeQuals);
       }
       // If this is not C99, extwarn about VLA's and C99 array size modifiers.
-      if (!getLangOptions().C99 &&
-          (ASM != ArrayType::Normal ||
-           (ArraySize && !ArraySize->isValueDependent() && 
-            !ArraySize->isIntegerConstantExpr(Context))))
-        Diag(D.getIdentifierLoc(), diag::ext_vla);
+      if (!getLangOptions().C99) {
+        if (ArraySize && !ArraySize->isValueDependent() && 
+            !ArraySize->isIntegerConstantExpr(Context))
+          Diag(D.getIdentifierLoc(), diag::ext_vla);
+        else if (ASM != ArrayType::Normal || ATI.TypeQuals != 0)
+          Diag(D.getIdentifierLoc(), diag::ext_c99_array_usage);
+      }
       break;
     }
     case DeclaratorChunk::Function:
diff --git a/test/Sema/c89.c b/test/Sema/c89.c
index b1780e9..0c7496a 100644
--- a/test/Sema/c89.c
+++ b/test/Sema/c89.c
@@ -60,3 +60,10 @@
 
 void foo(void) {}
 
+/* PR2759 */
+void test10 (int x[*]); /* expected-warning {{use of C99-specific array features}} */
+void test11 (int x[static 4]); /* expected-warning {{use of C99-specific array features}} */
+
+void test12 (int x[const 4]) { /* expected-warning {{use of C99-specific array features}} */
+  int Y[x[1]]; /* expected-warning {{variable length arrays are a C99 feature, accepted as an extension}} */
+}