Skip to content

Commit

Permalink
Silence -Wmatch-empty-string on trivial obviously nullable cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
skvadrik committed Sep 10, 2020
1 parent 960f881 commit ee125da
Show file tree
Hide file tree
Showing 80 changed files with 42 additions and 93 deletions.
1 change: 0 additions & 1 deletion examples/c/conditions/parse_u32_blocks.c
Expand Up @@ -242,4 +242,3 @@ int main()
assert(parse_u32("") == ERROR);
return 0;
}
c/conditions/parse_u32_blocks.re:29:23: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion examples/c/conditions/parse_u32_conditions.c
Expand Up @@ -250,4 +250,3 @@ int main()
assert(parse_u32("") == ERROR);
return 0;
}
c/conditions/parse_u32_conditions.re:33:30: warning: rule in condition 'init' matches empty string [-Wmatch-empty-string]
3 changes: 0 additions & 3 deletions examples/c/real_world/cxx98.c
Expand Up @@ -8349,7 +8349,4 @@ int main()
remove(fname);
return 0;
}
c/real_world/cxx98.re:152:14: warning: rule matches empty string [-Wmatch-empty-string]
c/real_world/cxx98.re:158:14: warning: rule matches empty string [-Wmatch-empty-string]
c/real_world/cxx98.re:163:14: warning: rule matches empty string [-Wmatch-empty-string]
c/real_world/cxx98.re:349:24: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion examples/go/conditions/parse_u32_blocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion examples/go/conditions/parse_u32_conditions.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 21 additions & 1 deletion src/regexp/nullable.cc
Expand Up @@ -92,6 +92,21 @@ static bool nullable(const RESpec &spec, std::vector<StackItem> &stack, const RE
return null;
}

static bool trivially_nullable(const RESpec &spec, const RE *re)
{
// "" { ... }
if (re->type == RE::NIL) return true;

// "" / ... { ... }
if (re->type == RE::CAT
&& re->cat.re1->type == RE::NIL
&& re->cat.re2->type == RE::CAT
&& re->cat.re2->cat.re1->type == RE::TAG
&& trailing(spec.tags[re->cat.re2->cat.re1->tag.idx])) return true;

return false;
}

} // anonymous namespace

// Warn about rules that match empty string (including rules with nonempty
Expand All @@ -104,7 +119,12 @@ void warn_nullable(const RESpec &spec, const std::string &cond)
std::vector<StackItem> stack;
const size_t nre = spec.res.size();
for (size_t i = 0; i < nre; ++i) {
if (nullable(spec, stack, spec.res[i])) {
const RE *re = spec.res[i];
if (trivially_nullable(spec, re)) {
// Exclude trivial obviously nullable cases like "", as they are
// often used as a non-consuming default rule. This also captures
// empty character classes, but they are covered by another warning.
} else if (nullable(spec, stack, re)) {
spec.msg.warn.match_empty_string(spec.rules[i].semact->loc, cond);
}
}
Expand Down
1 change: 0 additions & 1 deletion test/bug116.c
Expand Up @@ -21,5 +21,4 @@
}
#line 4 "bug116.re"

bug116.re:3:13: warning: rule matches empty string [-Wmatch-empty-string]
bug116.re:4:2: warning: control flow is undefined for strings that match '[\x0-\x60\x62-\xFF]', use default rule '*' [-Wundefined-control-flow]
1 change: 0 additions & 1 deletion test/bug119.c
Expand Up @@ -9,4 +9,3 @@
yy0:
{}

bug119.re:3:7: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug119_abort.c
Expand Up @@ -13,4 +13,3 @@
{}
}

bug119_abort.re:4:7: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug119_abort_bif.c
Expand Up @@ -11,4 +11,3 @@
yy0:
{}

bug119_abort_bif.re:4:7: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug119_abort_if.c
Expand Up @@ -11,4 +11,3 @@
yy0:
{}

bug119_abort_if.re:4:7: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug119_gif.c
Expand Up @@ -11,4 +11,3 @@
{}
}

