From 1a419df06c74bc8389316ffbb2cce9d6a2312f63 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Wed, 6 Jul 2011 21:44:12 -0400 Subject: [PATCH] Check specifiers for type names. Type names cannot have storage-class or function specifiers. --- src/parse-decl.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/parse-decl.c b/src/parse-decl.c index c210f7c..dd4bd19 100644 --- a/src/parse-decl.c +++ b/src/parse-decl.c @@ -24,6 +24,18 @@ #include "parse.h" #include "scan.h" +/* + * Determine if a declarator declares an identifier (other than a function + * parameter). + */ +static bool is_abstract(struct cdecl_declarator *d) +{ + while (d->child) + d = d->child; + + return d->type != CDECL_DECL_IDENT; +} + /* * Verify the declaration specifiers of a declaration. If top is true, treat * this as a top-level declaration. Otherwise, treat this as a function @@ -33,6 +45,7 @@ static bool valid_declspecs(struct cdecl *decl, bool top) { struct cdecl_declspec *specs = decl->specifiers; struct cdecl_declarator *d = decl->declarators; + bool abstract = is_abstract(d); unsigned num_storage = 0; unsigned long typemap; @@ -40,6 +53,7 @@ static bool valid_declspecs(struct cdecl *decl, bool top) if (typemap == -1) return -1; + for (struct cdecl_declspec *c = specs; c; c = c->next) { switch (cdecl_spec_kind(c)) { case CDECL_SPEC_TYPE: @@ -51,6 +65,11 @@ static bool valid_declspecs(struct cdecl *decl, bool top) } continue; case CDECL_SPEC_STOR: + if (top && abstract) { + fprintf(stderr, "type names cannot have storage-class specifiers\n"); + return false; + } + if (!top && c->type != CDECL_STOR_REGISTER) { fprintf(stderr, "function parameters may only have register storage\n"); return false; @@ -72,6 +91,11 @@ static bool valid_declspecs(struct cdecl *decl, bool top) } break; case CDECL_SPEC_FUNC: + if (abstract) { + fprintf(stderr, "type names cannot have function specifiers\n"); + return false; + } + if (!top || d->type != CDECL_DECL_FUNCTION) { fprintf(stderr, "only function declarations may have function specifiers.\n"); return false; -- 2.43.2