]> granicus.if.org Git - clang/commitdiff
Splitting the duplicated decl spec extension warning into two: one is an ExtWarn...
authorAaron Ballman <aaron@aaronballman.com>
Tue, 28 Aug 2012 20:55:40 +0000 (20:55 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Tue, 28 Aug 2012 20:55:40 +0000 (20:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162793 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticParseKinds.td
lib/Sema/DeclSpec.cpp
test/Misc/warning-flags.c
test/Parser/cxx-decl.cpp
test/Parser/cxx0x-decl.cpp

index 4ce43e0d62f743725f2f35df6e0a31a35c7a4054..5f48cc7e126829033c9b071d3b2530d9059f3421 100644 (file)
@@ -197,6 +197,7 @@ def StringPlusInt : DiagGroup<"string-plus-int">;
 def StrncatSize : DiagGroup<"strncat-size">;
 def TautologicalCompare : DiagGroup<"tautological-compare">;
 def HeaderHygiene : DiagGroup<"header-hygiene">;
+def DuplicateDeclSpecifiers : DiagGroup<"duplicate-decl-specifiers">;
 
 // Preprocessor warnings.
 def : DiagGroup<"builtin-macro-redefined">;
index a9c0a1752c462094c6d9bba3d6abc7cf5bb24e02..feae2d0a5ea00fc477082c42c46df311386c2826 100644 (file)
@@ -43,7 +43,10 @@ def warn_extra_semi_after_mem_fn_def : Warning<
   "extra ';' after member function definition">,
   InGroup<ExtraSemi>, DefaultIgnore;
 
-def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">;
+def ext_duplicate_declspec : ExtWarn<"duplicate '%0' declaration specifier">,
+  InGroup<DuplicateDeclSpecifiers>;
+def warn_duplicate_declspec : Warning<"duplicate '%0' declaration specifier">,
+  InGroup<DuplicateDeclSpecifiers>;
 def ext_plain_complex : ExtWarn<
   "plain '_Complex' requires a type specifier; assuming '_Complex double'">;
 def ext_integer_complex : Extension<
index d12ca78390955995a21af7713fd4ea19e0fda4b7..e8ce9ac01c3eca75ff14907fdea8cb29e0d91d3a 100644 (file)
@@ -325,10 +325,14 @@ unsigned DeclSpec::getParsedSpecifiers() const {
 
 template <class T> static bool BadSpecifier(T TNew, T TPrev,
                                             const char *&PrevSpec,
-                                            unsigned &DiagID) {
+                                            unsigned &DiagID,
+                                            bool IsExtension = true) {
   PrevSpec = DeclSpec::getSpecifierName(TPrev);
-  DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec
-            : diag::err_invalid_decl_spec_combination);
+  if (TNew != TPrev)
+    DiagID = diag::err_invalid_decl_spec_combination;
+  else
+    DiagID = IsExtension ? diag::ext_duplicate_declspec : 
+                           diag::warn_duplicate_declspec;    
   return true;
 }
 
@@ -673,9 +677,15 @@ bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
                            unsigned &DiagID, const LangOptions &Lang,
                            bool IsTypeSpec) {
   // Duplicates are permitted in C99, and are permitted in C++11 unless the
-  // cv-qualifier appears as a type-specifier.
-  if ((TypeQualifiers & T) && !Lang.C99 && (!Lang.CPlusPlus0x || IsTypeSpec))
-    return BadSpecifier(T, T, PrevSpec, DiagID);
+  // cv-qualifier appears as a type-specifier.  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 = false;
+    if (Lang.C99 || (Lang.CPlusPlus0x && !IsTypeSpec))
+      IsExtension = true;
+    return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);
+  }
   TypeQualifiers |= T;
 
   switch (T) {
index 06c70eb57c59c794fada1a4917b3590b73e4ed8e..5968851d09b0f116b5ba72a5f2d95f678e0b1e1d 100644 (file)
@@ -181,4 +181,4 @@ CHECK-NEXT:   warn_weak_import
 
 The list of warnings in -Wpedantic should NEVER grow.
 
-CHECK: Number in -Wpedantic (not covered by other -W flags): 39
+CHECK: Number in -Wpedantic (not covered by other -W flags): 38
index 30ac2794ab548ccc374af67a7fe3e60b5b55fe46..290b947de2b7a4fa47cb576d95c2fd12caf5d9db 100644 (file)
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -pedantic %s
 
+const char const *x10; // expected-warning {{duplicate 'const' declaration specifier}}
+
 int x(*g); // expected-error {{use of undeclared identifier 'g'}}
 
 struct Type {
index a6fc49cb9e9d7bf777032f2afec4a0fdf660b730..e97ba1ec90380a808018188948d71a73c5266e37 100644 (file)
@@ -26,5 +26,7 @@ class ExtraSemiAfterMemFn {
   void i() = delete;;; // expected-warning {{extra ';' after member function definition}}
 };
 
-int *const const p = 0; // ok
+// This is technically okay, but not likely what the user expects, so we will
+// pedantically warn on it
+int *const const p = 0; // expected-warning {{duplicate 'const' declaration specifier}}
 const const int *q = 0; // expected-warning {{duplicate 'const' declaration specifier}}