nickdesaulniers updated this revision to Diff 167843.
nickdesaulniers marked 2 inline comments as done.
nickdesaulniers added a comment.

- add back test for typedef typedef
- add test for dupl _Atomic and restrict


Repository:
  rC Clang

https://reviews.llvm.org/D52248

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaType.cpp
  test/FixIt/fixit-eof-space.c
  test/FixIt/fixit.c
  test/Parser/atomic.c
  test/Sema/declspec.c
  test/Sema/dupl-declspec.c

Index: test/Sema/dupl-declspec.c
===================================================================
--- /dev/null
+++ test/Sema/dupl-declspec.c
@@ -0,0 +1,242 @@
+/*
+RUN: not %clang_cc1 %s -std=c89 -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-C89 %s
+RUN: not %clang_cc1 %s -std=c89 -pedantic -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-C89-PEDANTIC %s
+RUN: not %clang_cc1 %s -std=c99 -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-C99 %s
+RUN: not %clang_cc1 %s -std=c99 -pedantic -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-C99-PEDANTIC %s
+RUN: not %clang_cc1 %s -std=c11 -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-C11 %s
+RUN: not %clang_cc1 %s -std=c11 -pedantic -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-C11-PEDANTIC %s
+RUN: not %clang_cc1 %s -std=c17 -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-C17 %s
+RUN: not %clang_cc1 %s -std=c17 -pedantic -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-C17-PEDANTIC %s
+
+RUN: not %clang_cc1 %s -std=gnu89 -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-GNU89 -allow-empty %s
+RUN: not %clang_cc1 %s -std=gnu89 -pedantic -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-GNU89-PEDANTIC %s
+RUN: %clang_cc1 %s -std=gnu99 -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-GNU99 -allow-empty %s
+RUN: %clang_cc1 %s -std=gnu99 -pedantic -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-GNU99-PEDANTIC %s
+RUN: %clang_cc1 %s -std=gnu11 -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-GNU11 -allow-empty %s
+RUN: %clang_cc1 %s -std=gnu11 -pedantic -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-GNU11-PEDANTIC %s
+RUN: %clang_cc1 %s -std=gnu17 -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-GNU17 -allow-empty %s
+RUN: %clang_cc1 %s -std=gnu17 -pedantic -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-GNU17-PEDANTIC %s
+*/
+
+const const int pr8264_1;
+/*
+CHECK-C89-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-C89-PEDANTIC: 21:7: warning: duplicate 'const' declaration specifier
+          ^ NOTE: special case
+CHECK-C99-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-C99-PEDANTIC-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-C11-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-C11-PEDANTIC-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-C17-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-C17-PEDANTIC-NOT: 21:7: warning: duplicate 'const' declaration specifier
+
+CHECK-GNU89-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-GNU89-PEDANTIC: 21:7: warning: duplicate 'const' declaration specifier
+            ^ NOTE: special case
+CHECK-GNU99-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-GNU99-PEDANTIC-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-GNU11-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-GNU11-PEDANTIC-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-GNU17-NOT: 21:7: warning: duplicate 'const' declaration specifier
+CHECK-GNU17-PEDANTIC-NOT: 21:7: warning: duplicate 'const' declaration specifier
+*/
+
+typedef const int t;
+const t c_i;
+/*
+CHECK-C89-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-C89-PEDANTIC: 45:1: warning: duplicate 'const' declaration specifier
+          ^ NOTE: special case
+CHECK-C99-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-C99-PEDANTIC-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-C11-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-C11-PEDANTIC-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-C17-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-C17-PEDANTIC-NOT: 45:1: warning: duplicate 'const' declaration specifier
+
+CHECK-GNU89-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU89-PEDANTIC: 45:1: warning: duplicate 'const' declaration specifier
+            ^ NOTE: special case
+CHECK-GNU99-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU99-PEDANTIC-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU11-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU11-PEDANTIC-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU17-NOT: 45:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU17-PEDANTIC-NOT: 45:1: warning: duplicate 'const' declaration specifier
+*/
+
+const int c_i2;
+const typeof(pr8264_1) c_i4;
+/*
+CHECK-C89-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-C89-PEDANTIC-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-C99-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-C99-PEDANTIC-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-C11-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-C11-PEDANTIC-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-C17-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-C17-PEDANTIC-NOT: 69:1: warning: duplicate 'const' declaration specifier
+
+CHECK-GNU89-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU89-PEDANTIC: 69:1: warning: duplicate 'const' declaration specifier
+            ^ NOTE: special case
+CHECK-GNU99-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU99-PEDANTIC-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU11-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU11-PEDANTIC-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU17-NOT: 69:1: warning: duplicate 'const' declaration specifier
+CHECK-GNU17-PEDANTIC-NOT: 69:1: warning: duplicate 'const' declaration specifier
+*/
+
+volatile volatile int pr8264_2;
+/*
+CHECK-C89-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-C89-PEDANTIC: 91:10: warning: duplicate 'volatile' declaration specifier
+          ^ NOTE: special case
+CHECK-C99-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-C99-PEDANTIC-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-C11-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-C11-PEDANTIC-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-C17-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-C17-PEDANTIC-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+
+CHECK-GNU89-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-GNU89-PEDANTIC: 91:10: warning: duplicate 'volatile' declaration specifier
+            ^ NOTE: special case
+CHECK-GNU99-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-GNU99-PEDANTIC-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-GNU11-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-GNU11-PEDANTIC-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-GNU17-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+CHECK-GNU17-PEDANTIC-NOT: 91:10: warning: duplicate 'volatile' declaration specifier
+*/
+
+extern extern int pr8264_3;
+/*
+CHECK-C89: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-C89-PEDANTIC: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-C99: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-C99-PEDANTIC: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-C11: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-C11-PEDANTIC: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-C17: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-C17-PEDANTIC: 114:8: warning: duplicate 'extern' declaration specifier
+
+CHECK-GNU89: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-GNU89-PEDANTIC: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-GNU99: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-GNU99-PEDANTIC: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-GNU11: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-GNU11-PEDANTIC: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-GNU17: 114:8: warning: duplicate 'extern' declaration specifier
+CHECK-GNU17-PEDANTIC: 114:8: warning: duplicate 'extern' declaration specifier
+*/
+
+void pr8264_4() {
+  register register int x;
+}
+/*
+CHECK-C89: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-C89-PEDANTIC: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-C99: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-C99-PEDANTIC: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-C11: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-C11-PEDANTIC: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-C17: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-C17-PEDANTIC: 136:12: warning: duplicate 'register' declaration specifier
+
+CHECK-GNU89: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-GNU89-PEDANTIC: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-GNU99: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-GNU99-PEDANTIC: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-GNU11: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-GNU11-PEDANTIC: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-GNU17: 136:12: warning: duplicate 'register' declaration specifier
+CHECK-GNU17-PEDANTIC: 136:12: warning: duplicate 'register' declaration specifier
+*/
+
+inline inline void pr8264_5() {}
+/*
+CHECK-C89-NOT: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-C89-PEDANTIC-NOT: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-C99: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-C99-PEDANTIC: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-C11: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-C11-PEDANTIC: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-C17: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-C17-PEDANTIC: 158:8: warning: duplicate 'inline' declaration specifier
+
+CHECK-GNU89: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-GNU89-PEDANTIC: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-GNU99: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-GNU99-PEDANTIC: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-GNU11: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-GNU11-PEDANTIC: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-GNU17: 158:8: warning: duplicate 'inline' declaration specifier
+CHECK-GNU17-PEDANTIC: 158:8: warning: duplicate 'inline' declaration specifier
+*/
+
+_Noreturn _Noreturn void pr8264_6() {}
+/*
+CHECK-C89: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-C89-PEDANTIC: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-C99: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-C99-PEDANTIC: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-C11: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-C11-PEDANTIC: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-C17: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-C17-PEDANTIC: 179:11: warning: duplicate '_Noreturn' declaration specifier
+
+CHECK-GNU89: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-GNU89-PEDANTIC: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-GNU99: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-GNU99-PEDANTIC: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-GNU11: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-GNU11-PEDANTIC: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-GNU17: 179:11: warning: duplicate '_Noreturn' declaration specifier
+CHECK-GNU17-PEDANTIC: 179:11: warning: duplicate '_Noreturn' declaration specifier
+*/
+
+typedef _Atomic _Atomic _Atomic(int) atomic_int;
+/*
+CHECK-C89-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-C89-PEDANTIC: 200:17: warning: duplicate '_Atomic' declaration specifier
+          ^ NOTE: special case
+CHECK-C99-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-C99-PEDANTIC-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-C11-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-C11-PEDANTIC-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-C17-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-C17-PEDANTIC-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+
+CHECK-GNU89-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-GNU89-PEDANTIC: 200:17: warning: duplicate '_Atomic' declaration specifier
+            ^ NOTE: special case
+CHECK-GNU99-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-GNU99-PEDANTIC-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-GNU11-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-GNU11-PEDANTIC-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-GNU17-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+CHECK-GNU17-PEDANTIC-NOT: 200:17: warning: duplicate '_Atomic' declaration specifier
+*/
+
+char * restrict restrict pr8264_7;
+/*
+CHECK-C89-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-C89-PEDANTIC-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-C99-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-C99-PEDANTIC-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-C11-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-C11-PEDANTIC-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-C17-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-C17-PEDANTIC-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+
+CHECK-GNU89-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-GNU89-PEDANTIC-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-GNU99-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-GNU99-PEDANTIC-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-GNU11-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-GNU11-PEDANTIC-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-GNU17-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+CHECK-GNU17-PEDANTIC-NOT: 223:17: warning: duplicate 'restrict' declaration specifier
+*/
Index: test/Sema/declspec.c
===================================================================
--- test/Sema/declspec.c
+++ test/Sema/declspec.c
@@ -36,16 +36,3 @@
 struct test3s {
 } // expected-error {{expected ';' after struct}}
 typedef int test3g;
