diagnostics: don't crash because of repeated definitions of error

According to https://www.unix.com/man-page/POSIX/1posix/yacc/, the
user is allowed to specify her user number for the error token:

    The token error shall be reserved for error handling. The name
    error can be used in grammar rules. It indicates places where the
    parser can recover from a syntax error. The default value of error
    shall be 256. Its value can be changed using a %token
    declaration. The lexical analyzer should not return the value of
    error.

I think this feature is useless, the user should not have to deal with
that.  The intend is probably to give the user a means to use 256 if
she wants to, but provided "error" cleared the path first by being
assigned another number.  In the case of Bison, 256 is assigned to
"error" at the end if the user did not use it for a token of hers.  So
this feature is useless.

Yet it is valid, and if the user assigns twice a token number to
"error", then the second time we want to complain about it and want to
show the original definition.  At this point, we try to display the
built-in definition of "error", whose location is NULL, and we crash.

Rather, the location of the first user definition of "error" should
become its defining location.

Reported byg Ahcheong Lee.
https://lists.gnu.org/r/bug-bison/2020-03/msg00007.html

* src/symtab.c (symbol_class_set): If this is a declaration and the
symbol was not declared yet, keep this as defining location.
* tests/input.at (Redefining the error token): New.
This commit is contained in:
Akim Demaille
2020-03-08 07:27:57 +01:00
parent 2f02d9beae
commit cfcd823e16
3 changed files with 37 additions and 1 deletions

View File

@@ -175,6 +175,8 @@ location_print (location loc, FILE *out)
}
else
{
aver (loc.start.file);
aver (loc.end.file);
int end_col = 0 != loc.end.column ? loc.end.column - 1 : 0;
res += fprintf (out, "%s",
quotearg_n_style (3, escape_quoting_style, loc.start.file));

View File

@@ -555,7 +555,10 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
_("previous declaration"));
}
else
s->status = declared;
{
sym->location = loc;
s->status = declared;
}
}
}
}

View File

@@ -298,6 +298,37 @@ input.y:8.14: error: syntax error, unexpected integer
AT_CLEANUP
## ---------------------------- ##
## Redefining the error token. ##
## ---------------------------- ##
AT_SETUP([Redefining the error token])
# We used to crash when trying to display the original definition of
# "error", which is a builtin without any location.
AT_DATA([input.y],
[[%token error 123
%token error 124
%%
exp:
]])
AT_BISON_CHECK([-fcaret input.y], [1], [],
[[input.y:2.8-12: warning: symbol error redeclared [-Wother]
2 | %token error 124
| ^~~~~
input.y:1.8-12: previous declaration
1 | %token error 123
| ^~~~~
input.y:2.14-16: error: redefining user token number of error
2 | %token error 124
| ^~~
]])
AT_CLEANUP
## ------------------ ##
## Dangling aliases. ##
## ------------------ ##