mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
named references: fix double free.
In `rhs[name]: "a" | "b"', do not free "name" twice. Reported by Tys Lefering. <http://lists.gnu.org/archive/html/bug-bison/2010-06/msg00002.html> * src/named-ref.h, src/named-ref.c (named_ref_copy): New. * src/parse-gram.y (current_lhs): Rename as... (current_lhs_symbol): this. (current_lhs): New function. Use it to free the current lhs named reference. * src/reader.c: Bind lhs to a copy of the current named reference. * src/symlist.c: Rely on free (0) being valid. * tests/named-refs.at: Test this.
This commit is contained in:
15
ChangeLog
15
ChangeLog
@@ -1,3 +1,18 @@
|
||||
2011-03-09 Akim Demaille <akim@lrde.epita.fr>
|
||||
|
||||
named references: fix double free.
|
||||
In `rhs[name]: "a" | "b"', do not free "name" twice.
|
||||
Reported by Tys Lefering.
|
||||
<http://lists.gnu.org/archive/html/bug-bison/2010-06/msg00002.html>
|
||||
* src/named-ref.h, src/named-ref.c (named_ref_copy): New.
|
||||
* src/parse-gram.y (current_lhs): Rename as...
|
||||
(current_lhs_symbol): this.
|
||||
(current_lhs): New function. Use it to free the current lhs
|
||||
named reference.
|
||||
* src/reader.c: Bind lhs to a copy of the current named reference.
|
||||
* src/symlist.c: Rely on free (0) being valid.
|
||||
* tests/named-refs.at: Test this.
|
||||
|
||||
2011-03-09 Akim Demaille <akim@lrde.epita.fr>
|
||||
|
||||
tests: style changes.
|
||||
|
||||
2
THANKS
2
THANKS
@@ -102,7 +102,7 @@ Tom Lane tgl@sss.pgh.pa.us
|
||||
Tom Tromey tromey@cygnus.com
|
||||
Tommy Nordgren tommy.nordgren@chello.se
|
||||
Troy A. Johnson troyj@ecn.purdue.edu
|
||||
Tys Lefering twlevo@xs4all.nl
|
||||
Tys Lefering twlevo@gmail.com
|
||||
Vin Shelton acs@alumni.princeton.edu
|
||||
Wayne Green wayne@infosavvy.com
|
||||
Wolfram Wagner ww@mpi-sb.mpg.de
|
||||
|
||||
@@ -33,6 +33,12 @@ named_ref_new (uniqstr id, location loc)
|
||||
return res;
|
||||
}
|
||||
|
||||
named_ref *
|
||||
named_ref_copy (const named_ref *r)
|
||||
{
|
||||
return named_ref_new (r->id, r->loc);
|
||||
}
|
||||
|
||||
void
|
||||
named_ref_free (named_ref *r)
|
||||
{
|
||||
|
||||
@@ -37,6 +37,9 @@ typedef struct named_ref
|
||||
/* Allocate a named reference object. */
|
||||
named_ref *named_ref_new (uniqstr id, location loc);
|
||||
|
||||
/* Allocate and return a copy. */
|
||||
named_ref *named_ref_copy (const named_ref *r);
|
||||
|
||||
/* Free a named reference object. */
|
||||
void named_ref_free (named_ref *r);
|
||||
|
||||
|
||||
@@ -61,11 +61,30 @@ static void add_param (char const *type, char *decl, location loc);
|
||||
|
||||
static symbol_class current_class = unknown_sym;
|
||||
static uniqstr current_type = NULL;
|
||||
static symbol *current_lhs;
|
||||
static symbol *current_lhs_symbol;
|
||||
static location current_lhs_location;
|
||||
static named_ref *current_lhs_named_ref;
|
||||
static int current_prec = 0;
|
||||
|
||||
/** Set the new current left-hand side symbol, possibly common
|
||||
* to several right-hand side parts of rule.
|
||||
*/
|
||||
static
|
||||
void
|
||||
current_lhs(symbol *sym, location loc, named_ref *ref)
|
||||
{
|
||||
current_lhs_symbol = sym;
|
||||
current_lhs_location = loc;
|
||||
/* In order to simplify memory management, named references for lhs
|
||||
are always assigned by deep copy into the current symbol_list
|
||||
node. This is because a single named-ref in the grammar may
|
||||
result in several uses when the user factors lhs between several
|
||||
rules using "|". Therefore free the parser's original copy. */
|
||||
free (current_lhs_named_ref);
|
||||
current_lhs_named_ref = ref;
|
||||
}
|
||||
|
||||
|
||||
#define YYTYPE_INT16 int_fast16_t
|
||||
#define YYTYPE_INT8 int_fast8_t
|
||||
#define YYTYPE_UINT16 uint_fast16_t
|
||||
@@ -526,8 +545,11 @@ rules_or_grammar_declaration:
|
||||
;
|
||||
|
||||
rules:
|
||||
id_colon named_ref.opt { current_lhs = $1; current_lhs_location = @1;
|
||||
current_lhs_named_ref = $2; } rhses.1
|
||||
id_colon named_ref.opt { current_lhs ($1, @1, $2); } rhses.1
|
||||
{
|
||||
/* Free the current lhs. */
|
||||
current_lhs (0, @1, 0);
|
||||
}
|
||||
;
|
||||
|
||||
rhses.1:
|
||||
@@ -538,7 +560,7 @@ rhses.1:
|
||||
|
||||
rhs:
|
||||
/* Nothing. */
|
||||
{ grammar_current_rule_begin (current_lhs, current_lhs_location,
|
||||
{ grammar_current_rule_begin (current_lhs_symbol, current_lhs_location,
|
||||
current_lhs_named_ref); }
|
||||
| rhs symbol named_ref.opt
|
||||
{ grammar_current_rule_symbol_append ($2, @2, $3); }
|
||||
|
||||
@@ -231,7 +231,7 @@ grammar_current_rule_begin (symbol *lhs, location loc,
|
||||
|
||||
p = grammar_symbol_append (lhs, loc);
|
||||
if (lhs_name)
|
||||
assign_named_ref(p, lhs_name);
|
||||
assign_named_ref (p, named_ref_copy (lhs_name));
|
||||
|
||||
current_rule = grammar_end;
|
||||
|
||||
|
||||
@@ -151,8 +151,7 @@ symbol_list_free (symbol_list *list)
|
||||
for (node = list; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
if (node->named_ref)
|
||||
named_ref_free (node->named_ref);
|
||||
named_ref_free (node->named_ref);
|
||||
free (node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,6 +472,19 @@ AT_CLEANUP
|
||||
|
||||
#######################################################################
|
||||
|
||||
# Bison used to free twice the named ref for "a", since a single copy
|
||||
# was used in two rules.
|
||||
AT_SETUP([Factored LHS])
|
||||
AT_DATA_GRAMMAR([test.y],
|
||||
[[
|
||||
%%
|
||||
start[a]: "foo" | "bar";
|
||||
]])
|
||||
AT_BISON_CHECK([-o test.c test.y])
|
||||
AT_CLEANUP
|
||||
|
||||
#######################################################################
|
||||
|
||||
AT_SETUP([Unresolved references])
|
||||
AT_DATA_GRAMMAR([test.y],
|
||||
[[
|
||||
|
||||
Reference in New Issue
Block a user