diff options
author | Karl Williamson <khw@cpan.org> | 2014-06-17 09:39:51 -0600 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2014-06-17 09:54:50 -0600 |
commit | b3211734a7d280a8b7c6acaaba333f8f6a314675 (patch) | |
tree | 6757b4dd98bba1bb29c215588121d22914f175e3 | |
parent | e21c1f156f378627d5dcc0a326f14b0a11d80fde (diff) | |
download | perl-b3211734a7d280a8b7c6acaaba333f8f6a314675.tar.gz |
PATCH: [perl #121816] Add warning for repetition x < 0
I consider this experimental, so that if code breaks as a result, we
will remove it.
I chose the numeric warnings category. But misc or a new subcategory of
numeric might be better choices.
There is also the issue if someone is calculating the repeat count in
floating point and gets something that would be 0 if there were infinite
precision, but ends up being a very small negative number. The current
implementation will warn on that, but probably shouldn't. I suspect that
this would be extremely rare in practice.
-rw-r--r-- | pod/perldelta.pod | 11 | ||||
-rw-r--r-- | pod/perldiag.pod | 6 | ||||
-rw-r--r-- | pp.c | 14 | ||||
-rw-r--r-- | t/lib/warnings/op | 12 |
4 files changed, 37 insertions, 6 deletions
diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 5639dd94e1..97d623107c 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -546,6 +546,17 @@ simply disable this warning: no warnings "experimental::win32_perlio"; +=item * + +L<Negative repeat count does nothing|perldiag/Negative repeat count does nothing> + +(W numeric) This warns when the repeat count of the +L<C<x>|perlop/Multiplicative Operators> repetition operator is +negative. + +This warning may be changed or removed if it turn out that it was +unwise to have added it. + =back =head2 Changes to Existing Diagnostics diff --git a/pod/perldiag.pod b/pod/perldiag.pod index ea9aab1511..8bd44acb09 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -3241,6 +3241,12 @@ length that is less than 0. This is difficult to imagine. (F) When C<vec> is called in an lvalue context, the second argument must be greater than or equal to zero. +=item Negative repeat count does nothing + +(W numeric) You tried to execute the +L<C<x>|perlop/Multiplicative Operators> repetition operator fewer than 0 +times, which doesn't make sense. + =item Nested quantifiers in regex; marked by S<<-- HERE> in m/%s/ (F) You can't quantify a quantifier without intervening parentheses. @@ -1656,23 +1656,25 @@ PP(pp_repeat) else count = uv; } else { - const IV iv = SvIV_nomg(sv); - if (iv < 0) - count = 0; - else - count = iv; + count = SvIV_nomg(sv); } } else if (SvNOKp(sv)) { const NV nv = SvNV_nomg(sv); if (nv < 0.0) - count = 0; + count = -1; /* An arbitrary negative integer */ else count = (IV)nv; } else count = SvIV_nomg(sv); + if (count < 0) { + count = 0; + Perl_ck_warner(aTHX_ packWARN(WARN_NUMERIC), + "Negative repeat count does nothing"); + } + if (GIMME == G_ARRAY && PL_op->op_private & OPpREPEAT_DOLIST) { dMARK; static const char* const oom_list_extend = "Out of memory during list extend"; diff --git a/t/lib/warnings/op b/t/lib/warnings/op index a6b311654d..364d7e08a7 100644 --- a/t/lib/warnings/op +++ b/t/lib/warnings/op @@ -1914,3 +1914,15 @@ sub bbb ($a) { 4 } $aaa = sub { 2 }; $bbb = sub ($a) { 4 }; EXPECT +######## +use warnings 'numeric'; +my $c = -4.5; +my $a = "y" x $c; +my $b = "y" x -3; +no warnings 'numeric'; +my $d = "y" x $c; +my $e = "y" x -3; +no warnings 'numeric'; +EXPECT +Negative repeat count does nothing at - line 3. +Negative repeat count does nothing at - line 4. |