-Wempty-rule: diagnose empty rules without %empty

* src/complain.h, src/complain.c (warning_empty_rule, Wempty_rule):
New warning category.
(warnings_args, warnings_types): Adjust.
* src/reader.c (grammar_rule_check): Check the empty rules are
flagged by %empty.
* tests/actions.at (Implicitly empty rule): New.
* tests/existing.at: Add expected warnings.
This commit is contained in:
Akim Demaille
2013-02-09 18:26:38 +01:00
parent 684083f065
commit f68a49ed49
6 changed files with 107 additions and 5 deletions

View File

@@ -63,6 +63,7 @@ static const char * const warnings_args[] =
"conflicts-sr", "conflicts-sr",
"conflicts-rr", "conflicts-rr",
"deprecated", "deprecated",
"empty-rule",
"precedence", "precedence",
"other", "other",
"all", "all",
@@ -78,6 +79,7 @@ static const int warnings_types[] =
Wconflicts_sr, Wconflicts_sr,
Wconflicts_rr, Wconflicts_rr,
Wdeprecated, Wdeprecated,
Wempty_rule,
Wprecedence, Wprecedence,
Wother, Wother,
Wall, Wall,

View File

@@ -35,6 +35,7 @@ typedef enum
warning_yacc, /**< POSIXME. */ warning_yacc, /**< POSIXME. */
warning_conflicts_sr, /**< S/R conflicts. */ warning_conflicts_sr, /**< S/R conflicts. */
warning_conflicts_rr, /**< R/R conflicts. */ warning_conflicts_rr, /**< R/R conflicts. */
warning_empty_rule, /**< Implicitly empty rules. */
warning_deprecated, /**< Obsolete constructs. */ warning_deprecated, /**< Obsolete constructs. */
warning_precedence, /**< Useless precedence and associativity. */ warning_precedence, /**< Useless precedence and associativity. */
warning_other, /**< All other warnings. */ warning_other, /**< All other warnings. */
@@ -85,6 +86,7 @@ typedef enum
Wconflicts_sr = 1 << warning_conflicts_sr, Wconflicts_sr = 1 << warning_conflicts_sr,
Wconflicts_rr = 1 << warning_conflicts_rr, Wconflicts_rr = 1 << warning_conflicts_rr,
Wdeprecated = 1 << warning_deprecated, Wdeprecated = 1 << warning_deprecated,
Wempty_rule = 1 << warning_empty_rule,
Wprecedence = 1 << warning_precedence, Wprecedence = 1 << warning_precedence,
Wother = 1 << warning_other, Wother = 1 << warning_other,

View File