bug119_gif.re:3:7: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug119_if.c
Expand Up @@ -9,4 +9,3 @@
yy0:
{}

bug119_if.re:3:7: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug46_infinite_loop.c
Expand Up @@ -52,5 +52,4 @@ int main(int argc, char** argv)
printf("exit 1\n");
return 0;
}
bug46_infinite_loop.re:14:4: warning: rule matches empty string [-Wmatch-empty-string]
bug46_infinite_loop.re:19:13: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug61_difference_full.c
Expand Up @@ -7,4 +7,3 @@
}

bug61_difference_full.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_difference_full.re:3:28: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug61_difference_full_i.c
Expand Up @@ -7,4 +7,3 @@
}

bug61_difference_full_i.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_difference_full_i.re:3:28: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug61_difference_negative_i.c
Expand Up @@ -7,4 +7,3 @@
}

bug61_difference_negative_i.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_difference_negative_i.re:3:30: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug61_difference_negative_i_empty_class_match_empty.c
Expand Up @@ -7,4 +7,3 @@
}

bug61_difference_negative_i_empty_class_match_empty.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_difference_negative_i_empty_class_match_empty.re:3:30: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug61_difference_positive.c
Expand Up @@ -7,4 +7,3 @@
}

bug61_difference_positive.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_difference_positive.re:3:10: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug61_difference_positive_i.c
Expand Up @@ -7,4 +7,3 @@
}

bug61_difference_positive_i.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_difference_positive_i.re:3:10: warning: rule matches empty string [-Wmatch-empty-string]
5 changes: 0 additions & 5 deletions test/bug61_i.c
Expand Up @@ -35,12 +35,7 @@
}

bug61_i.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_i.re:3:7: warning: rule matches empty string [-Wmatch-empty-string]
bug61_i.re:7:4: warning: empty character class [-Wempty-character-class]
bug61_i.re:7:17: warning: rule matches empty string [-Wmatch-empty-string]
bug61_i.re:11:4: warning: empty character class [-Wempty-character-class]
bug61_i.re:11:28: warning: rule matches empty string [-Wmatch-empty-string]
bug61_i.re:15:4: warning: empty character class [-Wempty-character-class]
bug61_i.re:15:10: warning: rule matches empty string [-Wmatch-empty-string]
bug61_i.re:19:4: warning: empty character class [-Wempty-character-class]
bug61_i.re:19:30: warning: rule matches empty string [-Wmatch-empty-string]
5 changes: 0 additions & 5 deletions test/bug61_i_empty_class_match_empty.c
Expand Up @@ -35,12 +35,7 @@
}

bug61_i_empty_class_match_empty.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_i_empty_class_match_empty.re:3:7: warning: rule matches empty string [-Wmatch-empty-string]
bug61_i_empty_class_match_empty.re:7:4: warning: empty character class [-Wempty-character-class]
bug61_i_empty_class_match_empty.re:7:17: warning: rule matches empty string [-Wmatch-empty-string]
bug61_i_empty_class_match_empty.re:11:4: warning: empty character class [-Wempty-character-class]
bug61_i_empty_class_match_empty.re:11:28: warning: rule matches empty string [-Wmatch-empty-string]
bug61_i_empty_class_match_empty.re:15:4: warning: empty character class [-Wempty-character-class]
bug61_i_empty_class_match_empty.re:15:10: warning: rule matches empty string [-Wmatch-empty-string]
bug61_i_empty_class_match_empty.re:19:4: warning: empty character class [-Wempty-character-class]
bug61_i_empty_class_match_empty.re:19:30: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug61_negative.c
Expand Up @@ -7,4 +7,3 @@
}

bug61_negative.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_negative.re:3:17: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug61_negative_i_empty_class_match_empty.c
Expand Up @@ -7,4 +7,3 @@
}

bug61_negative_i_empty_class_match_empty.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_negative_i_empty_class_match_empty.re:3:17: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug61_positive.c
Expand Up @@ -7,4 +7,3 @@
}