-
-// PR8264
-const const int pr8264_1 = 0;  // expected-warning {{duplicate 'const' declaration specifier}}
-volatile volatile int pr8264_2;  // expected-warning {{duplicate 'volatile' declaration specifier}}
-char * restrict restrict pr8264_3;  // expected-warning {{duplicate 'restrict' declaration specifier}}
-
-extern extern int pr8264_4;  // expected-warning {{duplicate 'extern' declaration specifier}}
-void pr8264_5() {
-  register register int x;  // expected-warning {{duplicate 'register' declaration specifier}}
-}
-
-inline inline void pr8264_6() {}  // expected-warning {{duplicate 'inline' declaration specifier}}
-_Noreturn _Noreturn void pr8264_7();  // expected-warning {{duplicate '_Noreturn' declaration specifier}}
Index: test/Parser/atomic.c
===================================================================
--- test/Parser/atomic.c
+++ test/Parser/atomic.c
@@ -2,7 +2,6 @@
 
 typedef _Atomic(int) atomic_int;
 typedef _Atomic int atomic_int;
-typedef _Atomic _Atomic _Atomic(int) atomic_int; // expected-warning {{duplicate '_Atomic' declaration specifier}}
 
 typedef const int const_int;
 
Index: test/FixIt/fixit.c
===================================================================
--- test/FixIt/fixit.c
+++ test/FixIt/fixit.c
@@ -46,16 +46,16 @@
   return x;
 }
 
