aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2012-08-15 07:42:30 +0000
committerHans Wennborg <hans@hanshq.net>2012-08-15 07:42:30 +0000
commit7f397c5d97fc0c11333d939f2c07bc3b230956e2 (patch)
tree4e4bca2af66c7826049fe11f342a58b49de448a4 /lib
parentdece8b325821acaa5b91e97cf03baf610f264e01 (diff)
Check for improper use of 'static' and type qualifiers in array
declarators. They are only allowed for function parameters, and then only on the outermost array type derivation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161934 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/SemaType.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index c45705813e..7b7cc99dff 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -2258,6 +2258,50 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
ASM = ArrayType::Normal;
D.setInvalidType(true);
}
+
+ // C99 6.7.5.2p1: The optional type qualifiers and the keyword static
+ // shall appear only in a declaration of a function parameter with an
+ // array type, ...
+ if (ASM == ArrayType::Static || ATI.TypeQuals) {
+ if (!D.isPrototypeContext()) {
+ S.Diag(DeclType.Loc, diag::err_array_static_outside_prototype) <<
+ (ASM == ArrayType::Static ? "'static'" : "type qualifier");
+ // Remove the 'static' and the type qualifiers.
+ if (ASM == ArrayType::Static)
+ ASM = ArrayType::Normal;
+ ATI.TypeQuals = 0;
+ D.setInvalidType(true);
+ }
+
+ // C99 6.7.5.2p1: ... and then only in the outermost array type
+ // derivation.
+ unsigned x = chunkIndex;
+ while (x != 0) {
+ // Walk outwards along the declarator chunks.
+ x--;
+ const DeclaratorChunk &DC = D.getTypeObject(x);
+ switch (DC.Kind) {
+ case DeclaratorChunk::Paren:
+ continue;
+ case DeclaratorChunk::Array:
+ case DeclaratorChunk::Pointer:
+ case DeclaratorChunk::Reference:
+ case DeclaratorChunk::MemberPointer:
+ S.Diag(DeclType.Loc, diag::err_array_static_not_outermost) <<
+ (ASM == ArrayType::Static ? "'static'" : "type qualifier");
+ if (ASM == ArrayType::Static)
+ ASM = ArrayType::Normal;
+ ATI.TypeQuals = 0;
+ D.setInvalidType(true);
+ break;
+ case DeclaratorChunk::Function:
+ case DeclaratorChunk::BlockPointer:
+ // These are invalid anyway, so just ignore.
+ break;
+ }
+ }
+ }
+
T = S.BuildArrayType(T, ASM, ArraySize, ATI.TypeQuals,
SourceRange(DeclType.Loc, DeclType.EndLoc), Name);
break;