1 # Checking diagnotics. -*- Autotest -*-
3 # Copyright (C) 2019 Free Software Foundation, Inc.
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 AT_BANNER([[Diagnostics.]])
21 # AT_TEST($1: TITLE, $2: GRAMMAR, $3: EXIT-STATUS, $4: OUTPUT-WITH-STYLE,
23 # -----------------------------------------------------------------------
24 # Run Bison on GRAMMAR with debugging style enabled, and expect
25 # OUTPUT-WITH-STYLE as diagnostics.
29 AT_KEYWORDS([diagnostics])
31 # We need UTF-8 support for correct screen-width computation of UTF-8
32 # characters. Skip the test if not available.
33 AT_SKIP_IF([! locale -a | grep '^en_US.UTF-8$'])
35 AT_BISON_OPTION_PUSHDEFS
37 AT_DATA_GRAMMAR([[input.y]], [$2])
39 # For some reason, literal ^M in the input are removed and don't end
40 # in `input.y`. So use the two-character ^M represent it, and let
41 # Perl insert real CR characters.
42 if grep '\^M' input.y >/dev/null; then
43 AT_PERL_REQUIRE([-pi -e 's{\^M}{\r}gx' input.y])
46 AT_DATA([experr], [$4])
48 AT_CHECK([LC_ALL=en_US.UTF-8 $5 bison -fcaret --color=debug -Wall input.y], [$3], [], [experr])
50 # When no style, same messages, but without style.
51 AT_PERL_REQUIRE([-pi -e 's{(</?(-|\w)+>)}{ $[]1 eq "<tag>" ? $[]1 : "" }ge' experr])
53 # Cannot use AT_BISON_CHECK easily as we need to change the
55 # FIXME: Enhance AT_BISON_CHECK.
56 AT_CHECK([LC_ALL=en_US.UTF-8 $5 bison -fcaret -Wall input.y], [$3], [], [experr])
59 AT_BISON_OPTION_POPDEFS
76 [[input.y:9.12-14: <warning>warning:</warning> symbol FOO redeclared [<warning>-Wother</warning>]
77 9 | %token FOO <warning>FOO</warning> FOO
78 | <warning>^~~</warning>
79 input.y:9.8-10: previous declaration
80 9 | %token <note>FOO</note> FOO FOO
82 input.y:9.16-18: <warning>warning:</warning> symbol FOO redeclared [<warning>-Wother</warning>]
83 9 | %token FOO FOO <warning>FOO</warning>
84 | <warning>^~~</warning>
85 input.y:9.8-10: previous declaration
86 9 | %token <note>FOO</note> FOO FOO
88 input.y:10.8-10: <warning>warning:</warning> symbol FOO redeclared [<warning>-Wother</warning>]
89 10 | %token <warning>FOO</warning> FOO FOO
90 | <warning>^~~</warning>
91 input.y:9.8-10: previous declaration
92 9 | %token <note>FOO</note> FOO FOO
94 input.y:10.13-15: <warning>warning:</warning> symbol FOO redeclared [<warning>-Wother</warning>]
95 10 | %token FOO <warning>FOO</warning> FOO
96 | <warning>^~~</warning>
97 input.y:9.8-10: previous declaration
98 9 | %token <note>FOO</note> FOO FOO
100 input.y:10.18-20: <warning>warning:</warning> symbol FOO redeclared [<warning>-Wother</warning>]
101 10 | %token FOO FOO <warning>FOO</warning>
102 | <warning>^~~</warning>
103 input.y:9.8-10: previous declaration
104 9 | %token <note>FOO</note> FOO FOO
109 ## ------------------------ ##
110 ## Single point locations. ##
111 ## ------------------------ ##
113 # Single point locations (equal boundaries) are troublesome: it's easy
114 # to mess up the opening/closing of style. They come from the parser,
115 # rules with empty rhs. Their position is therefore debatable
116 # (between the previous token and the next one).
118 AT_TEST([[Single point locations]],
130 [[input.y:11.4-5: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
131 11 | a: <warning>{}</warning>
132 | <warning>^~</warning>
133 | <fixit-insert>%empty</fixit-insert>
134 input.y:12.3-13.1: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
135 12 | b:<warning>{</warning>
136 | <warning>^</warning>
137 | <fixit-insert>%empty</fixit-insert>
138 input.y:14.3: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
140 | <warning>^</warning>
141 | <fixit-insert>%empty</fixit-insert>
142 input.y:16.2: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
144 | <warning>^</warning>
145 | <fixit-insert>%empty</fixit-insert>
146 input.y:17.3: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
148 | <warning>^</warning>
149 | <fixit-insert>%empty</fixit-insert>
150 input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>]
154 ## -------------------------------------- ##
155 ## Tabulations and multibyte characters. ##
156 ## -------------------------------------- ##
158 # Make sure we treat tabulations as eight spaces, and that multibyte
159 # characters have correct width.
161 AT_TEST([[Tabulations and multibyte characters]],
174 [[input.y:11.4-17: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
175 11 | a: <warning>{ }</warning>
176 | <warning>^~~~~~~~~~~~~~</warning>
177 | <fixit-insert>%empty</fixit-insert>
178 input.y:12.4-17: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
179 12 | b: <warning>{ }</warning>
180 | <warning>^~~~~~~~~~~~~~</warning>
181 | <fixit-insert>%empty</fixit-insert>
182 input.y:13.4-17: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
183 13 | c: <warning>{------------}</warning>
184 | <warning>^~~~~~~~~~~~~~</warning>
185 | <fixit-insert>%empty</fixit-insert>
186 input.y:14.4-17: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
187 14 | d: <warning>{éééééééééééé}</warning>
188 | <warning>^~~~~~~~~~~~~~</warning>
189 | <fixit-insert>%empty</fixit-insert>
190 input.y:15.4-17: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
191 15 | e: <warning>{∇⃗×𝐸⃗ = -∂𝐵⃗/∂t}</warning>
192 | <warning>^~~~~~~~~~~~~~</warning>
193 | <fixit-insert>%empty</fixit-insert>
194 input.y:16.4-17: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
195 16 | f: <warning>{ 42 }</warning>
196 | <warning>^~~~~~~~~~~~~~</warning>
197 | <fixit-insert>%empty</fixit-insert>
198 input.y:17.4-17: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
199 17 | g: <warning>{ "฿¥$€₦" }</warning>
200 | <warning>^~~~~~~~~~~~~~</warning>
201 | <fixit-insert>%empty</fixit-insert>
202 input.y:18.4-17: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
203 18 | h: <warning>{ 🐃 }</warning>
204 | <warning>^~~~~~~~~~~~~~</warning>
205 | <fixit-insert>%empty</fixit-insert>
206 input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>]
210 ## --------------- ##
212 ## --------------- ##
214 # Don't try to quote special files.
215 # http://lists.gnu.org/archive/html/bug-bison/2019-04/msg00000.html
216 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90034
218 AT_TEST([[Special files]],
222 #line 1 "/dev/stdout"
226 [[input.y:11.4-5: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
227 11 | a: <warning>{}</warning>
228 | <warning>^~</warning>
229 | <fixit-insert>%empty</fixit-insert>
230 /dev/stdout:1.4-5: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
231 | <fixit-insert>%empty</fixit-insert>
232 /dev/stdout: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>]
236 ## ------------------- ##
237 ## Locations from M4. ##
238 ## ------------------- ##
240 # Locations coming from m4 need the byte-column for diagnostics.
242 AT_TEST([[Locations from M4]],
243 [[%define api.prefix {foo}
244 %define api.prefix {bar}
249 [[input.y:10.1-24: <error>error:</error> %define variable 'api.prefix' redefined
250 10 | <error>%define api.prefix {bar}</error>
251 | <error>^~~~~~~~~~~~~~~~~~~~~~~~</error>
252 input.y:9.1-24: previous definition
253 9 | <note>%define api.prefix {foo}</note>
254 | <note>^~~~~~~~~~~~~~~~~~~~~~~~</note>
255 input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>]
259 ## ---------------------------------------------- ##
260 ## Tabulations and multibyte characters from M4. ##
261 ## ---------------------------------------------- ##
263 # Locations coming from m4 need the byte-column for diagnostics.
265 AT_TEST([[Tabulations and multibyte characters from M4]],
266 [[%define api.prefix {sun}
267 %define api.prefix {🌞}
272 [[input.y:10.1-35: <error>error:</error> %define variable 'api.prefix' redefined
273 10 | <error>%define api.prefix {🌞}</error>
274 | <error>^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</error>
275 input.y:9.1-37: previous definition
276 9 | <note>%define api.prefix {sun}</note>
277 | <note>^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</note>
278 input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>]
282 ## ----------------- ##
283 ## Carriage return. ##
284 ## ----------------- ##
286 # Carriage-return used to count as a newline in the scanner, and not
287 # in diagnostics. Resulting in all sort of nice bugs.
289 AT_TEST([[Carriage return]],
290 [[^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M
295 [[input.y:10.8-11.0: <error>error:</error> missing '"' at end of line
296 10 | %token <error>"</error>
298 input.y:10.8-11.0: <error>error:</error> syntax error, unexpected string, expecting character literal or identifier or <tag>
299 10 | %token <error>"</error>
308 # Check Windows EOLs.
318 [[input.y:11.9-11: <warning>warning:</warning> symbol FOO redeclared [<warning>-Wother</warning>]
319 11 | %token
\r <warning>FOO</warning>
320 | <warning>^~~</warning>
321 input.y:10.9-11: previous declaration
322 10 | %token
\r <note>FOO</note>
324 input.y:13.5: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
326 | <warning>^</warning>
327 | <fixit-insert>%empty</fixit-insert>
328 input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>]
337 AT_TEST([[Screen width: 200 columns]],
338 [[%token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
341 exp: ABCDEFGHIJKLMNOPQRSTUVWXYZ
344 [[input.y:9.36-61: <warning>warning:</warning> symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [<warning>-Wother</warning>]
345 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ <warning>ABCDEFGHIJKLMNOPQRSTUVWXYZ</warning> ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
346 | <warning>^~~~~~~~~~~~~~~~~~~~~~~~~~</warning>
347 input.y:9.8-33: previous declaration
348 9 | %token <note>ABCDEFGHIJKLMNOPQRSTUVWXYZ</note> ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
349 | <note>^~~~~~~~~~~~~~~~~~~~~~~~~~</note>
350 input.y:9.64-89: <warning>warning:</warning> symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [<warning>-Wother</warning>]
351 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ <warning>ABCDEFGHIJKLMNOPQRSTUVWXYZ</warning> ABCDEFGHIJKLMNOPQRSTUVWXYZ
352 | <warning>^~~~~~~~~~~~~~~~~~~~~~~~~~</warning>
353 input.y:9.8-33: previous declaration
354 9 | %token <note>ABCDEFGHIJKLMNOPQRSTUVWXYZ</note> ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
355 | <note>^~~~~~~~~~~~~~~~~~~~~~~~~~</note>
356 input.y:9.92-117: <warning>warning:</warning> symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [<warning>-Wother</warning>]
357 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ <warning>ABCDEFGHIJKLMNOPQRSTUVWXYZ</warning>
358 | <warning>^~~~~~~~~~~~~~~~~~~~~~~~~~</warning>
359 input.y:9.8-33: previous declaration
360 9 | %token <note>ABCDEFGHIJKLMNOPQRSTUVWXYZ</note> ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
361 | <note>^~~~~~~~~~~~~~~~~~~~~~~~~~</note>
362 input.y:10.56-69: <warning>warning:</warning> deprecated directive: '%error-verbose', use '%define parse.error verbose' [<warning>-Wdeprecated</warning>]
363 10 | <warning>%error-verbose</warning>
364 | <warning>^~~~~~~~~~~~~~</warning>
365 | <fixit-insert>%define parse.error verbose</fixit-insert>
366 input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>]
370 AT_TEST([[Screen width: 80 columns]],
371 [[%token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
374 exp: ABCDEFGHIJKLMNOPQRSTUVWXYZ
377 [[input.y:9.36-61: <warning>warning:</warning> symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [<warning>-Wother</warning>]
378 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ <warning>ABCDEFGHIJKLMNOPQRSTUVWXYZ</warning> ABCDEF...
379 | <warning>^~~~~~~~~~~~~~~~~~~~~~~~~~</warning>
380 input.y:9.8-33: previous declaration
381 9 | %token <note>ABCDEFGHIJKLMNOPQRSTUVWXYZ</note> ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEF...
382 | <note>^~~~~~~~~~~~~~~~~~~~~~~~~~</note>
383 input.y:9.64-89: <warning>warning:</warning> symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [<warning>-Wother</warning>]
384 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ <warning>ABCDEF</warning>...
385 | <warning>^~~~~~</warning>
386 input.y:9.8-33: previous declaration
387 9 | %token <note>ABCDEFGHIJKLMNOPQRSTUVWXYZ</note> ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEF...
388 | <note>^~~~~~~~~~~~~~~~~~~~~~~~~~</note>
389 input.y:9.92-117: <warning>warning:</warning> symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [<warning>-Wother</warning>]
390 9 | ...TUVWXYZ <warning>ABCDEFGHIJKLMNOPQRSTUVWXYZ</warning>
391 | <warning>^~~~~~~~~~~~~~~~~~~~~~~~~~</warning>
392 input.y:9.8-33: previous declaration
393 9 | %token <note>ABCDEFGHIJKLMNOPQRSTUVWXYZ</note> ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEF...
394 | <note>^~~~~~~~~~~~~~~~~~~~~~~~~~</note>
395 input.y:10.56-69: <warning>warning:</warning> deprecated directive: '%error-verbose', use '%define parse.error verbose' [<warning>-Wdeprecated</warning>]
396 10 | <warning>%error-verbose</warning>
397 | <warning>^~~~~~~~~~~~~~</warning>
398 | <fixit-insert>%define parse.error verbose</fixit-insert>
399 input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>]
403 AT_TEST([[Screen width: 60 columns]],
404 [[%token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ
407 exp: ABCDEFGHIJKLMNOPQRSTUVWXYZ
410 [[input.y:9.36-61: <warning>warning:</warning> symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [<warning>-Wother</warning>]
411 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ <warning>ABCDEFGHIJKLMN</warning>...
412 | <warning>^~~~~~~~~~~~~~</warning>
413 input.y:9.8-33: previous declaration
414 9 | %token <note>ABCDEFGHIJKLMNOPQRSTUVWXYZ</note> ABCDEFGHIJKLMN...
415 | <note>^~~~~~~~~~~~~~~~~~~~~~~~~~</note>
416 input.y:9.64-89: <warning>warning:</warning> symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [<warning>-Wother</warning>]
417 9 | ...TUVWXYZ <warning>ABCDEFGHIJKLMNOPQRSTUVWXYZ</warning> ABCDEFGHI...
418 | <warning>^~~~~~~~~~~~~~~~~~~~~~~~~~</warning>
419 input.y:9.8-33: previous declaration
420 9 | %token <note>ABCDEFGHIJKLMNOPQRSTUVWXYZ</note> ABCDEFGHIJKLMN...
421 | <note>^~~~~~~~~~~~~~~~~~~~~~~~~~</note>
422 input.y:9.92-117: <warning>warning:</warning> symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [<warning>-Wother</warning>]
423 9 | ...TUVWXYZ <warning>ABCDEFGHIJKLMNOPQRSTUVWXYZ</warning>
424 | <warning>^~~~~~~~~~~~~~~~~~~~~~~~~~</warning>
425 input.y:9.8-33: previous declaration
426 9 | %token <note>ABCDEFGHIJKLMNOPQRSTUVWXYZ</note> ABCDEFGHIJKLMN...
427 | <note>^~~~~~~~~~~~~~~~~~~~~~~~~~</note>
428 input.y:10.56-69: <warning>warning:</warning> deprecated directive: '%error-verbose', use '%define parse.error verbose' [<warning>-Wdeprecated</warning>]
429 10 | ... <warning>%error-verbose</warning>
430 | <warning>^~~~~~~~~~~~~~</warning>
431 | <fixit-insert>%define parse.error verbose</fixit-insert>
432 input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>]
441 # Don't suggest to fix QUX with QUUX and QUUX with QUX...
442 AT_TEST([[Suggestions]],
448 [[input.y:10.6-8: <error>error:</error> symbol 'QUX' is used, but is not defined as a token and has no rules
449 10 | res: <error>QUX</error> baz
451 input.y:10.10-12: <error>error:</error> symbol 'baz' is used, but is not defined as a token and has no rules; did you mean 'bar'?
452 10 | res: QUX <error>baz</error>
454 | <fixit-insert>bar</fixit-insert>
455 input.y:11.6-9: <error>error:</error> symbol 'QUUX' is used, but is not defined as a token and has no rules
456 11 | bar: <error>QUUX</error>
457 | <error>^~~~</error>
469 ## -------------------------------------- ##
470 ## Indentation with message suppression. ##
471 ## -------------------------------------- ##
473 AT_SETUP([[Indentation with message suppression]])
475 # https://lists.gnu.org/archive/html/bug-bison/2019-08/msg00002.html
485 AT_BISON_CHECK([[-fcaret -Wno-other input.y]], [0], [],
486 [[input.y:2.1-12: warning: deprecated directive: '%pure-parser', use '%define api.pure' [-Wdeprecated]
490 input.y:3.1-14: warning: deprecated directive: '%error-verbose', use '%define parse.error verbose' [-Wdeprecated]
493 | %define parse.error verbose