X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/1ef30936f5fdb253b397347b91521455d0c39172..00514ec7f1070550a52651971bb6a5e36efbe4f0:/src/parse-decl.c diff --git a/src/parse-decl.c b/src/parse-decl.c index 8516a3a..8f0bd38 100644 --- a/src/parse-decl.c +++ b/src/parse-decl.c @@ -73,9 +73,10 @@ struct parse_item *cdecl__alloc_item(size_t s_sz) */ static int valid_typespec(struct cdecl_declspec *s) { + struct cdecl_declspec *c; unsigned long map = 0; - for (struct cdecl_declspec *c = s; c; c = c->next) { + for (c = s; c; c = c->next) { unsigned long bit; if (cdecl_spec_kind(c) != CDECL_SPEC_TYPE) @@ -117,7 +118,7 @@ static int valid_typespec(struct cdecl_declspec *s) */ static bool valid_declspecs(struct cdecl *decl, bool top) { - struct cdecl_declspec *specs = decl->specifiers; + struct cdecl_declspec *c, *specs = decl->specifiers; struct cdecl_declarator *d = decl->declarators; bool abstract = cdecl_is_abstract(d); unsigned num_storage = 0; @@ -125,7 +126,7 @@ static bool valid_declspecs(struct cdecl *decl, bool top) if (!valid_typespec(specs)) return false; - for (struct cdecl_declspec *c = specs; c; c = c->next) { + for (c = specs; c; c = c->next) { switch (cdecl_spec_kind(c)) { case CDECL_SPEC_TYPE: if (c->type == CDECL_TYPE_VOID && @@ -220,7 +221,6 @@ static struct cdecl_declarator *reduce_function(struct cdecl *param) spec->u.declarator.type = CDECL_DECL_IDENT; *p = &spec->u.declarator; - free(d); d = param->declarators; free(param); return d; @@ -262,7 +262,6 @@ simplify_functions(struct cdecl_declarator **p, struct cdecl_declarator *d) if (!new) return 0; /* e.g. int (foo bar) */ *p = new; - free(d->child); free(d); return 1; @@ -502,9 +501,9 @@ static int forall_declarators(struct cdecl *decl, static struct cdecl *do_parse(const char *str, int english_mode) { + struct cdecl *decl = NULL; YY_BUFFER_STATE state; yyscan_t scanner; - struct cdecl *decl; #if YYDEBUG extern int cdecl__yydebug; @@ -516,8 +515,15 @@ static struct cdecl *do_parse(const char *str, int english_mode) return NULL; state = cdecl__yy_scan_string(str, scanner); - if (cdecl__yyparse(scanner, &decl) != 0) + if (cdecl__yyparse(scanner, &decl) != 0) { + /* + * If the input consists of a complete, valid declaration + * followed by some garbage, that parsed declaration will + * be output by the parser and we need to free it here. + */ + cdecl__free(decl); decl = NULL; + } cdecl__yy_delete_buffer(state, scanner); cdecl__yylex_destroy(scanner);