]> granicus.if.org Git - clang/commitdiff
Implement C90 pedantic warning for duplicate declaration specifiers which are duplica...
authorEli Friedman <eli.friedman@gmail.com>
Thu, 5 Apr 2012 22:47:34 +0000 (22:47 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Thu, 5 Apr 2012 22:47:34 +0000 (22:47 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154136 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaType.cpp
test/Sema/c89.c

index 711ff08ce17d4b54900d0139aa164d0bd569f518..c41df82a48b59449ccaae6fb2b186b69f6bdd463 100644 (file)
@@ -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"
@@ -979,6 +980,25 @@ 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 
+        && 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";
+      }
+
+      // C90 doesn't have restrict, so it doesn't force us to produce a warning
+      // in this case.
+    }
+
     Qualifiers Quals = Qualifiers::fromCVRMask(TypeQuals);
     Result = Context.getQualifiedType(Result, Quals);
   }
index 25a10481e9234d140f342afa63295f8fceec0cfa..110d7e137621f2ef1edf203ca4b1e7a0ec3508e8 100644 (file)
@@ -92,4 +92,21 @@ 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;
+
+typedef const int CI;
+
+const CI mine1[5][5]; /* expected-warning {{duplicate 'const' declaration specifier}} */
+
+typedef CI array_of_CI[5];
+const array_of_CI mine2; /* expected-warning {{duplicate 'const' declaration specifier}} */
+
+typedef CI *array_of_pointer_to_CI[5];
+const array_of_pointer_to_CI mine3;
+
 void main() {} /* expected-error {{'main' must return 'int'}} */