From 96b00735351dd8e39fc5d71ff31afbdddd83ecba Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sun, 23 Jul 2023 15:37:32 -0400 Subject: [PATCH] libcdecl: Don't dynamically allocate null declarators. Since identifiers now come with their own declarator allocations, nothing actually modifies any part of an allocated null declarator. And since null declarators are always the same (with all members zero), we don't even need to allocate them at all. Just use a single static allocation and make every reference to a null declarator point to that. Then we just need to not free null declarators in the various places where that currently happens. --- src/parse-decl.c | 2 -- src/parse.y | 24 ++++++++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/parse-decl.c b/src/parse-decl.c index 8516a3a..a31a377 100644 --- a/src/parse-decl.c +++ b/src/parse-decl.c @@ -220,7 +220,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 +261,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; diff --git a/src/parse.y b/src/parse.y index 8631f3b..ba9bf22 100644 --- a/src/parse.y +++ b/src/parse.y @@ -105,6 +105,7 @@ static void free_declarator(struct cdecl_declarator *x) switch (x->type) { case CDECL_DECL_NULL: + x = NULL; case CDECL_DECL_IDENT: case CDECL_DECL_ARRAY: break; @@ -168,11 +169,18 @@ static struct cdecl *insert_identifier(struct cdecl *decl, struct parse_item *id while ((d = *p)->child) p = &d->child; - free(d); - *p = d = &ident->u.declarator; + *p = &ident->u.declarator; return decl; } + +static struct cdecl_declarator *nulldecl(void) +{ + static const struct cdecl_declarator nulldecl = {0}; + return (void *)&nulldecl; +} +#define NULLDECL (nulldecl()) + %} %destructor { free($$); } @@ -431,16 +439,14 @@ declarator_ish: direct_declarator_ish | pointer postfix: array | parens direct_declarator_ish: { - ALLOC_STRUCT($$, struct cdecl_declarator, - .type = CDECL_DECL_NULL); + $$ = NULLDECL; } | direct_declarator_ish postfix { $$ = $2; $$->child = $1; } direct_declarator: { - ALLOC_STRUCT($$, struct cdecl_declarator, - .type = CDECL_DECL_NULL); + $$ = NULLDECL; } | T_IDENT { $$ = &$1->u.declarator; } | direct_declarator postfix { @@ -491,8 +497,7 @@ english_declaration: storage_func_specs english_declarator post_specs { } english_declarator: { - ALLOC_STRUCT($$, struct cdecl_declarator, - .type = CDECL_DECL_NULL); + $$ = NULLDECL; } | english_declarator qualifiers T_POINTER T_TO { ALLOC_STRUCT($$, struct cdecl_declarator, .type = CDECL_DECL_POINTER, @@ -535,8 +540,7 @@ typedef_name_qual: T_IDENT qualifiers { } null_decl: { - ALLOC_STRUCT($$, struct cdecl_declarator, - .type = CDECL_DECL_NULL); + $$ = NULLDECL; } /* -- 2.43.2