-// CHECK: const typedef int int_t;
-const typedef typedef int int_t; // expected-warning {{duplicate 'typedef'}}
-
 // <rdar://problem/7159693>
 enum Color { 
   Red // expected-error{{missing ',' between enumerators}}
   Green = 17 // expected-error{{missing ',' between enumerators}}
   Blue,
 };
 
+// CHECK: const typedef int int_t;
+const typedef typedef int int_t; // expected-warning {{duplicate 'typedef'}}
+
 // rdar://9295072
 struct test_struct {
   // CHECK: struct test_struct *struct_ptr;
Index: test/FixIt/fixit-eof-space.c
===================================================================
--- test/FixIt/fixit-eof-space.c
+++ test/FixIt/fixit-eof-space.c
@@ -1,9 +1,9 @@
-// RUN: not %clang_cc1 %s -fsyntax-only -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 %s -fsyntax-only -fdiagnostics-parseable-fixits -std=c90 -pedantic 2>&1 | FileCheck %s
 // vim: set binary noeol:
 
 // This file intentionally ends without a \n on the last line.  Make sure your
 // editor doesn't add one. The trailing space is also intentional.
 
 // CHECK: :9:8: warning: duplicate 'extern' declaration specifier
 // CHECK: fix-it:"{{.*}}":{9:8-9:15}:""
 extern extern 
\ No newline at end of file
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -1679,8 +1679,12 @@
     // C90 6.5.3 constraints: "The same type qualifier shall not appear more
     // than once in the same specifier-list or qualifier-list, either directly
     // or via one or more typedefs."
-    if (!S.getLangOpts().C99 && !S.getLangOpts().CPlusPlus
-        && TypeQuals & Result.getCVRQualifiers()) {
+    //
+    // C90 and GNU89 do not warn if the TST is from a typedef unless -pedantic
+    // was set. GNU89 additionally does not warn if the TST is from a typeof
+    // expression unless -pedantic was set.
+    if (!S.getLangOpts().C99 && !S.getLangOpts().CPlusPlus &&
+        TypeQuals & Result.getCVRQualifiers()) {
       if (TypeQuals & DeclSpec::TQ_const && Result.isConstQualified()) {
         S.Diag(DS.getConstSpecLoc(), diag::ext_duplicate_declspec)
           << "const";
Index: lib/Sema/DeclSpec.cpp
===================================================================
--- lib/Sema/DeclSpec.cpp
+++ lib/Sema/DeclSpec.cpp
@@ -438,8 +438,8 @@
   if (TNew != TPrev)
     DiagID = diag::err_invalid_decl_spec_combination;
   else
-    DiagID = IsExtension ? diag::ext_duplicate_declspec :
-                           diag::warn_duplicate_declspec;
+    DiagID = IsExtension ? diag::ext_duplicate_declspec
+                         : diag::extwarn_duplicate_declspec;
   return true;
 }
 
@@ -608,7 +608,8 @@
         !(SCS_extern_in_linkage_spec &&
           StorageClassSpec == SCS_extern &&
           SC == SCS_typedef))
-      return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);
+      return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID,
+                          /*IsExtension=*/false);
   }
   StorageClassSpec = SC;
   StorageClassSpecLoc = Loc;