@@ -327,6 +327,7 @@ Warning categories include:\n\
`conflicts-sr' S/R conflicts (enabled by default)\n\ `conflicts-sr' S/R conflicts (enabled by default)\n\
`conflicts-rr' R/R conflicts (enabled by default)\n\ `conflicts-rr' R/R conflicts (enabled by default)\n\
`deprecated' obsolete constructs\n\ `deprecated' obsolete constructs\n\
`empty-rule' empty rules without %empty\n\
`precedence' useless precedence and associativity\n\ `precedence' useless precedence and associativity\n\
`other' all other warnings (enabled by default)\n\ `other' all other warnings (enabled by default)\n\
`all' all the warnings\n\ `all' all the warnings\n\

View File

@@ -339,6 +339,12 @@ grammar_rule_check (const symbol_list *r)
complain (&r->percent_empty_loc, complaint, complain (&r->percent_empty_loc, complaint,
_("%%empty on non-empty rule")); _("%%empty on non-empty rule"));
/* Check that empty rule => %empty. */
if (!(r->next && r->next->content.sym)
&& !r->midrule_parent_rule
&& !r->percent_empty_loc.start.file)
complain (&r->location, Wempty_rule, _("empty rule without %%empty"));
/* See comments in grammar_current_rule_prec_set for how POSIX /* See comments in grammar_current_rule_prec_set for how POSIX
mandates this complaint. It's only for identifiers, so skip mandates this complaint. It's only for identifiers, so skip
it for char literals and strings, which are always tokens. */ it for char literals and strings, which are always tokens. */

View File

@@ -64,6 +64,28 @@ AT_PARSER_CHECK([./input], 0,
AT_CLEANUP AT_CLEANUP
## ----------------------- ##
## Implicitly empty rule. ##
## ----------------------- ##
AT_SETUP([Implicitly empty rule])
AT_DATA_GRAMMAR([[1.y]],
[[%%
exp: a b;
a: /* empty. */ {};
// A mid-rule action does not count as an empty rule.
b: {} {};
]])
AT_BISON_CHECK([-fcaret -Wempty-rule 1.y], [0], [],
[[1.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
a: /* empty. */ {};
^^
]])
AT_CLEANUP
## ------------------------ ## ## ------------------------ ##
## Invalid uses of %empty. ## ## Invalid uses of %empty. ##
## ------------------------ ## ## ------------------------ ##

View File

@@ -427,7 +427,17 @@ dnl don't like even `print $!4;'.
dnl BISON-STDERR dnl BISON-STDERR
[AT_COND_CASE([[canonical LR]], [AT_COND_CASE([[canonical LR]],
[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr] [[input.y:66.10: warning: empty rule without %empty [-Wempty-rule]
input.y:169.8: warning: empty rule without %empty [-Wempty-rule]
input.y:174.12: warning: empty rule without %empty [-Wempty-rule]
input.y:179.13: warning: empty rule without %empty [-Wempty-rule]
input.y:187.15: warning: empty rule without %empty [-Wempty-rule]
input.y:201.8: warning: empty rule without %empty [-Wempty-rule]
input.y:206.21: warning: empty rule without %empty [-Wempty-rule]
input.y:220.20: warning: empty rule without %empty [-Wempty-rule]
input.y:299.13: warning: empty rule without %empty [-Wempty-rule]
input.y:322.9: warning: empty rule without %empty [-Wempty-rule]
input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]
input.y:19.8-16: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence] input.y:19.8-16: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence]
input.y:21.8-14: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence] input.y:21.8-14: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence]
input.y:21.16-22: warning: useless associativity for YSTRING, use %precedence [-Wprecedence] input.y:21.16-22: warning: useless associativity for YSTRING, use %precedence [-Wprecedence]
@@ -446,7 +456,17 @@ input.y:47.12-16: warning: useless associativity for UNARY, use %precedence [-Wp
input.y:50.7-9: warning: useless associativity for '$', use %precedence [-Wprecedence] input.y:50.7-9: warning: useless associativity for '$', use %precedence [-Wprecedence]
input.y:51.7-9: warning: useless associativity for '(', use %precedence [-Wprecedence] input.y:51.7-9: warning: useless associativity for '(', use %precedence [-Wprecedence]
input.y:51.11-13: warning: useless precedence and associativity for ')' [-Wprecedence]]], input.y:51.11-13: warning: useless precedence and associativity for ')' [-Wprecedence]]],
[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr] [[input.y:66.10: warning: empty rule without %empty [-Wempty-rule]
input.y:169.8: warning: empty rule without %empty [-Wempty-rule]
input.y:174.12: warning: empty rule without %empty [-Wempty-rule]
input.y:179.13: warning: empty rule without %empty [-Wempty-rule]
input.y:187.15: warning: empty rule without %empty [-Wempty-rule]
input.y:201.8: warning: empty rule without %empty [-Wempty-rule]
input.y:206.21: warning: empty rule without %empty [-Wempty-rule]
input.y:220.20: warning: empty rule without %empty [-Wempty-rule]
input.y:299.13: warning: empty rule without %empty [-Wempty-rule]
input.y:322.9: warning: empty rule without %empty [-Wempty-rule]
input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]
input.y:19.8-16: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence] input.y:19.8-16: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence]
input.y:21.8-14: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence] input.y:21.8-14: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence]
input.y:21.16-22: warning: useless associativity for YSTRING, use %precedence [-Wprecedence] input.y:21.16-22: warning: useless associativity for YSTRING, use %precedence [-Wprecedence]
@@ -1404,7 +1424,29 @@ dnl INPUT
dnl BISON-STDERR dnl BISON-STDERR
[AT_COND_CASE([[canonical LR]], [AT_COND_CASE([[canonical LR]],
[[input.y: warning: 1876 shift/reduce conflicts [-Wconflicts-sr] [[input.y:128.12: warning: empty rule without %empty [-Wempty-rule]
input.y:137.10: warning: empty rule without %empty [-Wempty-rule]
input.y:142.8: warning: empty rule without %empty [-Wempty-rule]
input.y:161.15: warning: empty rule without %empty [-Wempty-rule]
input.y:179.17: warning: empty rule without %empty [-Wempty-rule]
input.y:205.16: warning: empty rule without %empty [-Wempty-rule]
input.y:213.9: warning: empty rule without %empty [-Wempty-rule]
input.y:225.6: warning: empty rule without %empty [-Wempty-rule]
input.y:292.18: warning: empty rule without %empty [-Wempty-rule]
input.y:294.19: warning: empty rule without %empty [-Wempty-rule]
input.y:367.16: warning: empty rule without %empty [-Wempty-rule]
input.y:373.11: warning: empty rule without %empty [-Wempty-rule]
input.y:387.15: warning: empty rule without %empty [-Wempty-rule]
input.y:401.18: warning: empty rule without %empty [-Wempty-rule]
input.y:413.15: warning: empty rule without %empty [-Wempty-rule]
input.y:443.15: warning: empty rule without %empty [-Wempty-rule]
input.y:471.15: warning: empty rule without %empty [-Wempty-rule]
input.y:474.15: warning: empty rule without %empty [-Wempty-rule]
input.y:489.15: warning: empty rule without %empty [-Wempty-rule]
input.y:506.14: warning: empty rule without %empty [-Wempty-rule]
input.y:587.9: warning: empty rule without %empty [-Wempty-rule]
input.y:591.14: warning: empty rule without %empty [-Wempty-rule]
input.y: warning: 1876 shift/reduce conflicts [-Wconflicts-sr]
input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr] input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]
input.y:32.9-12: warning: useless associativity for HQUA, use %precedence [-Wprecedence] input.y:32.9-12: warning: useless associativity for HQUA, use %precedence [-Wprecedence]
input.y:53.8-14: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence] input.y:53.8-14: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence]
@@ -1412,7 +1454,29 @@ input.y:54.9-15: warning: useless associativity for HORELSE, use %precedence [-W
input.y:55.9-16: warning: useless associativity for HANDTHEN, use %precedence [-Wprecedence] input.y:55.9-16: warning: useless associativity for HANDTHEN, use %precedence [-Wprecedence]
input.y:61.9-12: warning: useless associativity for HNOT, use %precedence [-Wprecedence] input.y:61.9-12: warning: useless associativity for HNOT, use %precedence [-Wprecedence]
input.y:68.7-11: warning: useless associativity for UNEAR, use %precedence [-Wprecedence]]], input.y:68.7-11: warning: useless associativity for UNEAR, use %precedence [-Wprecedence]]],
[[input.y: warning: 78 shift/reduce conflicts [-Wconflicts-sr] [[input.y:128.12: warning: empty rule without %empty [-Wempty-rule]
input.y:137.10: warning: empty rule without %empty [-Wempty-rule]
input.y:142.8: warning: empty rule without %empty [-Wempty-rule]
input.y:161.15: warning: empty rule without %empty [-Wempty-rule]
input.y:179.17: warning: empty rule without %empty [-Wempty-rule]
input.y:205.16: warning: empty rule without %empty [-Wempty-rule]
input.y:213.9: warning: empty rule without %empty [-Wempty-rule]
input.y:225.6: warning: empty rule without %empty [-Wempty-rule]
input.y:292.18: warning: empty rule without %empty [-Wempty-rule]
input.y:294.19: warning: empty rule without %empty [-Wempty-rule]
input.y:367.16: warning: empty rule without %empty [-Wempty-rule]
input.y:373.11: warning: empty rule without %empty [-Wempty-rule]
input.y:387.15: warning: empty rule without %empty [-Wempty-rule]
input.y:401.18: warning: empty rule without %empty [-Wempty-rule]
input.y:413.15: warning: empty rule without %empty [-Wempty-rule]
input.y:443.15: warning: empty rule without %empty [-Wempty-rule]
input.y:471.15: warning: empty rule without %empty [-Wempty-rule]
input.y:474.15: warning: empty rule without %empty [-Wempty-rule]
input.y:489.15: warning: empty rule without %empty [-Wempty-rule]
input.y:506.14: warning: empty rule without %empty [-Wempty-rule]
input.y:587.9: warning: empty rule without %empty [-Wempty-rule]
input.y:591.14: warning: empty rule without %empty [-Wempty-rule]
input.y: warning: 78 shift/reduce conflicts [-Wconflicts-sr]
input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr] input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]
input.y:32.9-12: warning: useless associativity for HQUA, use %precedence [-Wprecedence] input.y:32.9-12: warning: useless associativity for HQUA, use %precedence [-Wprecedence]
input.y:53.8-14: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence] input.y:53.8-14: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence]
@@ -2001,7 +2065,12 @@ dnl without being followed by "of".)
[[VARIABLE, '=', LABEL, LEFT, DOT_X]], [[VARIABLE, '=', LABEL, LEFT, DOT_X]],
dnl BISON-STDERR dnl BISON-STDERR
[[input.y:471.11-48: warning: rule useless in parser due to conflicts [-Wother] [[input.y:202.19: warning: empty rule without %empty [-Wempty-rule]
input.y:270.6: warning: empty rule without %empty [-Wempty-rule]
input.y:292.12: warning: empty rule without %empty [-Wempty-rule]
input.y:309.17: warning: empty rule without %empty [-Wempty-rule]
input.y:382.13: warning: empty rule without %empty [-Wempty-rule]
input.y:471.11-48: warning: rule useless in parser due to conflicts [-Wother]
input.y:19.8-12: warning: useless associativity for LABEL, use %precedence [-Wprecedence] input.y:19.8-12: warning: useless associativity for LABEL, use %precedence [-Wprecedence]
input.y:20.8-15: warning: useless associativity for VARIABLE, use %precedence [-Wprecedence] input.y:20.8-15: warning: useless associativity for VARIABLE, use %precedence [-Wprecedence]
input.y:21.8-13: warning: useless associativity for NUMBER, use %precedence [-Wprecedence] input.y:21.8-13: warning: useless associativity for NUMBER, use %precedence [-Wprecedence]