From ec207d1bb2fb934b68d6a70c386d4d4c3b00e891 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 28 Jun 2020 10:48:33 +0200 Subject: [PATCH] yacc.c: simplify yypull_parse Currently yypull_parse takes a yypstate* as argument, and accepts it to be NULL. This does not seem to make a lot of sense: rather it is its callers that should do that. I believe this is historical: yypull_parse was introduced first (c3d503425f8014b432601a33b3398446d63b5963), with yyparse being a macro. So yyparse could hardly deal with memory allocation properly. In 7172e23e8ffb95b8cafee24c4f36c46ca709507f that yyparse was turned into a genuine function. At that point, it should have allocated its own yypstate*, which would have left yypull_parse deal with only one single non-null ypstate* argument. Fortunately, it is nowhere documented that it is valid to pass NULL to yypull_parse. It is now forbidden. * data/skeletons/yacc.c (yypull_parse): Don't allocate a yypstate. Needs a location to issue the error message. (yyparse): Allocate the yypstate. --- data/skeletons/yacc.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c index a9c84a33..9e49aa82 100644 --- a/data/skeletons/yacc.c +++ b/data/skeletons/yacc.c @@ -1444,36 +1444,33 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, int yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[) { - return yypull_parse (YY_NULLPTR]b4_user_args[); + yypstate *yyps = yypstate_new (); + if (!yyps) + {]b4_pure_if([b4_locations_if([[ + static YYLTYPE yyloc_default][]b4_yyloc_default[; + YYLTYPE yylloc = yyloc_default;]])[ + yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[ + if (!yypstate_allocated) + yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[ + return 2; + } + int yystatus = yypull_parse (yyps]b4_user_args[); + yypstate_delete (yyps); + return yystatus; } int yypull_parse (yypstate *yyps]b4_user_formals[) -{]b4_pure_if([b4_locations_if([[ +{ + YY_ASSERT (yyps);]b4_pure_if([b4_locations_if([[ static YYLTYPE yyloc_default][]b4_yyloc_default[; YYLTYPE yylloc = yyloc_default;]])])[ - yypstate *yyps_local; - if (yyps) - yyps_local = yyps; - else - { - yyps_local = yypstate_new (); - if (!yyps_local) - {]b4_pure_if([[ - yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[ - if (!yypstate_allocated) - yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[ - return 2; - } - } int yystatus; do { ]b4_pure_if([[ YYSTYPE yylval; int ]])[yychar = ]b4_lex[; - yystatus = yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[); + yystatus = yypush_parse (yyps]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[); } while (yystatus == YYPUSH_MORE); - if (!yyps) - yypstate_delete (yyps_local); return yystatus; }]])[