Skip to content

Commit

Permalink
Forbid use of any/all with a deferred expression; only accept BLOCK
Browse files Browse the repository at this point in the history
  • Loading branch information
leonerd committed Nov 22, 2024
1 parent 588fb05 commit 56de829
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
18 changes: 18 additions & 0 deletions op.c
Original file line number Diff line number Diff line change
Expand Up @@ -13228,6 +13228,24 @@ Perl_ck_grep(pTHX_ OP *o)
Perl_croak(aTHX_ "panic: ck_grep, type=%u", (unsigned) kid->op_type);
kid = kUNOP->op_first;

switch(o->op_type) {
case OP_ANYSTART:
case OP_ALLSTART:
/* any { BLOCK } would create an OP_NULL[OP_SCOPE[...]] or
* OP_NULL[OP_LEAVE[...]] here. If we don't see this structure
* then it must have been any EXPR, ... which we forbid
* TODO: See if we can forbid this somehow in perly.y itself
*/
if(!OP_TYPE_IS(kid, OP_NULL) ||
!(OP_TYPE_IS(kUNOP->op_first, OP_SCOPE) || OP_TYPE_IS(kUNOP->op_first, OP_LEAVE))) {
/* diag_listed_as: any EXPR, LIST is not allowed */
/* diag_listed_as: all EXPR, LIST is not allowed */
croak("%s EXPR, LIST is not allowed",
o->op_type == OP_ANYSTART ? "any" : "all");
}
break;
}

gwop = alloc_LOGOP(type, o, LINKLIST(kid));
kid->op_next = (OP*)gwop;
o->op_private = gwop->op_private = 0;
Expand Down
16 changes: 16 additions & 0 deletions pod/perldiag.pod
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ removed in a future Perl version:
use feature "refaliasing";
\$x = \$y;

=item all EXPR, LIST is not allowed

(F) An attempt was made to use the C<all> keyword with a deferred expression,
which is permitted for C<grep> but not for C<all>. You need to put the
expression in a block instead, as

$result = all { EXPR } LIST;

=item all is experimental

(S experimental::any_all) This warning is emitted if you use the C<all>
Expand Down Expand Up @@ -188,6 +196,14 @@ which 'splits' output into two streams, such as
}
close OUT;

=item any EXPR, LIST is not allowed

(F) An attempt was made to use the C<any> keyword with a deferred expression,
which is permitted for C<grep> but not for C<any>. You need to put the
expression in a block instead, as

$result = any { EXPR } LIST;

=item any is experimental

(S experimental::any_all) This warning is emitted if you use the C<any>
Expand Down
14 changes: 14 additions & 0 deletions t/lib/croak/op
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,17 @@ use 5.012;
use 5.010;
EXPECT
Downgrading a use VERSION declaration to below v5.11 is not permitted at - line 3.
########
# any with deferred LIST expression
use feature 'any_all';
no warnings 'experimental::any_all';
any length, qw( a b c )
EXPECT
any EXPR, LIST is not allowed at - line 4.
########
# all with deferred LIST expression
use feature 'any_all';
no warnings 'experimental::any_all';
all length, qw( a b c )
EXPECT
all EXPR, LIST is not allowed at - line 4.

0 comments on commit 56de829

Please sign in to comment.