mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-19 09:13:04 +00:00
Don't miss %merge result type warnings just because the LHS types are
declared after the %merge. * src/reader.c (get_merge_function): Don't set the merger type yet. (record_merge_function_type): New function for setting the merger type and checking for clashes. (grammar_current_rule_merge_set): Set the location of the %merge for the current rule. (packgram): Invoke record_merge_function_type for each rule now that all symbol type declarations have been parsed. * src/reader.h (merger_list.type_declaration_location): New member storing the location of the first %merge from which the type for this merging function was derived. * src/symlist.h (symbol_list.merger_declaration_location): New member storing the location of a rule's %merge, if any. * tests/glr-regression.at (Missed %merge type warnings when LHS type is declared later): New test to catch the error fixed by the above patch.
This commit is contained in:
19
ChangeLog
19
ChangeLog
@@ -1,3 +1,22 @@
|
|||||||
|
2006-06-26 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||||
|
|
||||||
|
Don't miss %merge result type warnings just because the LHS types are
|
||||||
|
declared after the %merge.
|
||||||
|
* src/reader.c (get_merge_function): Don't set the merger type yet.
|
||||||
|
(record_merge_function_type): New function for setting the merger type
|
||||||
|
and checking for clashes.
|
||||||
|
(grammar_current_rule_merge_set): Set the location of the %merge for
|
||||||
|
the current rule.
|
||||||
|
(packgram): Invoke record_merge_function_type for each rule now that
|
||||||
|
all symbol type declarations have been parsed.
|
||||||
|
* src/reader.h (merger_list.type_declaration_location): New member
|
||||||
|
storing the location of the first %merge from which the type for this
|
||||||
|
merging function was derived.
|
||||||
|
* src/symlist.h (symbol_list.merger_declaration_location): New member
|
||||||
|
storing the location of a rule's %merge, if any.
|
||||||
|
* tests/glr-regression.at (Missed %merge type warnings when LHS type is
|
||||||
|
declared later): New test to catch the error fixed by the above patch.
|
||||||
|
|
||||||
2006-06-26 Joel E. Denny <jdenny@ces.clemson.edu>
|
2006-06-26 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||||
|
|
||||||
Get action warnings (grammar_rule_check) right even when symbol
|
Get action warnings (grammar_rule_check) right even when symbol
|
||||||
|
|||||||
66
src/reader.c
66
src/reader.c
@@ -90,14 +90,13 @@ prologue_augment (const char *prologue, location loc, bool post)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------.
|
/*------------------------------------------------------------------------.
|
||||||
| Return the merger index for a merging function named NAME, whose |
|
| Return the merger index for a merging function named NAME. Records the |
|
||||||
| arguments have type TYPE. Records the function, if new, in |
|
| function, if new, in MERGER_LIST. |
|
||||||
| MERGER_LIST. |
|
`------------------------------------------------------------------------*/
|
||||||
`-------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_merge_function (uniqstr name, uniqstr type, location loc)
|
get_merge_function (uniqstr name)
|
||||||
{
|
{
|
||||||
merger_list *syms;
|
merger_list *syms;
|
||||||
merger_list head;
|
merger_list head;
|
||||||
@@ -106,9 +105,6 @@ get_merge_function (uniqstr name, uniqstr type, location loc)
|
|||||||
if (! glr_parser)
|
if (! glr_parser)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (type == NULL)
|
|
||||||
type = uniqstr_new ("");
|
|
||||||
|
|
||||||
head.next = merge_functions;
|
head.next = merge_functions;
|
||||||
for (syms = &head, n = 1; syms->next; syms = syms->next, n += 1)
|
for (syms = &head, n = 1; syms->next; syms = syms->next, n += 1)
|
||||||
if (UNIQSTR_EQ (name, syms->next->name))
|
if (UNIQSTR_EQ (name, syms->next->name))
|
||||||
@@ -117,16 +113,54 @@ get_merge_function (uniqstr name, uniqstr type, location loc)
|
|||||||
{
|
{
|
||||||
syms->next = xmalloc (sizeof syms->next[0]);
|
syms->next = xmalloc (sizeof syms->next[0]);
|
||||||
syms->next->name = uniqstr_new (name);
|
syms->next->name = uniqstr_new (name);
|
||||||
syms->next->type = uniqstr_new (type);
|
/* After all symbol type declarations have been parsed, packgram invokes
|
||||||
|
record_merge_function_type to set the type. */
|
||||||
|
syms->next->type = NULL;
|
||||||
syms->next->next = NULL;
|
syms->next->next = NULL;
|
||||||
merge_functions = head.next;
|
merge_functions = head.next;
|
||||||
}
|
}
|
||||||
else if (!UNIQSTR_EQ (type, syms->next->type))
|
|
||||||
warn_at (loc, _("result type clash on merge function %s: <%s> != <%s>"),
|
|
||||||
name, type, syms->next->type);
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------.
|
||||||
|
| For the existing merging function with index MERGER, record the result |
|
||||||
|
| type as TYPE as required by the lhs of the rule whose %merge declaration |
|
||||||
|
| is at DECLARATION_LOC. |
|
||||||
|
`-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
record_merge_function_type (int merger, uniqstr type, location declaration_loc)
|
||||||
|
{
|
||||||
|
int merger_find;
|
||||||
|
merger_list *merge_function;
|
||||||
|
|
||||||
|
if (merger <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (type == NULL)
|
||||||
|
type = uniqstr_new ("");
|
||||||
|
|
||||||
|
merger_find = 1;
|
||||||
|
for (merge_function = merge_functions;
|
||||||
|
merge_function != NULL && merger_find != merger;
|
||||||
|
merge_function = merge_function->next)
|
||||||
|
merger_find += 1;
|
||||||
|
assert (merge_function != NULL && merger_find == merger);
|
||||||
|
if (merge_function->type == NULL)
|
||||||
|
{
|
||||||
|
merge_function->type = uniqstr_new (type);
|
||||||
|
merge_function->type_declaration_location = declaration_loc;
|
||||||
|
}
|
||||||
|
else if (!UNIQSTR_EQ (merge_function->type, type))
|
||||||
|
{
|
||||||
|
warn_at (declaration_loc,
|
||||||
|
_("result type clash on merge function `%s': <%s> != <%s>"),
|
||||||
|
merge_function->name, type, merge_function->type);
|
||||||
|
warn_at (merge_function->type_declaration_location,
|
||||||
|
_("first declaration"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------.
|
/*--------------------------------------.
|
||||||
| Free all merge-function definitions. |
|
| Free all merge-function definitions. |
|
||||||
`--------------------------------------*/
|
`--------------------------------------*/
|
||||||
@@ -382,8 +416,8 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
|
|||||||
warn_at (loc, _("%s affects only GLR parsers"), "%merge");
|
warn_at (loc, _("%s affects only GLR parsers"), "%merge");
|
||||||
if (current_rule->merger != 0)
|
if (current_rule->merger != 0)
|
||||||
complain_at (loc, _("only one %s allowed per rule"), "%merge");
|
complain_at (loc, _("only one %s allowed per rule"), "%merge");
|
||||||
current_rule->merger =
|
current_rule->merger = get_merge_function (name);
|
||||||
get_merge_function (name, current_rule->sym->type_name, loc);
|
current_rule->merger_declaration_location = loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attach SYM to the current rule. If needed, move the previous
|
/* Attach SYM to the current rule. If needed, move the previous
|
||||||
@@ -434,6 +468,8 @@ packgram (void)
|
|||||||
{
|
{
|
||||||
int rule_length = 0;
|
int rule_length = 0;
|
||||||
symbol *ruleprec = p->ruleprec;
|
symbol *ruleprec = p->ruleprec;
|
||||||
|
record_merge_function_type (p->merger, p->sym->type_name,
|
||||||
|
p->merger_declaration_location);
|
||||||
rules[ruleno].user_number = ruleno;
|
rules[ruleno].user_number = ruleno;
|
||||||
rules[ruleno].number = ruleno;
|
rules[ruleno].number = ruleno;
|
||||||
rules[ruleno].lhs = p->sym;
|
rules[ruleno].lhs = p->sym;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ typedef struct merger_list
|
|||||||
struct merger_list* next;
|
struct merger_list* next;
|
||||||
uniqstr name;
|
uniqstr name;
|
||||||
uniqstr type;
|
uniqstr type;
|
||||||
|
location type_declaration_location;
|
||||||
} merger_list;
|
} merger_list;
|
||||||
|
|
||||||
/* From the parser. */
|
/* From the parser. */
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ typedef struct symbol_list
|
|||||||
symbol *ruleprec;
|
symbol *ruleprec;
|
||||||
int dprec;
|
int dprec;
|
||||||
int merger;
|
int merger;
|
||||||
|
location merger_declaration_location;
|
||||||
|
|
||||||
/* The list. */
|
/* The list. */
|
||||||
struct symbol_list *next;
|
struct symbol_list *next;
|
||||||
|
|||||||
@@ -1661,3 +1661,58 @@ AT_CHECK([[./glr-regr17]], 0, [],
|
|||||||
])
|
])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
|
|
||||||
|
## -------------------------------------------------------------##
|
||||||
|
## Missed %merge type warnings when LHS type is declared later. ##
|
||||||
|
## -------------------------------------------------------------##
|
||||||
|
|
||||||
|
AT_SETUP([Missed %merge type warnings when LHS type is declared later])
|
||||||
|
AT_DATA_GRAMMAR([glr-regr18.y],
|
||||||
|
[[%glr-parser
|
||||||
|
|
||||||
|
%{
|
||||||
|
static void yyerror (char const *);
|
||||||
|
static int yylex ();
|
||||||
|
%}
|
||||||
|
|
||||||
|
%union {
|
||||||
|
int type1;
|
||||||
|
int type2;
|
||||||
|
}
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
sym1: sym2 %merge<merge> { $$ = $1; } ;
|
||||||
|
sym2: %merge<merge> { $$ = 0; } ;
|
||||||
|
|
||||||
|
%type <type1> sym1;
|
||||||
|
%type <type2> sym2;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
static void
|
||||||
|
yyerror (char const *msg)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
yylex ()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
return yyparse ();
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|
||||||
|
AT_CHECK([[bison -o glr-regr18.c glr-regr18.y]], 0, [],
|
||||||
|
[glr-regr18.y:26.13-19: warning: result type clash on merge function `merge': <type2> != <type1>
|
||||||
|
glr-regr18.y:25.18-24: warning: first declaration
|
||||||
|
])
|
||||||
|
|
||||||
|
AT_CLEANUP
|
||||||
|
|||||||
Reference in New Issue
Block a user