diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2012-04-05 22:47:34 +0000 |
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2012-04-05 22:47:34 +0000 |
| commit | c1f0d5b8736c69557567de86267ff61417d60779 (patch) | |
| tree | 82a01aee56628efe88c1bb5b01bb1b5f1b97c0c8 /clang | |
| parent | 57a75390fcfc4fc7e019817aa4a0b3dc3675827e (diff) | |
| download | bcm5719-llvm-c1f0d5b8736c69557567de86267ff61417d60779.tar.gz bcm5719-llvm-c1f0d5b8736c69557567de86267ff61417d60779.zip | |
Implement C90 pedantic warning for duplicate declaration specifiers which are duplicated via a typedef. Patch by Tim Northover.
llvm-svn: 154136
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 20 | ||||
| -rw-r--r-- | clang/test/Sema/c89.c | 17 |
2 files changed, 37 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 711ff08ce17..c41df82a48b 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/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" @@ -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); } diff --git a/clang/test/Sema/c89.c b/clang/test/Sema/c89.c index 25a10481e92..110d7e13762 100644 --- a/clang/test/Sema/c89.c +++ b/clang/test/Sema/c89.c @@ -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'}} */ |