bug61_positive.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_positive.re:3:7: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/bug61_positive_i_empty_class_match_empty.c
Expand Up @@ -7,4 +7,3 @@
}

bug61_positive_i_empty_class_match_empty.re:3:4: warning: empty character class [-Wempty-character-class]
bug61_positive_i_empty_class_match_empty.re:3:7: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/encodings/default_dup_star_1.c
Expand Up @@ -28,5 +28,4 @@
{ return DEFAULT-*; }
}

encodings/default_dup_star_1.re:5:9: warning: rule in condition 'c3' matches empty string [-Wmatch-empty-string]
encodings/default_dup_star_1.re:5:9: warning: unreachable rule in condition 'c3' (shadowed by rule at line 6) [-Wunreachable-rules]
1 change: 0 additions & 1 deletion test/encodings/range_empty.c
Expand Up @@ -12,4 +12,3 @@
#line 4 "encodings/range_empty.re"

encodings/range_empty.re:3:1: warning: empty character class [-Wempty-character-class]
encodings/range_empty.re:3:4: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/encodings/range_empty_8.c
Expand Up @@ -12,4 +12,3 @@
#line 4 "encodings/range_empty_8.re"

encodings/range_empty_8.re:3:1: warning: empty character class [-Wempty-character-class]
encodings/range_empty_8.re:3:4: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/encodings/range_empty_e.c
Expand Up @@ -12,4 +12,3 @@
#line 4 "encodings/range_empty_e.re"

encodings/range_empty_e.re:3:1: warning: empty character class [-Wempty-character-class]
encodings/range_empty_e.re:3:4: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/encodings/range_empty_u.c
Expand Up @@ -12,4 +12,3 @@
#line 4 "encodings/range_empty_u.re"

encodings/range_empty_u.re:3:1: warning: empty character class [-Wempty-character-class]
encodings/range_empty_u.re:3:4: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/encodings/range_empty_w.c
Expand Up @@ -12,4 +12,3 @@
#line 4 "encodings/range_empty_w.re"

encodings/range_empty_w.re:3:1: warning: empty character class [-Wempty-character-class]
encodings/range_empty_w.re:3:4: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/encodings/range_empty_x.c
Expand Up @@ -12,4 +12,3 @@
#line 4 "encodings/range_empty_x.re"

encodings/range_empty_x.re:3:1: warning: empty character class [-Wempty-character-class]
encodings/range_empty_x.re:3:4: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/eof/eof_11_multiblock.c
Expand Up @@ -339,4 +339,3 @@ int main()
assert(lex("aa b cc", count) == 2);
return 0;
}
eof/eof_11_multiblock.re:25:19: warning: rule matches empty string [-Wmatch-empty-string]
2 changes: 0 additions & 2 deletions test/eof/shadowrule_04_hoist.c
Expand Up @@ -60,6 +60,4 @@
{ /* EOF - here 'x' must not be set */ }
}

eof/shadowrule_04_hoist.re:6:12: warning: rule matches empty string [-Wmatch-empty-string]
eof/shadowrule_04_hoist.re:6:12: warning: unreachable rule (shadowed by rule at line 5) [-Wunreachable-rules]
eof/shadowrule_04_hoist.re:14:12: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/golang/009_conditions.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion test/input4.c
Expand Up @@ -14,6 +14,5 @@
#line 8 "input4.re"

input4.re:4:0: warning: empty character class [-Wempty-character-class]
input4.re:4:5: warning: rule matches empty string [-Wmatch-empty-string]
input4.re:4:5: warning: unreachable rule (shadowed by rule at line 5) [-Wunreachable-rules]
input4.re:6:12: warning: unreachable rule (shadowed by rule at line 5) [-Wunreachable-rules]
1 change: 0 additions & 1 deletion test/input4__empty_class_match_empty.c
Expand Up @@ -14,6 +14,5 @@
#line 8 "input4__empty_class_match_empty.re"

