From 35ee866a326351fe074945f67f4801fd6b829def Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Thu, 2 Mar 2006 06:18:09 +0000 Subject: [PATCH] Avoid memory leaks by not invoking longjmp in yyreportAmbiguity. * tests/glr-regression.at (Leaked semantic values when reporting ambiguity): New test case. * data/glr.c (yyreportAmbiguity): Invoke yyyerror directly and return yyabort rather than invoking yyFail, which invokes longjmp. Remove the now unnecessary yystackp parameter. (yyresolveValue): Return yyreportAmbiguity's result. Now the necessary destructors can be called. * tests/glr-regression.at: Don't invoke bison with `-t' unnecessarily in existing testcases. --- ChangeLog | 18 ++++++- data/glr.c | 15 +++--- tests/glr-regression.at | 102 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 120 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index dfdd7df8..b3413819 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,24 @@ +2006-03-02 Joel E. Denny + + Avoid memory leaks by not invoking longjmp in yyreportAmbiguity. + * tests/glr-regression.at (Leaked semantic values when reporting + ambiguity): New test case. + * data/glr.c (yyreportAmbiguity): Invoke yyyerror directly and return + yyabort rather than invoking yyFail, which invokes longjmp. Remove the + now unnecessary yystackp parameter. + (yyresolveValue): Return yyreportAmbiguity's result. Now the necessary + destructors can be called. + + * tests/glr-regression.at: Don't invoke bison with `-t' unnecessarily + in existing testcases. + 2006-03-02 Joel E. Denny Don't leak semantic values for parent RHS when a user action cuts the parser, and clean up related code a bit. * tests/glr-regression.at (Leaked merged semantic value if user action - cuts parse) Rename to... - (Leaked semantic values if user action cuts parse) ... this. Add check + cuts parse): Rename to... + (Leaked semantic values if user action cuts parse): ... this. Add check for leaked parent RHS values. * data/glr.c (yydestroyGLRState): In debugging output, distinguish between an unresolved state (non-empty chain of semantic options) and diff --git a/data/glr.c b/data/glr.c index 4a8fe983..aab6779c 100644 --- a/data/glr.c +++ b/data/glr.c @@ -1783,12 +1783,9 @@ yyreportTree (yySemanticOption* yyx, int yyindent) } #endif -static void yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1, - yyGLRStack* yystackp]b4_pure_formals[) - __attribute__ ((__noreturn__)); -/*ARGSUSED*/ static void -yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1, - yyGLRStack* yystackp]b4_pure_formals[) +/*ARGSUSED*/ static YYRESULTTAG +yyreportAmbiguity (yySemanticOption* yyx0, + yySemanticOption* yyx1]b4_pure_formals[) { YYUSE (yyx0); YYUSE (yyx1); @@ -1801,7 +1798,9 @@ yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1, yyreportTree (yyx1, 2); YYFPRINTF (stderr, "\n"); #endif - yyFail (yystackp][]b4_pure_args[, YY_("syntax is ambiguous")); + + yyerror (]b4_yyerror_args[YY_("syntax is ambiguous")); + return yyabort; } @@ -1838,7 +1837,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[) switch (yypreference (yybest, yyp)) { case 0: - yyreportAmbiguity (yybest, yyp, yystackp]b4_pure_args[); + return yyreportAmbiguity (yybest, yyp]b4_pure_args[); break; case 1: yymerge = yytrue; diff --git a/tests/glr-regression.at b/tests/glr-regression.at index 823d9451..54c02f56 100644 --- a/tests/glr-regression.at +++ b/tests/glr-regression.at @@ -864,7 +864,7 @@ main (void) } ]]) -AT_CHECK([[bison -t -o glr-regr10.c glr-regr10.y]], 0, [], +AT_CHECK([[bison -o glr-regr10.c glr-regr10.y]], 0, [], [glr-regr10.y: conflicts: 1 reduce/reduce ]) AT_COMPILE([glr-regr10]) @@ -930,7 +930,7 @@ main (void) } ]]) -AT_CHECK([[bison -t -o glr-regr11.c glr-regr11.y]], 0, [], +AT_CHECK([[bison -o glr-regr11.c glr-regr11.y]], 0, [], [glr-regr11.y: conflicts: 1 reduce/reduce ]) AT_COMPILE([glr-regr11]) @@ -1059,7 +1059,7 @@ main (void) } ]]) -AT_CHECK([[bison -t -o glr-regr12.c glr-regr12.y]], 0, [], +AT_CHECK([[bison -o glr-regr12.c glr-regr12.y]], 0, [], [glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce ]) AT_COMPILE([glr-regr12]) @@ -1186,7 +1186,7 @@ main (void) } ]]) -AT_CHECK([[bison -t -o glr-regr13.c glr-regr13.y]], 0, [], []) +AT_CHECK([[bison -o glr-regr13.c glr-regr13.y]], 0, [], []) AT_COMPILE([glr-regr13]) AT_CHECK([[./glr-regr13]], 0, @@ -1399,7 +1399,7 @@ main (void) } ]]) -AT_CHECK([[bison -t -o glr-regr14.c glr-regr14.y]], 0, [], +AT_CHECK([[bison -o glr-regr14.c glr-regr14.y]], 0, [], [glr-regr14.y: conflicts: 3 reduce/reduce ]) AT_COMPILE([glr-regr14]) @@ -1420,3 +1420,95 @@ start <- merge 'c' stack_explosion: ], []) AT_CLEANUP + + +## ------------------------------------------------------------------------- ## +## Leaked semantic values when reporting ambiguity. ## +## ------------------------------------------------------------------------- ## + +AT_SETUP([Leaked semantic values when reporting ambiguity]) + +AT_DATA_GRAMMAR([glr-regr15.y], +[[ +%glr-parser +%union { int dummy; } +%type parent_rhs_before +%destructor { parent_rhs_before_value = 0; } parent_rhs_before + +%{ +# include + static void yyerror (char const *); + static int yylex (void); + static int parent_rhs_before_value = 0; +# define USE(val) +%} + +%% + +start: + alt1 %dprec 1 + | alt2 %dprec 2 + ; + +/* This stack must be merged into the other stacks *last* (added at the + beginning of the semantic options list) so that yyparse will choose to clean + it up rather than the tree for which some semantic actions have been + performed. Thus, if yyreportAmbiguity longjmp's to yyparse, the values from + those other trees are not cleaned up. */ +alt1: ; + +alt2: + parent_rhs_before ambiguity { + USE ($1); + parent_rhs_before_value = 0; + } + ; + +parent_rhs_before: + { + USE ($$); + parent_rhs_before_value = 1; + } + ; + +ambiguity: ambiguity1 | ambiguity2 ; +ambiguity1: ; +ambiguity2: ; + +%% + +static void +yyerror (char const *msg) +{ + fprintf (stderr, "%s\n", msg); +} + +static int +yylex (void) +{ + return 0; +} + +int +main (void) +{ + int exit_status = yyparse () != 1; + if (parent_rhs_before_value) + { + fprintf (stderr, "`parent_rhs_before' destructor not called.\n"); + exit_status = 1; + } + return exit_status; +} +]]) + +AT_CHECK([[bison -o glr-regr15.c glr-regr15.y]], 0, [], +[glr-regr15.y: conflicts: 2 reduce/reduce +]) +AT_COMPILE([glr-regr15]) + +AT_CHECK([[./glr-regr15]], 0, [], +[syntax is ambiguous +]) + +AT_CLEANUP -- 2.45.2