#include "parse.h"
#include "scan.h"
-static int verify_declspecs(struct cdecl_declspec *s)
+/*
+ * Verify the declaration specifiers of a declaration.
+ */
+static bool valid_declspecs(struct cdecl *decl)
{
+ struct cdecl_declspec *specs = decl->specifiers;
+ struct cdecl_declarator *d = decl->declarators;
unsigned num_storage = 0;
unsigned long typemap;
- typemap = cdecl__build_typemap(s);
+ typemap = cdecl__build_typemap(specs);
if (typemap == -1)
return -1;
- for (struct cdecl_declspec *c = s; c; c = c->next) {
+ for (struct cdecl_declspec *c = specs; c; c = c->next) {
switch (cdecl_spec_kind(c)) {
case CDECL_SPEC_TYPE:
+ if (c->type == CDECL_TYPE_VOID &&
+ (d->type == CDECL_DECL_IDENT
+ || d->type == CDECL_DECL_ARRAY)) {
+ fprintf(stderr, "invalid declaration of type void\n");
+ return false;
+ }
continue;
case CDECL_SPEC_STOR:
if (++num_storage > 1) {
fprintf(stderr, "too many storage-class specifiers\n");
- return -1;
+ return false;
}
break;
case CDECL_SPEC_QUAL:
*/
if (c->type == CDECL_QUAL_RESTRICT) {
fprintf(stderr, "only pointer types can be restrict-qualified.\n");
- return -1;
+ return false;
}
break;
case CDECL_SPEC_FUNC:
* We don't support functions yet.
*/
fprintf(stderr, "only function declarations may have function specifiers.\n");
- return -1;
+ return false;
default:
assert(0);
}
}
- return 0;
+ return true;
}
/*
if (rc != 0)
return NULL;
- if (verify_declspecs(decl->specifiers) != 0)
- goto err;
-
for (struct cdecl *i = decl; i; i = i->next) {
if (!forall_declarators(i, reduce_parentheses))
goto err;
if (!forall_declarators(i, simplify_functions))
goto err;
+
+ if (!valid_declspecs(i))
+ goto err;
}
return decl;