aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-07-31 01:06:09 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-07-31 01:06:09 +0200
commit5fc204f2ec2d3ec038848db3f3bdb9fead782b4c (patch)
tree129c519e457d389e7bf17407183d8e93a28d906a
parent9d3aa4b96b853c82da6940c1fed3a4e5801c5d90 (diff)
parent7cdd65dd26cc523b3ff6d4acfc19488a47be8d7b (diff)
downloadsparse-5fc204f2ec2d3ec038848db3f3bdb9fead782b4c.tar.gz
Merge branch 'array-decl'
-rw-r--r--parse.c53
-rw-r--r--symbol.h2
-rw-r--r--validation/abstract-array-declarator-quals.c21
-rw-r--r--validation/abstract-array-declarator-star.c8
-rw-r--r--validation/abstract-array-declarator.c11
5 files changed, 57 insertions, 38 deletions
diff --git a/parse.c b/parse.c
index b07237ee..5f587ce6 100644
--- a/parse.c
+++ b/parse.c
@@ -171,7 +171,7 @@ static struct symbol_op register_op = {
};
static struct symbol_op static_op = {
- .type = KW_MODIFIER,
+ .type = KW_MODIFIER|KW_STATIC,
.declarator = static_specifier,
};
@@ -678,24 +678,6 @@ static void fn_local_symbol(struct symbol *sym)
add_symbol(function_symbol_list, sym);
}
-static int SENTINEL_ATTR match_idents(struct token *token, ...)
-{
- va_list args;
- struct ident * next;
-
- if (token_type(token) != TOKEN_IDENT)
- return 0;
-
- va_start(args, token);
- do {
- next = va_arg(args, struct ident *);
- } while (next && token->ident != next);
- va_end(args);
-
- return next && token->ident == next;
-}
-
-
struct statement *alloc_statement(struct position pos, int type)
{
struct statement *stmt = __alloc_statement(0);
@@ -1711,29 +1693,26 @@ 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, &__restrict___ident, NULL))
- token = abstract_array_static_declarator(token->next, &has_static);
- token = parse_expression(token, &expr);
+ while (token_type(token) == TOKEN_IDENT) {
+ struct symbol *sym = lookup_keyword(token->ident, NS_TYPEDEF);
+ if (!sym || !(sym->op->type & (KW_STATIC|KW_QUALIFIER)))
+ break;
+ if (has_static && (sym->op->type & KW_STATIC))
+ sparse_error(token->pos, "duplicate array static declarator");
+ has_static |= (sym->op->type & KW_STATIC);
+ token = token->next;
+ }
+ if (match_op(token, '*') && match_op(token->next, ']')) {
+ // FIXME: '[*]' is treated like '[]'
+ token = token->next;
+ } else {
+ token = assignment_expression(token, &expr);
+ }
sym->array_size = expr;
return token;
}
diff --git a/symbol.h b/symbol.h
index 3ec68e2e..8e7a2860 100644
--- a/symbol.h
+++ b/symbol.h
@@ -81,7 +81,7 @@ enum keyword {
KW_BUILTIN = 1 << 4,
KW_ASM = 1 << 5,
KW_MODE = 1 << 6,
- // KW UNUSED = 1 << 7,
+ KW_STATIC = 1 << 7,
// KW UNUSED = 1 << 8,
KW_EXACT = 1 << 9,
};
diff --git a/validation/abstract-array-declarator-quals.c b/validation/abstract-array-declarator-quals.c
new file mode 100644
index 00000000..e69df902
--- /dev/null
+++ b/validation/abstract-array-declarator-quals.c
@@ -0,0 +1,21 @@
+#define N 2
+
+void ok1(int []);
+void ok2(int [N]);
+void ok3(int [const volatile restrict]);
+void ok4(int [const volatile restrict N]);
+void ok5(int [static N]);
+void ok6(int [static const volatile restrict N]);
+void ok7(int [const volatile restrict static N]);
+
+void ok1(int a[]);
+void ok2(int a[N]);
+void ok3(int a[const volatile restrict]);
+void ok4(int a[const volatile restrict N]);
+void ok5(int a[static N]);
+void ok6(int a[static const volatile restrict N]);
+void ok7(int a[const volatile restrict static N]);
+
+/*
+ * check-name: abstract-array-declarator-quals
+ */
diff --git a/validation/abstract-array-declarator-star.c b/validation/abstract-array-declarator-star.c
new file mode 100644
index 00000000..fc42da3a
--- /dev/null
+++ b/validation/abstract-array-declarator-star.c
@@ -0,0 +1,8 @@
+void ok8(int [*]);
+
+void ok8(int a[*]);
+void ok9(int a[const volatile restrict *]);
+
+/*
+ * check-name: abstract-array-declarator-star
+ */
diff --git a/validation/abstract-array-declarator.c b/validation/abstract-array-declarator.c
new file mode 100644
index 00000000..ca182373
--- /dev/null
+++ b/validation/abstract-array-declarator.c
@@ -0,0 +1,11 @@
+void f77(int a[1, 2]);
+void c99(int a[(1, 2)]);
+
+/*
+ * check-name: abstract-array-declarator
+ *
+ * check-error-start
+abstract-array-declarator.c:1:17: error: Expected ] in abstract_array_declarator
+abstract-array-declarator.c:1:17: error: got ,
+ * check-error-end
+ */