aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCody P Schafer <cody@linux.vnet.ibm.com>2014-04-15 16:08:57 -0700
committerChristopher Li <sparse@chrisli.org>2014-04-17 16:25:35 -0700
commitf11dd94ea7eaf505d27b313f6e2eb72eeee5d013 (patch)
tree89a44e0e0eb69dad1a1cec4bb4fe0be2c664cc25
parentfe5eda126b9f5315e0049fd174d2326fecea6249 (diff)
downloadsparse-f11dd94ea7eaf505d27b313f6e2eb72eeee5d013.tar.gz
parse: support c99 [static ...] in abstract array declarators
The n1570 specifies (in 6.7.6.2.3) that either type-qualifiers (ie: "restrict") come first and are followed by "static" or the opposite ("static" then type-qualifiers). Also add a test. Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
-rw-r--r--ident-list.h1
-rw-r--r--parse.c18
-rw-r--r--validation/abstract-array-declarator-static.c14
3 files changed, 32 insertions, 1 deletions
diff --git a/ident-list.h b/ident-list.h
index e93aae76..c0fc18fc 100644
--- a/ident-list.h
+++ b/ident-list.h
@@ -91,6 +91,7 @@ IDENT(artificial); IDENT(__artificial__);
IDENT(leaf); IDENT(__leaf__);
IDENT(vector_size); IDENT(__vector_size__);
IDENT(error); IDENT(__error__);
+IDENT(static);
/* Preprocessor idents. Direct use of __IDENT avoids mentioning the keyword
diff --git a/parse.c b/parse.c
index 785630ad..55a57a74 100644
--- a/parse.c
+++ b/parse.c
@@ -1533,12 +1533,28 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta
return token;
}
+static struct token *abstract_array_static_declarator(struct token *token, int *has_static)
+{
+ while (token->ident == &static_ident) {
+ if (*has_static)
+ sparse_error(token->pos, "duplicate array static declarator");
+
+ *has_static = 1;
+ token = token->next;
+ }
+ return token;
+
+}
+
static struct token *abstract_array_declarator(struct token *token, struct symbol *sym)
{
struct expression *expr = NULL;
+ int has_static = 0;
+
+ token = abstract_array_static_declarator(token, &has_static);
if (match_idents(token, &restrict_ident, &__restrict_ident, NULL))
- token = token->next;
+ token = abstract_array_static_declarator(token->next, &has_static);
token = parse_expression(token, &expr);
sym->array_size = expr;
return token;
diff --git a/validation/abstract-array-declarator-static.c b/validation/abstract-array-declarator-static.c
new file mode 100644
index 00000000..92f06bdc
--- /dev/null
+++ b/validation/abstract-array-declarator-static.c
@@ -0,0 +1,14 @@
+
+extern void f1(int g[static 1]);
+extern void f2(int g[static restrict 1]);
+extern void f3(int g[restrict static 1]);
+extern void f4(int g[static restrict static 1]); /* duplicate static error */
+extern void f5(int g[restrict static static 1]); /* duplicate static error */
+
+/*
+ * check-name: abstract array declarator static
+ * check-error-start
+abstract-array-declarator-static.c:5:38: error: duplicate array static declarator
+abstract-array-declarator-static.c:6:38: error: duplicate array static declarator
+ * check-error-end
+ */