@@ -850,14 +851,11 @@
 
 bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
                            unsigned &DiagID, const LangOptions &Lang) {
-  // Duplicates are permitted in C99 onwards, but are not permitted in C89 or
-  // C++.  However, since this is likely not what the user intended, we will
-  // always warn.  We do not need to set the qualifier's location since we
-  // already have it.
-  if (TypeQualifiers & T) {
-    bool IsExtension = true;
-    if (Lang.C99)
-      IsExtension = false;
+  // Duplicates are permitted in C99 onwards, but are not permitted in C++.  In
+  // C90, they are a warning if -pedantic.  We do not need to set the
+  // qualifier's location since we already have it.
+  if (TypeQualifiers & T && !Lang.C99) {
+    bool IsExtension = !Lang.CPlusPlus;
     return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);
   }
   TypeQualifiers |= T;
@@ -967,7 +965,7 @@
                                     unsigned &DiagID) {
   if (isModulePrivateSpecified()) {
     PrevSpec = "__module_private__";
-    DiagID = diag::ext_duplicate_declspec;
+    DiagID = diag::extwarn_duplicate_declspec;
     return true;
   }
 
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -3838,7 +3838,8 @@
       assert(PrevSpec && "Method did not return previous specifier!");
       assert(DiagID);
 
-      if (DiagID == diag::ext_duplicate_declspec)
+      if (DiagID == diag::ext_duplicate_declspec ||
+          DiagID == diag::extwarn_duplicate_declspec)
         Diag(Tok, DiagID)
           << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
       else if (DiagID == diag::err_opencl_unknown_type_specifier) {
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -192,7 +192,9 @@
   "flexible array initialization is a GNU extension">, InGroup<GNUFlexibleArrayInitializer>;
 
 // Declarations.
-def ext_duplicate_declspec : ExtWarn<"duplicate '%0' declaration specifier">,
+def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">,
+  InGroup<DuplicateDeclSpecifier>;
+def extwarn_duplicate_declspec : ExtWarn<"duplicate '%0' declaration specifier">,
   InGroup<DuplicateDeclSpecifier>;
 def warn_duplicate_declspec : Warning<"duplicate '%0' declaration specifier">,
   InGroup<DuplicateDeclSpecifier>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to