mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-18 00:33:03 +00:00
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.
This commit is contained in:
18
ChangeLog
18
ChangeLog
@@ -1,10 +1,24 @@
|
|||||||
|
2006-03-02 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||||
|
|
||||||
|
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 <jdenny@ces.clemson.edu>
|
2006-03-02 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||||
|
|
||||||
Don't leak semantic values for parent RHS when a user action cuts the
|
Don't leak semantic values for parent RHS when a user action cuts the
|
||||||
parser, and clean up related code a bit.
|
parser, and clean up related code a bit.
|
||||||
* tests/glr-regression.at (Leaked merged semantic value if user action
|
* tests/glr-regression.at (Leaked merged semantic value if user action
|
||||||
cuts parse) Rename to...
|
cuts parse): Rename to...
|
||||||
(Leaked semantic values if user action cuts parse) ... this. Add check
|
(Leaked semantic values if user action cuts parse): ... this. Add check
|
||||||
for leaked parent RHS values.
|
for leaked parent RHS values.
|
||||||
* data/glr.c (yydestroyGLRState): In debugging output, distinguish
|
* data/glr.c (yydestroyGLRState): In debugging output, distinguish
|
||||||
between an unresolved state (non-empty chain of semantic options) and
|
between an unresolved state (non-empty chain of semantic options) and
|
||||||
|
|||||||
15
data/glr.c
15
data/glr.c
@@ -1783,12 +1783,9 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1,
|
/*ARGSUSED*/ static YYRESULTTAG
|
||||||
yyGLRStack* yystackp]b4_pure_formals[)
|
yyreportAmbiguity (yySemanticOption* yyx0,
|
||||||
__attribute__ ((__noreturn__));
|
yySemanticOption* yyx1]b4_pure_formals[)
|
||||||
/*ARGSUSED*/ static void
|
|
||||||
yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1,
|
|
||||||
yyGLRStack* yystackp]b4_pure_formals[)
|
|
||||||
{
|
{
|
||||||
YYUSE (yyx0);
|
YYUSE (yyx0);
|
||||||
YYUSE (yyx1);
|
YYUSE (yyx1);
|
||||||
@@ -1801,7 +1798,9 @@ yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1,
|
|||||||
yyreportTree (yyx1, 2);
|
yyreportTree (yyx1, 2);
|
||||||
YYFPRINTF (stderr, "\n");
|
YYFPRINTF (stderr, "\n");
|
||||||
#endif
|
#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))
|
switch (yypreference (yybest, yyp))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
yyreportAmbiguity (yybest, yyp, yystackp]b4_pure_args[);
|
return yyreportAmbiguity (yybest, yyp]b4_pure_args[);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
yymerge = yytrue;
|
yymerge = yytrue;
|
||||||
|
|||||||
@@ -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
|
[glr-regr10.y: conflicts: 1 reduce/reduce
|
||||||
])
|
])
|
||||||
AT_COMPILE([glr-regr10])
|
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
|
[glr-regr11.y: conflicts: 1 reduce/reduce
|
||||||
])
|
])
|
||||||
AT_COMPILE([glr-regr11])
|
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
|
[glr-regr12.y: conflicts: 1 shift/reduce, 1 reduce/reduce
|
||||||
])
|
])
|
||||||
AT_COMPILE([glr-regr12])
|
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_COMPILE([glr-regr13])
|
||||||
|
|
||||||
AT_CHECK([[./glr-regr13]], 0,
|
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
|
[glr-regr14.y: conflicts: 3 reduce/reduce
|
||||||
])
|
])
|
||||||
AT_COMPILE([glr-regr14])
|
AT_COMPILE([glr-regr14])
|
||||||
@@ -1420,3 +1420,95 @@ start <- merge 'c' stack_explosion:
|
|||||||
], [])
|
], [])
|
||||||
|
|
||||||
AT_CLEANUP
|
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 <dummy> parent_rhs_before
|
||||||
|
%destructor { parent_rhs_before_value = 0; } parent_rhs_before
|
||||||
|
|
||||||
|
%{
|
||||||
|
# include <stdlib.h>
|
||||||
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user