Hi,

C90 annoyingly requires a diagnostic to be produced for any type that ends up 
with two copies of the same type-qualifier. This warning is already produced 
for cases which can be detected during parsing, but when it happens via a 
typedef Sema needs to be involved.

I believe this patch implements the correct note, though I was uncertain how 
best to test for C90 only compilation: is !C99 && !C++ & !ObjC correct?

Could someone take a look at the patch?

Thanks.

Tim.
commit 520dab07ed90045eb9717b467d72ae1a75d16b8c
Author: Tim Northover <[email protected]>
Date:   Mon Apr 2 12:26:26 2012 +0100

    Diagnose duplicate type-qualifiers in pedantic C90 mode

diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index e83e9ef..744315a 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -26,6 +26,7 @@
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/DelayedDiagnostic.h"
 #include "clang/Sema/Lookup.h"
@@ -973,6 +974,29 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
       TypeQuals &= ~DeclSpec::TQ_volatile;
     }
 
+    // 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 
+        && !S.getLangOpts().ObjC1 && TypeQuals & Result.getCVRQualifiers()) {
+      if (TypeQuals & DeclSpec::TQ_const && Result.isConstQualified()) {
+        S.Diag(DS.getConstSpecLoc(), diag::ext_duplicate_declspec) 
+          << "const";
+      }
+
+      if (TypeQuals & DeclSpec::TQ_volatile && Result.isVolatileQualified()) {
+        S.Diag(DS.getVolatileSpecLoc(), diag::ext_duplicate_declspec) 
+          << "volatile";
+      }
+
+      // Highly unlikely in -pedantic C90 code, but technically the best way to
+      // handle it.
+      if (TypeQuals & DeclSpec::TQ_restrict && Result.isRestrictQualified()) {
+        S.Diag(DS.getRestrictSpecLoc(), diag::ext_duplicate_declspec) 
+          << "restrict";
+      }
+    }
+
     Qualifiers Quals = Qualifiers::fromCVRMask(TypeQuals);
     Result = Context.getQualifiedType(Result, Quals);
   }
diff --git a/test/Sema/c89.c b/test/Sema/c89.c
index 25a1048..82c93d4 100644
--- a/test/Sema/c89.c
+++ b/test/Sema/c89.c
@@ -92,4 +92,11 @@ void test16() {
 
 struct x { int x,y[]; }; /* expected-warning {{Flexible array members are a C99-specific feature}} */
 
+/* Duplicated type-qualifiers aren't allowed by C90 */
+const const int c_i; /* expected-warning {{duplicate 'const' declaration specifier}} */
+typedef volatile int vol_int;
+volatile vol_int volvol_i; /* expected-warning {{duplicate 'volatile' declaration specifier}} */
+typedef volatile vol_int volvol_int; /* expected-warning {{duplicate 'volatile' declaration specifier}} */
+const int * const c;
+
 void main() {} /* expected-error {{'main' must return 'int'}} */
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to