]> git.saurik.com Git - bison.git/blame - tests/torture.at
tests: handle locations in a more generic way.
[bison.git] / tests / torture.at
CommitLineData
6d7d248e 1# Torturing Bison. -*- Autotest -*-
6e30ede8 2
c932d613 3# Copyright (C) 2001-2002, 2004-2007, 2009-2012 Free Software
ea0a7676 4# Foundation, Inc.
6d7d248e 5
f16b0819 6# This program is free software: you can redistribute it and/or modify
6d7d248e 7# it under the terms of the GNU General Public License as published by
f16b0819
PE
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
6d7d248e
AD
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
f16b0819 15#
6d7d248e 16# You should have received a copy of the GNU General Public License
f16b0819 17# along with this program. If not, see <http://www.gnu.org/licenses/>.
6d7d248e
AD
18
19AT_BANNER([[Torture Tests.]])
20
21
49e794c5 22# AT_INCREASE_DATA_SIZE(SIZE)
f79b4f5c 23# ---------------------------
49e794c5
PE
24# Try to increase the data size to SIZE KiB if possible.
25m4_define([AT_INCREASE_DATA_SIZE],
26[data_limit=`(ulimit -S -d) 2>/dev/null`
27case $data_limit in
28[[0-9]]*)
29 if test "$data_limit" -lt $1; then
f79b4f5c 30 AT_CHECK([ulimit -S -d $1 || exit 77])
49e794c5
PE
31 ulimit -S -d $1
32 fi
33esac])
34
35
817e9f41
AD
36## ------------------------------------- ##
37## Creating a large artificial grammar. ##
38## ------------------------------------- ##
39
40# AT_DATA_TRIANGULAR_GRAMMAR(FILE-NAME, SIZE)
41# -------------------------------------------
42# Create FILE-NAME, containing a self checking parser for a huge
43# triangular grammar.
817e9f41 44m4_define([AT_DATA_TRIANGULAR_GRAMMAR],
71c7e24f
AD
45[AT_BISON_OPTION_PUSHDEFS
46AT_DATA([[gengram.pl]],
817e9f41
AD
47[[#! /usr/bin/perl -w
48
49use strict;
50my $max = $ARGV[0] || 10;
51
52print <<EOF;
9501dc6e 53]AT_DATA_GRAMMAR_PROLOGUE[
8f3596a6
AD
54%error-verbose
55%debug
817e9f41
AD
56%{
57#include <stdio.h>
58#include <stdlib.h>
290a8ff2 59#define MAX $max
55f48c48
AD
60]AT_YYLEX_DECLARE[
61]AT_YYERROR_DECLARE[
817e9f41
AD
62%}
63%union
64{
65 int val;
66};
67
68%token END "end"
69%type <val> exp input
70EOF
71
72for my $size (1 .. $max)
73 {
e9955c83 74 print "%token t$size $size \"$size\"\n";
817e9f41
AD
75 };
76
77print <<EOF;
78%%
79input:
66871a81
PE
80 exp { if (\@S|@1 != 0) abort (); \$\$ = \@S|@1; }
81| input exp { if (\@S|@2 != \@S|@1 + 1) abort (); \$\$ = \@S|@2; }
817e9f41
AD
82;
83
84exp:
85 END
86 { \$\$ = 0; }
87EOF
88
89for my $size (1 .. $max)
90 {
91 use Text::Wrap;
92 print wrap ("| ", " ",
93 (map { "\"$_\"" } (1 .. $size)),
94 " END \n"),
95 " { \$\$ = $size; }\n";
96 };
97print ";\n";
98
290a8ff2 99print <<\EOF;
817e9f41 100%%
290a8ff2 101]AT_YYERROR_DEFINE[
817e9f41
AD
102static int
103yylex (void)
104{
105 static int inner = 1;
106 static int outer = 0;
290a8ff2 107 if (outer > MAX)
817e9f41
AD
108 return 0;
109 else if (inner > outer)
110 {
111 inner = 1;
112 ++outer;
113 return END;
114 }
23c5a174 115 return inner++;
817e9f41 116}
817e9f41
AD
117int
118main (void)
119{
120 yydebug = !!getenv ("YYDEBUG");
121 return yyparse ();
122}
123EOF
124]])
71c7e24f 125AT_BISON_OPTION_POPDEFS
817e9f41
AD
126
127AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
128mv stdout $1
129])
130
131
132## -------------- ##
133## Big triangle. ##
134## -------------- ##
135
817e9f41
AD
136AT_SETUP([Big triangle])
137
355e7c1c
AD
138# I have been able to go up to 2000 on my machine.
139# I tried 3000, a 29Mb grammar file, but then my system killed bison.
e9955c83
AD
140# With 500 and the new parser, which consume far too much memory,
141# it gets killed too. Of course the parser is to be cleaned.
142AT_DATA_TRIANGULAR_GRAMMAR([input.y], [200])
da730230 143AT_BISON_CHECK_NO_XML([-v -o input.c input.y])
1154cced
AD
144AT_COMPILE([input])
145AT_PARSER_CHECK([./input])
817e9f41
AD
146
147AT_CLEANUP
148
149
150
62a3e4f0
AD
151# AT_DATA_HORIZONTAL_GRAMMAR(FILE-NAME, SIZE)
152# -------------------------------------------
153# Create FILE-NAME, containing a self checking parser for a huge
154# horizontal grammar.
62a3e4f0 155m4_define([AT_DATA_HORIZONTAL_GRAMMAR],
71c7e24f
AD
156[AT_BISON_OPTION_PUSHDEFS
157AT_DATA([[gengram.pl]],
62a3e4f0
AD
158[[#! /usr/bin/perl -w
159
160use strict;
161my $max = $ARGV[0] || 10;
162
163print <<EOF;
9501dc6e 164]AT_DATA_GRAMMAR_PROLOGUE[
8f3596a6
AD
165%error-verbose
166%debug
62a3e4f0
AD
167%{
168#include <stdio.h>
169#include <stdlib.h>
290a8ff2 170#define MAX $max
55f48c48
AD
171]AT_YYLEX_DECLARE[
172]AT_YYERROR_DECLARE[
62a3e4f0 173%}
62a3e4f0 174
8f3596a6
AD
175%token
176EOF
62a3e4f0
AD
177for my $size (1 .. $max)
178 {
8f3596a6 179 print " t$size $size \"$size\"\n";
62a3e4f0
AD
180 };
181
182print <<EOF;
8f3596a6 183
62a3e4f0
AD
184%%
185EOF
186
187use Text::Wrap;
188print
189 wrap ("exp: ", " ",
190 (map { "\"$_\"" } (1 .. $max)), ";"),
191 "\n";
192
290a8ff2 193print <<\EOF;
62a3e4f0 194%%
290a8ff2 195]AT_YYERROR_DEFINE[
62a3e4f0
AD
196static int
197yylex (void)
198{
199 static int counter = 1;
290a8ff2 200 if (counter <= MAX)
cf806753 201 return counter++;
290a8ff2 202 if (counter++ != MAX + 1)
cf806753
PE
203 abort ();
204 return 0;
62a3e4f0
AD
205}
206
62a3e4f0
AD
207int
208main (void)
209{
210 yydebug = !!getenv ("YYDEBUG");
211 return yyparse ();
212}
213EOF
214]])
215
216AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
217mv stdout $1
71c7e24f 218AT_BISON_OPTION_POPDEFS
62a3e4f0
AD
219])
220
221
222## ---------------- ##
223## Big horizontal. ##
224## ---------------- ##
225
226AT_SETUP([Big horizontal])
227
228# I have been able to go up to 10000 on my machine, but I had to
229# increase the maximum stack size (* 100). It gave:
230#
231# input.y 263k
232# input.tab.c 1.3M
233# input 453k
234#
235# gengram.pl 10000 0.70s user 0.01s sys 99% cpu 0.711 total
236# bison input.y 730.56s user 0.53s sys 99% cpu 12:12.34 total
237# gcc -Wall input.tab.c -o input 5.81s user 0.20s sys 100% cpu 6.01 total
238# ./input 0.00s user 0.01s sys 108% cpu 0.01 total
239#
240AT_DATA_HORIZONTAL_GRAMMAR([input.y], [1000])
49e794c5
PE
241
242# GNU m4 requires about 70 MiB for this test on a 32-bit host.
243# Ask for 200 MiB, which should be plenty even on a 64-bit host.
244AT_INCREASE_DATA_SIZE(204000)
245
da730230 246AT_BISON_CHECK_NO_XML([-v -o input.c input.y])
1154cced
AD
247AT_COMPILE([input])
248AT_PARSER_CHECK([./input])
62a3e4f0
AD
249
250AT_CLEANUP
251
252
253
742e4900 254# AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR(FILE-NAME, SIZE)
8f3596a6 255# --------------------------------------------------
39ceb25b 256# Create FILE-NAME, containing a self checking parser for a grammar
742e4900
JD
257# requiring SIZE lookahead tokens.
258m4_define([AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR],
71c7e24f
AD
259[AT_BISON_OPTION_PUSHDEFS
260AT_DATA([[gengram.pl]],
39ceb25b
AD
261[[#! /usr/bin/perl -w
262
263use strict;
264use Text::Wrap;
265my $max = $ARGV[0] || 10;
266
267print <<EOF;
8f3596a6
AD
268%error-verbose
269%debug
39ceb25b 270%{
8f3596a6
AD
271# include <stdio.h>
272# include <stdlib.h>
273# include <assert.h>
290a8ff2 274# define MAX $max
55f48c48
AD
275]AT_YYLEX_DECLARE[
276]AT_YYERROR_DECLARE[
39ceb25b
AD
277%}
278%union
279{
280 int val;
281};
282
283%type <val> input exp
284%token token
285EOF
286
287print
288 wrap ("%type <val> ",
289 " ",
e9955c83 290 map { "n$_" } (1 .. $max)),
39ceb25b
AD
291 "\n";
292
8f3596a6 293print "%token\n";
39ceb25b
AD
294for my $count (1 .. $max)
295 {
8f3596a6 296 print " t$count $count \"$count\"\n";
39ceb25b
AD
297 };
298
299print <<EOF;
300%%
301input:
8f3596a6
AD
302 exp { assert (\@S|@1 == 1); \$\$ = \@S|@1; }
303| input exp { assert (\@S|@2 == \@S|@1 + 1); \$\$ = \@S|@2; }
39ceb25b
AD
304;
305
306exp:
8f3596a6 307 n1 "1" { assert (\@S|@1 == 1); \@S|@\@S|@ = \@S|@1; }
39ceb25b
AD
308EOF
309
310for my $count (2 .. $max)
311 {
8f3596a6 312 print "| n$count \"$count\" { assert (\@S|@1 == $count); \@S|@\@S|@ = \@S|@1; }\n";
39ceb25b
AD
313 };
314print ";\n";
315
316for my $count (1 .. $max)
317 {
e9955c83 318 print "n$count: token { \$\$ = $count; };\n";
39ceb25b
AD
319 };
320
290a8ff2 321print <<\EOF;
39ceb25b 322%%
290a8ff2 323]AT_YYERROR_DEFINE[
39ceb25b
AD
324static int
325yylex (void)
326{
327 static int return_token = 1;
328 static int counter = 1;
290a8ff2 329 if (counter > MAX)
cf806753 330 {
290a8ff2 331 if (counter++ != MAX + 1)
cf806753
PE
332 abort ();
333 return 0;
334 }
39ceb25b
AD
335 if (return_token)
336 {
337 return_token = 0;
338 return token;
339 }
340 return_token = 1;
341 return counter++;
342}
343
39ceb25b
AD
344int
345main (void)
346{
347 yydebug = !!getenv ("YYDEBUG");
348 return yyparse ();
349}
350EOF
351]])
352
353AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
354mv stdout $1
71c7e24f 355AT_BISON_OPTION_POPDEFS
39ceb25b
AD
356])
357
358
8dd162d3 359## ------------------------ ##
7d596384 360## Many lookahead tokens. ##
8dd162d3 361## ------------------------ ##
39ceb25b 362
742e4900 363AT_SETUP([Many lookahead tokens])
39ceb25b 364
742e4900 365AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR([input.y], [1000])
49e794c5
PE
366
367# GNU m4 requires about 70 MiB for this test on a 32-bit host.
368# Ask for 200 MiB, which should be plenty even on a 64-bit host.
369AT_INCREASE_DATA_SIZE(204000)
370
da730230 371AT_BISON_CHECK([-v -o input.c input.y])
1154cced
AD
372AT_COMPILE([input])
373AT_PARSER_CHECK([./input])
39ceb25b
AD
374
375AT_CLEANUP
376
377
378
7d596384
JD
379# AT_DATA_STACK_TORTURE(C-PROLOGUE, [BISON-DECLS])
380# ------------------------------------------------
6d7d248e
AD
381# A parser specialized in torturing the stack size.
382m4_define([AT_DATA_STACK_TORTURE],
55f48c48
AD
383[AT_BISON_OPTION_PUSHDEFS([$2])
384# A grammar of parens growing the stack thanks to right recursion.
6d7d248e
AD
385# exp:
386AT_DATA([input.y],
387[[%{
04098407
PE
388#include <errno.h>
389#include <limits.h>
6d7d248e
AD
390#include <stdio.h>
391#include <stdlib.h>
6d7d248e 392]$1[
55f48c48
AD
393 ]AT_YYLEX_DECLARE[
394 ]AT_YYERROR_DECLARE[
6d7d248e 395%}
7d596384 396]$2[
04d843a2 397%error-verbose
6d7d248e
AD
398%debug
399%token WAIT_FOR_EOF
400%%
401exp: WAIT_FOR_EOF exp | ;
402%%
55f48c48 403]AT_YYERROR_DEFINE[
6d7d248e
AD
404static int
405yylex (void)
406{
cf806753
PE
407 if (yylval < 0)
408 abort ();
6d7d248e
AD
409 if (yylval--)
410 return WAIT_FOR_EOF;
411 else
412 return EOF;
413}
414
415int
416main (int argc, const char **argv)
417{
04098407 418 char *endp;
7d596384 419 YYSTYPE yylval_init;
66871a81
PE
420 if (argc != 2)
421 abort ();
7d596384 422 yylval_init = strtol (argv[1], &endp, 10);
04098407 423 if (! (argv[1] != endp
7d596384 424 && 0 <= yylval_init && yylval_init <= INT_MAX
04098407
PE
425 && errno != ERANGE))
426 abort ();
6d7d248e 427 yydebug = 1;
7d596384
JD
428 {
429 int count;
430 int status;
431]m4_bmatch([$2], [%push-],
5d31a216 432[[ yypstate *ps = yypstate_new ();
7d596384
JD
433]])[ for (count = 0; count < 2; ++count)
434 {
435 int new_status;
436 yylval = yylval_init;
437]m4_bmatch([$2], [%push-],
5d31a216 438[[ new_status = yypull_parse (ps);
7d596384
JD
439]],
440[[ new_status = yyparse ();
441]])[ if (count > 0 && new_status != status)
442 abort ();
443 status = new_status;
444 }
445]m4_bmatch([$2], [%push-],
5d31a216 446[[ yypstate_delete (ps);
7d596384
JD
447]])[ return status;
448 }
6d7d248e
AD
449}
450]])
55f48c48 451AT_BISON_OPTION_POPDEFS([$2])
da730230 452AT_BISON_CHECK([-o input.c input.y])
1154cced 453AT_COMPILE([input])
6d7d248e
AD
454])
455
456
457## -------------------------------------- ##
458## Exploding the Stack Size with Alloca. ##
459## -------------------------------------- ##
460
461AT_SETUP([Exploding the Stack Size with Alloca])
462
7d596384 463m4_pushdef([AT_USE_ALLOCA], [[
0d50976f 464#if (defined __GNUC__ || defined __BUILTIN_VA_ARG_INCR \
62c4328e 465 || defined _AIX || defined _MSC_VER || defined _ALLOCA_H)
577d7c33
PE
466# define YYSTACK_USE_ALLOCA 1
467#endif
468]])
6d7d248e 469
7d596384
JD
470AT_DATA_STACK_TORTURE([AT_USE_ALLOCA])
471
6d7d248e 472# Below the limit of 200.
e0ac9b4b
JD
473AT_PARSER_CHECK([./input 20], 0, [], [ignore],
474 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e 475# Two enlargements: 2 * 2 * 200.
e0ac9b4b
JD
476AT_PARSER_CHECK([./input 900], 0, [], [ignore],
477 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e
AD
478# Fails: beyond the limit of 10,000 (which we don't reach anyway since we
479# multiply by two starting at 200 => 5120 is the last possible).
e0ac9b4b
JD
480AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
481 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e 482
78143faa
JD
483# The push parser can't use alloca since the stacks can't be locals. This test
484# just helps guarantee we don't let the YYSTACK_USE_ALLOCA feature affect
485# push parsers.
7d596384 486AT_DATA_STACK_TORTURE([AT_USE_ALLOCA],
f37495f6 487[[%define api.push-pull both
7d596384 488]])
e0ac9b4b
JD
489AT_PARSER_CHECK([./input 20], 0, [], [ignore],
490 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
491AT_PARSER_CHECK([./input 900], 0, [], [ignore],
492 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
493AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
494 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
7d596384
JD
495
496m4_popdef([AT_USE_ALLOCA])
497
6d7d248e
AD
498AT_CLEANUP
499
500
501
502
503## -------------------------------------- ##
504## Exploding the Stack Size with Malloc. ##
505## -------------------------------------- ##
506
507AT_SETUP([Exploding the Stack Size with Malloc])
508
7d596384
JD
509m4_pushdef([AT_USE_ALLOCA], [[#define YYSTACK_USE_ALLOCA 0]])
510
511AT_DATA_STACK_TORTURE([AT_USE_ALLOCA])
6d7d248e
AD
512
513# Below the limit of 200.
e0ac9b4b
JD
514AT_PARSER_CHECK([./input 20], 0, [], [ignore],
515 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e 516# Two enlargements: 2 * 2 * 200.
e0ac9b4b
JD
517AT_PARSER_CHECK([./input 900], 0, [], [ignore],
518 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e
AD
519# Fails: beyond the limit of 10,000 (which we don't reach anyway since we
520# multiply by two starting at 200 => 5120 is the possible).
e0ac9b4b
JD
521AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
522 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e 523
7d596384 524AT_DATA_STACK_TORTURE([AT_USE_ALLOCA],
f37495f6 525[[%define api.push-pull both
7d596384 526]])
e0ac9b4b
JD
527AT_PARSER_CHECK([./input 20], 0, [], [ignore],
528 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
529AT_PARSER_CHECK([./input 900], 0, [], [ignore],
530 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
531AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
532 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
7d596384
JD
533
534m4_popdef([AT_USE_ALLOCA])
535
6d7d248e 536AT_CLEANUP