input4__empty_class_match_empty.re:4:0: warning: empty character class [-Wempty-character-class]
input4__empty_class_match_empty.re:4:5: warning: rule matches empty string [-Wmatch-empty-string]
input4__empty_class_match_empty.re:4:5: warning: unreachable rule (shadowed by rule at line 5) [-Wunreachable-rules]
input4__empty_class_match_empty.re:6:12: warning: unreachable rule (shadowed by rule at line 5) [-Wunreachable-rules]
1 change: 0 additions & 1 deletion test/input6.c
Expand Up @@ -15,5 +15,4 @@

input6.re:4:0: warning: empty character class [-Wempty-character-class]
input6.re:4:3: warning: empty character class [-Wempty-character-class]
input6.re:4:12: warning: rule matches empty string [-Wmatch-empty-string]
input6.re:4:12: warning: unreachable rule (shadowed by rule at line 5) [-Wunreachable-rules]
1 change: 0 additions & 1 deletion test/input6__empty_class_match_empty.c
Expand Up @@ -15,5 +15,4 @@

input6__empty_class_match_empty.re:4:0: warning: empty character class [-Wempty-character-class]
input6__empty_class_match_empty.re:4:3: warning: empty character class [-Wempty-character-class]
input6__empty_class_match_empty.re:4:12: warning: rule matches empty string [-Wmatch-empty-string]
input6__empty_class_match_empty.re:4:12: warning: unreachable rule (shadowed by rule at line 5) [-Wunreachable-rules]
22 changes: 19 additions & 3 deletions test/messages/nullable.c
Expand Up @@ -6,16 +6,32 @@
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'b': goto yy3;
case 'a': goto yy3;
case 'b': goto yy6;
default: goto yy2;
}
yy2:
{}
yy3:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy3;
case 'b': goto yy8;
default: goto yy5;
}
yy5:
{}
yy6:
++YYCURSOR;
YYCURSOR -= 1;
{}
yy8:
++YYCURSOR;
YYCURSOR -= 1;
{}
}

messages/nullable.re:4:9: warning: rule matches empty string [-Wmatch-empty-string]
messages/nullable.re:5:3: warning: rule matches empty string [-Wmatch-empty-string]
messages/nullable.re:6:11: warning: rule matches empty string [-Wmatch-empty-string]
messages/nullable.re:7:5: warning: rule matches empty string [-Wmatch-empty-string]
2 changes: 2 additions & 0 deletions test/messages/nullable.re
Expand Up @@ -3,5 +3,7 @@
"" / "b" {}
"" {}
"a"* / "b" {}
"a"* {}
*/
1 change: 0 additions & 1 deletion test/real_world/rexx.c
Expand Up @@ -6908,4 +6908,3 @@ bool StripToken(){
}
real_world/rexx.re:254:5: warning: rule matches empty string [-Wmatch-empty-string]
real_world/rexx.re:289:0: warning: empty character class [-Wempty-character-class]
real_world/rexx.re:290:5: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/real_world/rexx__empty_class_match_empty.c
Expand Up @@ -6908,4 +6908,3 @@ bool StripToken(){
}
real_world/rexx__empty_class_match_empty.re:254:5: warning: rule matches empty string [-Wmatch-empty-string]
real_world/rexx__empty_class_match_empty.re:289:0: warning: empty character class [-Wempty-character-class]
real_world/rexx__empty_class_match_empty.re:290:5: warning: rule matches empty string [-Wmatch-empty-string]
2 changes: 0 additions & 2 deletions test/repeater2.c
Expand Up @@ -357,7 +357,6 @@
}
#line 52 "repeater2.re"

