mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-21 02:03:03 +00:00
yysyntax_error: test memory management more.
* tests/atlocal.in (NO_WERROR_CFLAGS): New cpp macro.
* tests/regression.at (%error-verbose and YYSTACK_USE_ALLOCA):
New test group.
(%error-verbose overflow): New test group that reveals an
obscure bug. Expected fail for now.
(cherry picked from commit 52cea04ad3)
This commit is contained in:
@@ -1,3 +1,12 @@
|
|||||||
|
2009-09-23 Joel E. Denny <jdenny@clemson.edu>
|
||||||
|
|
||||||
|
yysyntax_error: test memory management more.
|
||||||
|
* tests/atlocal.in (NO_WERROR_CFLAGS): New cpp macro.
|
||||||
|
* tests/regression.at (%error-verbose and YYSTACK_USE_ALLOCA):
|
||||||
|
New test group.
|
||||||
|
(%error-verbose overflow): New test group that reveals an
|
||||||
|
obscure bug. Expected fail for now.
|
||||||
|
|
||||||
2008-12-11 Akim Demaille <demaille@gostai.com>
|
2008-12-11 Akim Demaille <demaille@gostai.com>
|
||||||
|
|
||||||
Pass the token type to yysyntax_error.
|
Pass the token type to yysyntax_error.
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
# We want no optimization.
|
# We want no optimization.
|
||||||
CFLAGS='@O0CFLAGS@ @WARN_CFLAGS@ @WERROR_CFLAGS@'
|
CFLAGS='@O0CFLAGS@ @WARN_CFLAGS@ @WERROR_CFLAGS@'
|
||||||
|
|
||||||
|
# Sometimes a test group needs to ignore gcc warnings, so it locally
|
||||||
|
# sets CFLAGS to this.
|
||||||
|
NO_WERROR_CFLAGS='@O0CFLAGS@ @WARN_CFLAGS@'
|
||||||
|
|
||||||
# We need `config.h'.
|
# We need `config.h'.
|
||||||
CPPFLAGS="-I$abs_top_builddir/lib @CPPFLAGS@"
|
CPPFLAGS="-I$abs_top_builddir/lib @CPPFLAGS@"
|
||||||
|
|
||||||
|
|||||||
@@ -1268,3 +1268,212 @@ AT_BISON_CHECK([[-o input.c -Dlr.type=ielr input.y]])
|
|||||||
AT_CHECK([[diff -u lalr.c ielr.c]])
|
AT_CHECK([[diff -u lalr.c ielr.c]])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## --------------------------------------- ##
|
||||||
|
## %error-verbose and YYSTACK_USE_ALLOCA. ##
|
||||||
|
## --------------------------------------- ##
|
||||||
|
|
||||||
|
AT_SETUP([[%error-verbose and YYSTACK_USE_ALLOCA]])
|
||||||
|
|
||||||
|
AT_DATA_GRAMMAR([input.y],
|
||||||
|
[[%code {
|
||||||
|
#include <stdio.h>
|
||||||
|
void yyerror (char const *);
|
||||||
|
int yylex (void);
|
||||||
|
#define YYSTACK_USE_ALLOCA 1
|
||||||
|
}
|
||||||
|
|
||||||
|
%error-verbose
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
start: check syntax_error syntax_error ;
|
||||||
|
|
||||||
|
check:
|
||||||
|
{
|
||||||
|
if (128 < sizeof yymsgbuf)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"The initial size of yymsgbuf in yyparse has increased\n"
|
||||||
|
"since this test group was last updated. As a result,\n"
|
||||||
|
"this test group may no longer manage to induce a\n"
|
||||||
|
"reallocation of the syntax error message buffer.\n"
|
||||||
|
"This test group must be adjusted to produce a longer\n"
|
||||||
|
"error message.\n");
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
// Induce a syntax error message whose total length is more than
|
||||||
|
// sizeof yymsgbuf in yyparse. Each token here is 64 bytes.
|
||||||
|
syntax_error:
|
||||||
|
"123456789112345678921234567893123456789412345678951234567896123A"
|
||||||
|
| "123456789112345678921234567893123456789412345678951234567896123B"
|
||||||
|
| error 'a' 'b' 'c'
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
void
|
||||||
|
yyerror (char const *msg)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
yylex (void)
|
||||||
|
{
|
||||||
|
/* Induce two syntax error messages (which requires full error
|
||||||
|
recovery by shifting 3 tokens) in order to detect any loss of the
|
||||||
|
reallocated buffer. */
|
||||||
|
static char const *input = "abc";
|
||||||
|
return *input++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
return yyparse ();
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|
||||||
|
AT_BISON_CHECK([[-o input.c input.y]])
|
||||||
|
AT_COMPILE([[input]])
|
||||||
|
AT_PARSER_CHECK([[./input]], [[1]], [],
|
||||||
|
[[syntax error, unexpected 'a', expecting 123456789112345678921234567893123456789412345678951234567896123A or 123456789112345678921234567893123456789412345678951234567896123B
|
||||||
|
syntax error, unexpected $end, expecting 123456789112345678921234567893123456789412345678951234567896123A or 123456789112345678921234567893123456789412345678951234567896123B
|
||||||
|
]])
|
||||||
|
|
||||||
|
AT_CLEANUP
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ------------------------- ##
|
||||||
|
## %error-verbose overflow. ##
|
||||||
|
## ------------------------- ##
|
||||||
|
|
||||||
|
# Imagine the case where YYSTACK_ALLOC_MAXIMUM = YYSIZE_MAXIMUM and an
|
||||||
|
# invocation of yysyntax_error has caused yymsg_alloc to grow to exactly
|
||||||
|
# YYSTACK_ALLOC_MAXIMUM (perhaps because the normal doubling of size had
|
||||||
|
# to be clipped to YYSTACK_ALLOC_MAXIMUM). Now imagine a subsequent
|
||||||
|
# invocation of yysyntax_error that overflows during its size
|
||||||
|
# calculation and thus returns YYSIZE_MAXIMUM to yyparse. Then, yyparse
|
||||||
|
# will invoke yyerror using the old contents of yymsg. This bug needs
|
||||||
|
# to be fixed.
|
||||||
|
|
||||||
|
AT_SETUP([[%error-verbose overflow]])
|
||||||
|
|
||||||
|
AT_XFAIL_IF([[:]])
|
||||||
|
|
||||||
|
AT_DATA_GRAMMAR([input.y],
|
||||||
|
[[%code {
|
||||||
|
#include <stdio.h>
|
||||||
|
void yyerror (char const *);
|
||||||
|
int yylex (void);
|
||||||
|
|
||||||
|
/* This prevents this test case from having to induce error messages
|
||||||
|
large enough to overflow size_t. */
|
||||||
|
#define YYSIZE_T unsigned char
|
||||||
|
|
||||||
|
/* Bring in malloc so yacc.c doesn't try to provide a malloc prototype
|
||||||
|
using our YYSIZE_T. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Max depth is usually much smaller than YYSTACK_ALLOC_MAXIMUM, and
|
||||||
|
we don't want gcc to warn everywhere this constant would be too big
|
||||||
|
to make sense for our YYSIZE_T. */
|
||||||
|
#define YYMAXDEPTH 100
|
||||||
|
}
|
||||||
|
|
||||||
|
%error-verbose
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
start: syntax_error1 check syntax_error2 ;
|
||||||
|
|
||||||
|
// Induce a syntax error message whose total length causes yymsg in
|
||||||
|
// yyparse to be reallocated to size YYSTACK_ALLOC_MAXIMUM, which
|
||||||
|
// should be 255. Each token here is 64 bytes.
|
||||||
|
syntax_error1:
|
||||||
|
"123456789112345678921234567893123456789412345678951234567896123A"
|
||||||
|
| "123456789112345678921234567893123456789412345678951234567896123B"
|
||||||
|
| "123456789112345678921234567893123456789412345678951234567896123C"
|
||||||
|
| error 'a' 'b' 'c'
|
||||||
|
;
|
||||||
|
|
||||||
|
check:
|
||||||
|
{
|
||||||
|
if (yymsg_alloc != YYSTACK_ALLOC_MAXIMUM
|
||||||
|
|| YYSTACK_ALLOC_MAXIMUM != YYSIZE_MAXIMUM
|
||||||
|
|| YYSIZE_MAXIMUM != 255)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"The assumptions of this test group are no longer\n"
|
||||||
|
"valid, so it may no longer catch the error it was\n"
|
||||||
|
"designed to catch. Specifically, the following\n"
|
||||||
|
"values should all be 255:\n\n");
|
||||||
|
fprintf (stderr, " yymsg_alloc = %d\n", yymsg_alloc);
|
||||||
|
fprintf (stderr, " YYSTACK_ALLOC_MAXIMUM = %d\n",
|
||||||
|
YYSTACK_ALLOC_MAXIMUM);
|
||||||
|
fprintf (stderr, " YYSIZE_MAXIMUM = %d\n", YYSIZE_MAXIMUM);
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
// Now overflow.
|
||||||
|
syntax_error2:
|
||||||
|
"123456789112345678921234567893123456789412345678951234567896123A"
|
||||||
|
| "123456789112345678921234567893123456789412345678951234567896123B"
|
||||||
|
| "123456789112345678921234567893123456789412345678951234567896123C"
|
||||||
|
| "123456789112345678921234567893123456789412345678951234567896123D"
|
||||||
|
| "123456789112345678921234567893123456789412345678951234567896123E"
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
void
|
||||||
|
yyerror (char const *msg)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
yylex (void)
|
||||||
|
{
|
||||||
|
/* Induce two syntax error messages (which requires full error
|
||||||
|
recovery by shifting 3 tokens). */
|
||||||
|
static char const *input = "abc";
|
||||||
|
return *input++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
/* Push parsers throw away the message buffer between tokens, so skip
|
||||||
|
this test under maintainer-push-check. */
|
||||||
|
if (YYPUSH)
|
||||||
|
return 77;
|
||||||
|
return yyparse ();
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|
||||||
|
AT_BISON_CHECK([[-o input.c input.y]])
|
||||||
|
|
||||||
|
# gcc warns about tautologies and fallacies involving comparisons for
|
||||||
|
# unsigned char. However, it doesn't produce these same warnings for
|
||||||
|
# size_t and many other types when the warnings would seem to make just
|
||||||
|
# as much sense. We ignore the warnings.
|
||||||
|
[CFLAGS="$NO_WERROR_CFLAGS"]
|
||||||
|
AT_COMPILE([[input]])
|
||||||
|
|
||||||
|
AT_PARSER_CHECK([[./input]], [[2]], [],
|
||||||
|
[[syntax error, unexpected 'a', expecting 123456789112345678921234567893123456789412345678951234567896123A or 123456789112345678921234567893123456789412345678951234567896123B or 123456789112345678921234567893123456789412345678951234567896123C
|
||||||
|
syntax error
|
||||||
|
memory exhausted
|
||||||
|
]])
|
||||||
|
|
||||||
|
AT_CLEANUP
|
||||||
|
|||||||
Reference in New Issue
Block a user