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:
Akim Demaille
2011-03-02 17:06:58 +01:00
parent 686e83e396
commit 8f462efe92
8 changed files with 66 additions and 8 deletions

View File

@@ -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
View File

@@ -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

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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); }

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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],
[[