repeater2.re:3:8: warning: rule matches empty string [-Wmatch-empty-string]
repeater2.re:8:2: warning: control flow is undefined for strings that match '[\x0-\x60\x62-\xFF]', use default rule '*' [-Wundefined-control-flow]
repeater2.re:12:2: warning: control flow is undefined for strings that match
'[\x0-\x60\x62-\xFF]'
Expand All @@ -371,7 +370,6 @@ repeater2.re:24:2: warning: control flow is undefined for strings that match
'\x61 [\x0-\x60\x62-\xFF]'
'\x61 \x61 [\x0-\x60\x62-\xFF]'
, use default rule '*' [-Wundefined-control-flow]
repeater2.re:27:10: warning: rule matches empty string [-Wmatch-empty-string]
repeater2.re:31:10: warning: rule matches empty string [-Wmatch-empty-string]
repeater2.re:36:2: warning: control flow is undefined for strings that match '[\x0-\x60\x62-\xFF]', use default rule '*' [-Wundefined-control-flow]
repeater2.re:40:2: warning: control flow is undefined for strings that match '[\x0-\x60\x62-\xFF]', use default rule '*' [-Wundefined-control-flow]
Expand Down
1 change: 0 additions & 1 deletion test/stadfa/stadfa_01.c
Expand Up @@ -39,4 +39,3 @@
}
}

stadfa/stadfa_01.re:4:3: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_02.c
Expand Up @@ -26,5 +26,4 @@
}

stadfa/stadfa_02.re:3:10: warning: rule matches empty string [-Wmatch-empty-string]
stadfa/stadfa_02.re:4:3: warning: rule matches empty string [-Wmatch-empty-string]
stadfa/stadfa_02.re:4:3: warning: unreachable rule (shadowed by rule at line 3) [-Wunreachable-rules]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_03.c
Expand Up @@ -21,5 +21,4 @@
}

stadfa/stadfa_03.re:3:9: warning: rule matches empty string [-Wmatch-empty-string]
stadfa/stadfa_03.re:4:3: warning: rule matches empty string [-Wmatch-empty-string]
stadfa/stadfa_03.re:4:3: warning: unreachable rule (shadowed by rule at line 3) [-Wunreachable-rules]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_04.c
Expand Up @@ -27,4 +27,3 @@
{}
}

stadfa/stadfa_04.re:4:3: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_05.c
Expand Up @@ -24,4 +24,3 @@
goto yy4;
}

stadfa/stadfa_05.re:4:3: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_06.c
Expand Up @@ -38,4 +38,3 @@
goto yy4;
}

stadfa/stadfa_06.re:4:3: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_07.c
Expand Up @@ -36,5 +36,4 @@
}

stadfa/stadfa_07.re:4:13: warning: rule matches empty string [-Wmatch-empty-string]
stadfa/stadfa_07.re:5:3: warning: rule matches empty string [-Wmatch-empty-string]
stadfa/stadfa_07.re:5:3: warning: unreachable rule (shadowed by rule at line 4) [-Wunreachable-rules]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_08.c
Expand Up @@ -40,4 +40,3 @@
{}
}

stadfa/stadfa_08.re:4:3: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_09.c
Expand Up @@ -38,4 +38,3 @@
goto yy6;
}

stadfa/stadfa_09.re:4:3: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_10.c
Expand Up @@ -56,4 +56,3 @@
{}
}

stadfa/stadfa_10.re:5:3: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_11.c
Expand Up @@ -63,5 +63,4 @@
}

stadfa/stadfa_11.re:3:9: warning: rule matches empty string [-Wmatch-empty-string]
stadfa/stadfa_11.re:5:3: warning: rule matches empty string [-Wmatch-empty-string]
stadfa/stadfa_11.re:5:3: warning: unreachable rule (shadowed by rule at line 3) [-Wunreachable-rules]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_12.c
Expand Up @@ -43,4 +43,3 @@
}
}

stadfa/stadfa_12.re:4:3: warning: rule matches empty string [-Wmatch-empty-string]
1 change: 0 additions & 1 deletion test/stadfa/stadfa_13.c
Expand Up @@ -48,4 +48,3 @@
}
}

stadfa/stadfa_13.re:4:3: warning: rule matches empty string [-Wmatch-empty-string]

0 comments on commit ee125da

Please sign in to comment.