From 6f8bdce25df5669b0b200c2a3848a1c08a44eb79 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Sun, 27 Mar 2011 22:38:32 -0400 Subject: [PATCH] Add -Wconflicts-sr and -Wconflicts-rr. Thus, conflict reports are now affected by -Werror and -Wnone (unless %expect or %expect-rr is specified). Reported by George Neuner at . * NEWS (2.5): Document. * doc/bison.texinfo (Bison Options): Document. * src/complain.c, src/complain.h (set_warning_issued): Export function. * src/conflicts.c (conflicts_print): Suppress conflict report based on -Wno-conflicts-sr and -Wno-conflicts-rr, and treat conflicts as errors if -Werror. * src/getargs.c (warnings_flag): Initialize with warnings_conflicts_sr and warnings_conflicts_rr as well. (warnings_args, warnings_types): Add entries for warnings_conflicts_sr and warnings_conflicts_rr. (usage): Update. * src/getargs.h (enum warnings): Add entries for warnings_conflicts_sr and warnings_conflicts_rr. * tests/conflicts.at (-W versus %expect and %expect-rr): New test group. * tests/local.at (AT_BISON_CHECK_NO_XML): Update now that the conflict report can produce a "warnings being treated as errors" message. Also, check that stderr is now fully scrubbed by -Wnone when the exit status is 0. --- ChangeLog | 28 +++++++++++++ NEWS | 18 ++++++++ doc/bison.texinfo | 8 ++++ src/complain.c | 2 +- src/complain.h | 7 ++++ src/conflicts.c | 9 ++++ src/getargs.c | 9 +++- src/getargs.h | 4 +- tests/conflicts.at | 101 +++++++++++++++++++++++++++++++++++++++++++++ tests/local.at | 11 ++++- 10 files changed, 192 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index baa1d962..27c6a8d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2011-03-27 Joel E. Denny + + Add -Wconflicts-sr and -Wconflicts-rr. + Thus, conflict reports are now affected by -Werror and -Wnone + (unless %expect or %expect-rr is specified). Reported by George + Neuner at + . + * NEWS (2.5): Document. + * doc/bison.texinfo (Bison Options): Document. + * src/complain.c, src/complain.h (set_warning_issued): Export + function. + * src/conflicts.c (conflicts_print): Suppress conflict report + based on -Wno-conflicts-sr and -Wno-conflicts-rr, and treat + conflicts as errors if -Werror. + * src/getargs.c (warnings_flag): Initialize with + warnings_conflicts_sr and warnings_conflicts_rr as well. + (warnings_args, warnings_types): Add entries for + warnings_conflicts_sr and warnings_conflicts_rr. + (usage): Update. + * src/getargs.h (enum warnings): Add entries for + warnings_conflicts_sr and warnings_conflicts_rr. + * tests/conflicts.at (-W versus %expect and %expect-rr): New test + group. + * tests/local.at (AT_BISON_CHECK_NO_XML): Update now that the + conflict report can produce a "warnings being treated as errors" + message. Also, check that stderr is now fully scrubbed by -Wnone + when the exit status is 0. + 2011-03-27 Joel E. Denny Pacify maintainer-check-posix. diff --git a/NEWS b/NEWS index 7584f18e..3d02e031 100644 --- a/NEWS +++ b/NEWS @@ -309,6 +309,24 @@ Bison News bison -Wall,no-yacc gram.y +*** Bison now treats S/R and R/R conflicts like other warnings: + + Previously, conflict reports were independent of Bison's normal + warning system. Now, Bison recognizes the warning categories + "conflicts-sr" and "conflicts-rr". This change has important + consequences for the -W and --warnings command-line options. For + example: + + bison -Wno-conflicts-sr gram.y # S/R conflicts not reported + bison -Wno-conflicts-rr gram.y # R/R conflicts not reported + bison -Wnone gram.y # no conflicts are reported + bison -Werror gram.y # any conflict is an error + + However, as before, if the %expect or %expect-rr directive is + specified, an unexpected number of conflicts is an error, and an + expected number of conflicts is not reported, so -W and --warning + then have no effect on the conflict report. + *** The "none" category no longer disables a preceding "error": For example, for the following command line, Bison now reports diff --git a/doc/bison.texinfo b/doc/bison.texinfo index cb50a017..e0d5aa5b 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -8429,6 +8429,14 @@ be false alarms in existing grammars employing the Yacc constructs @item yacc Incompatibilities with POSIX Yacc. +@item conflicts-sr +@itemx conflicts-rr +S/R and R/R conflicts. These warnings are enabled by default. However, if +the @code{%expect} or @code{%expect-rr} directive is specified, an +unexpected number of conflicts is an error, and an expected number of +conflicts is not reported, so @option{-W} and @option{--warning} then have +no effect on the conflict report. + @item other All warnings not categorized above. These warnings are enabled by default. diff --git a/src/complain.c b/src/complain.c index 5629dd3a..5c07fb3d 100644 --- a/src/complain.c +++ b/src/complain.c @@ -94,7 +94,7 @@ error_message (location *loc, | Report a warning, and proceed. | `--------------------------------*/ -static void +void set_warning_issued (void) { static bool warning_issued = false; diff --git a/src/complain.h b/src/complain.h index 3d867f5e..07d401cb 100644 --- a/src/complain.h +++ b/src/complain.h @@ -25,6 +25,13 @@ extern "C" { # endif +/** Record that a warning is about to be issued, and treat it as an + error if warnings_flag & warnings_error. This is exported + only for the sake of Yacc-compatible conflict reports in conflicts.c. + All other warnings should be implemented in complain.c and should use + the normal warning format. */ +void set_warning_issued (void); + /** Informative messages, but we proceed. Report iff warnings_flag & warnings_other. */ diff --git a/src/conflicts.c b/src/conflicts.c index 0437670b..d8eddf0b 100644 --- a/src/conflicts.c +++ b/src/conflicts.c @@ -594,8 +594,17 @@ conflicts_print (void) return; /* Report the total number of conflicts on STDERR. */ + if (expected_sr_conflicts == -1 && expected_rr_conflicts == -1) + { + if (!(warnings_flag & warnings_conflicts_sr)) + src_total = 0; + if (!(warnings_flag & warnings_conflicts_rr)) + rrc_total = 0; + } if (src_total | rrc_total) { + if (expected_sr_conflicts == -1 && expected_rr_conflicts == -1) + set_warning_issued (); if (! yacc_flag) fprintf (stderr, "%s: ", current_file); conflict_report (stderr, src_total, rrc_total); diff --git a/src/getargs.c b/src/getargs.c index 772d7dfc..e1298f3e 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -63,7 +63,8 @@ bool glr_parser = false; int report_flag = report_none; int trace_flag = trace_none; -int warnings_flag = warnings_other; +int warnings_flag = warnings_conflicts_sr | warnings_conflicts_rr + | warnings_other; static struct bison_language const valid_languages[] = { { "c", "c-skel.m4", ".c", ".h", true }, @@ -234,6 +235,8 @@ static const char * const warnings_args[] = "none - no warnings", "midrule-values - unset or unused midrule values", "yacc - incompatibilities with POSIX Yacc", + "conflicts-sr - S/R conflicts", + "conflicts-rr - R/R conflicts", "other - all other warnings", "all - all of the above", "error - warnings are errors", @@ -245,6 +248,8 @@ static const int warnings_types[] = warnings_none, warnings_midrule_values, warnings_yacc, + warnings_conflicts_sr, + warnings_conflicts_rr, warnings_other, warnings_all, warnings_error @@ -335,6 +340,8 @@ Output:\n\ Warning categories include:\n\ `midrule-values' unset or unused midrule values\n\ `yacc' incompatibilities with POSIX Yacc\n\ + `conflicts-sr' S/R conflicts (enabled by default)\n\ + `conflicts-rr' R/R conflicts (enabled by default)\n\ `other' all other warnings (enabled by default)\n\ `all' all the warnings\n\ `no-CATEGORY' turn off warnings in CATEGORY\n\ diff --git a/src/getargs.h b/src/getargs.h index dc92584c..20a41437 100644 --- a/src/getargs.h +++ b/src/getargs.h @@ -123,7 +123,9 @@ enum warnings warnings_error = 1 << 0, /**< Warnings are treated as errors. */ warnings_midrule_values = 1 << 1, /**< Unset or unused midrule values. */ warnings_yacc = 1 << 2, /**< POSIXME. */ - warnings_other = 1 << 3, /**< All other warnings. */ + warnings_conflicts_sr = 1 << 3, /**< S/R conflicts. */ + warnings_conflicts_rr = 1 << 4, /**< R/R conflicts. */ + warnings_other = 1 << 5, /**< All other warnings. */ warnings_all = ~warnings_error /**< All above warnings. */ }; /** What warnings are issued. */ diff --git a/tests/conflicts.at b/tests/conflicts.at index e7a1c1c6..1fcd69b5 100644 --- a/tests/conflicts.at +++ b/tests/conflicts.at @@ -1440,3 +1440,104 @@ AT_CHECK([[cat input.output | sed -n '/^state 0$/,/^state 1$/p']], 0, state 1 ]]) AT_CLEANUP + + +## --------------------------------- ## +## -W versus %expect and %expect-rr ## +## --------------------------------- ## + +AT_SETUP([[-W versus %expect and %expect-rr]]) + +AT_DATA([[sr-rr.y]], +[[%glr-parser +%% +start: 'a' | A 'a' | B 'a' ; +A: ; +B: ; +]]) +AT_DATA([[sr.y]], +[[%glr-parser +%% +start: 'a' | A 'a' ; +A: ; +]]) +AT_DATA([[rr.y]], +[[%glr-parser +%% +start: A | B ; +A: ; +B: ; +]]) + +AT_BISON_CHECK([[sr-rr.y]], [[0]], [[]], +[[sr-rr.y: conflicts: 1 shift/reduce, 1 reduce/reduce +]]) +AT_BISON_CHECK([[-Wno-conflicts-sr sr-rr.y]], [[0]], [[]], +[[sr-rr.y: conflicts: 1 reduce/reduce +]]) +AT_BISON_CHECK([[-Wno-conflicts-rr sr-rr.y]], [[0]], [[]], +[[sr-rr.y: conflicts: 1 shift/reduce +]]) + +[for gram in sr-rr sr rr; do + for sr_exp_i in '' 0 1 2; do + for rr_exp_i in '' 0 1 2; do + test -z "$sr_exp_i" && test -z "$rr_exp_i" && continue + + # Build grammar file. + sr_exp=0 + rr_exp=0 + file=$gram + directives= + if test -n "$sr_exp_i"; then + sr_exp=$sr_exp_i + file=$file-expect-$sr_exp + directives="%expect $sr_exp" + fi + if test -n "$rr_exp_i"; then + rr_exp=$rr_exp_i + file=$file-expect-rr-$rr_exp + directives="$directives %expect-rr $rr_exp" + fi + file=$file.y + echo "$directives" > $file + cat $gram.y >> $file + + # Count actual conflicts. + conflicts= + sr_count=0 + rr_count=0 + if test $gram = sr || test $gram = sr-rr; then + conflicts="1 shift/reduce" + sr_count=1 + fi + if test $gram = rr || test $gram = sr-rr; then + if test -n "$conflicts"; then + conflicts="$conflicts, " + fi + conflicts="${conflicts}1 reduce/reduce" + rr_count=1 + fi + + # Run tests. + if test $sr_count -eq $sr_exp && test $rr_count -eq $rr_exp; then + ]AT_BISON_CHECK([[-Wnone $file]])[ + ]AT_BISON_CHECK([[-Werror $file]])[ + else + echo "$file: conflicts: $conflicts" > experr + if test $sr_count -ne $sr_exp; then + if test $sr_exp -ne 1; then s=s; else s= ; fi + echo "$file: expected $sr_exp shift/reduce conflict$s" >> experr + fi + if test $rr_count -ne $rr_exp; then + if test $rr_exp -ne 1; then s=s; else s= ; fi + echo "$file: expected $rr_exp reduce/reduce conflict$s" >> experr + fi + ]AT_BISON_CHECK([[-Wnone $file]], [[1]], [[]], [[experr]])[ + ]AT_BISON_CHECK([[-Werror $file]], [[1]], [[]], [[experr]])[ + fi + done + done +done] + +AT_CLEANUP diff --git a/tests/local.at b/tests/local.at index f08185a5..33f00fa5 100644 --- a/tests/local.at +++ b/tests/local.at @@ -301,6 +301,13 @@ m4_if(m4_bregexp([$4], [: warning: ]), [-1], [], sed -n '/: warning: /=' at-bison-check-warnings \ | sed -n 1p \ `" + at_bison_check_first_tmp="` \ + sed -n '/conflicts: [0-9].*reduce$/=' at-bison-check-warnings \ + | sed -n 1p \ + `" + if test $at_bison_check_first_tmp -lt $at_bison_check_first; then + at_bison_check_first=$at_bison_check_first_tmp + fi if test $at_bison_check_first -gt 1; then sed -n "1,`expr $at_bison_check_first - 1`"p \ at-bison-check-warnings > experr @@ -330,9 +337,9 @@ m4_if(m4_bregexp([$4], [: warning: ]), [-1], [], # -Werror doesn't change the exit status when -Wnone or # --warnings=none is specified. ]AT_CHECK(AT_QUELL_VALGRIND[[ bison ]$1[ -Wnone -Werror]], - [[0]], [expout], [ignore])[ + [[0]], [expout])[ ]AT_CHECK(AT_QUELL_VALGRIND[[ bison ]$1[ --warnings=none \ - -Werror]], [[0]], [expout], [ignore])[ + -Werror]], [[0]], [expout])[ # Restore caller's files. if test -f at-bison-check-expout.bak; then -- 2.45.2