Skip to content

Commit 56de829

Browse files
committed
Forbid use of any/all with a deferred expression; only accept BLOCK
1 parent 588fb05 commit 56de829

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

op.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13228,6 +13228,24 @@ Perl_ck_grep(pTHX_ OP *o)
1322813228
Perl_croak(aTHX_ "panic: ck_grep, type=%u", (unsigned) kid->op_type);
1322913229
kid = kUNOP->op_first;
1323013230

13231+
switch(o->op_type) {
13232+
case OP_ANYSTART:
13233+
case OP_ALLSTART:
13234+
/* any { BLOCK } would create an OP_NULL[OP_SCOPE[...]] or
13235+
* OP_NULL[OP_LEAVE[...]] here. If we don't see this structure
13236+
* then it must have been any EXPR, ... which we forbid
13237+
* TODO: See if we can forbid this somehow in perly.y itself
13238+
*/
13239+
if(!OP_TYPE_IS(kid, OP_NULL) ||
13240+
!(OP_TYPE_IS(kUNOP->op_first, OP_SCOPE) || OP_TYPE_IS(kUNOP->op_first, OP_LEAVE))) {
13241+
/* diag_listed_as: any EXPR, LIST is not allowed */
13242+
/* diag_listed_as: all EXPR, LIST is not allowed */
13243+
croak("%s EXPR, LIST is not allowed",
13244+
o->op_type == OP_ANYSTART ? "any" : "all");
13245+
}
13246+
break;
13247+
}
13248+
1323113249
gwop = alloc_LOGOP(type, o, LINKLIST(kid));
1323213250
kid->op_next = (OP*)gwop;
1323313251
o->op_private = gwop->op_private = 0;

pod/perldiag.pod

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ removed in a future Perl version:
7575
use feature "refaliasing";
7676
\$x = \$y;
7777

78+
=item all EXPR, LIST is not allowed
79+
80+
(F) An attempt was made to use the C<all> keyword with a deferred expression,
81+
which is permitted for C<grep> but not for C<all>. You need to put the
82+
expression in a block instead, as
83+
84+
$result = all { EXPR } LIST;
85+
7886
=item all is experimental
7987

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

199+
=item any EXPR, LIST is not allowed
200+
201+
(F) An attempt was made to use the C<any> keyword with a deferred expression,
202+
which is permitted for C<grep> but not for C<any>. You need to put the
203+
expression in a block instead, as
204+
205+
$result = any { EXPR } LIST;
206+
191207
=item any is experimental
192208

193209
(S experimental::any_all) This warning is emitted if you use the C<any>

t/lib/croak/op

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,17 @@ use 5.012;
326326
use 5.010;
327327
EXPECT
328328
Downgrading a use VERSION declaration to below v5.11 is not permitted at - line 3.
329+
########
330+
# any with deferred LIST expression
331+
use feature 'any_all';
332+
no warnings 'experimental::any_all';
333+
any length, qw( a b c )
334+
EXPECT
335+
any EXPR, LIST is not allowed at - line 4.
336+
########
337+
# all with deferred LIST expression
338+
use feature 'any_all';
339+
no warnings 'experimental::any_all';
340+
all length, qw( a b c )
341+
EXPECT
342+
all EXPR, LIST is not allowed at - line 4.

0 commit comments

Comments
 (0)