Skip to content

Commit cb50cab

Browse files
committed
Forbid use of any/all with a deferred expression; only accept BLOCK
1 parent e4ea037 commit cb50cab

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
@@ -13238,6 +13238,24 @@ Perl_ck_grep(pTHX_ OP *o)
1323813238
Perl_croak(aTHX_ "panic: ck_grep, type=%u", (unsigned) kid->op_type);
1323913239
kid = kUNOP->op_first;
1324013240

13241+
switch(o->op_type) {
13242+
case OP_ANYSTART:
13243+
case OP_ALLSTART:
13244+
/* any { BLOCK } would create an OP_NULL[OP_SCOPE[...]] or
13245+
* OP_NULL[OP_LEAVE[...]] here. If we don't see this structure
13246+
* then it must have been any EXPR, ... which we forbid
13247+
* TODO: See if we can forbid this somehow in perly.y itself
13248+
*/
13249+
if(!OP_TYPE_IS(kid, OP_NULL) ||
13250+
!(OP_TYPE_IS(kUNOP->op_first, OP_SCOPE) || OP_TYPE_IS(kUNOP->op_first, OP_LEAVE))) {
13251+
/* diag_listed_as: any EXPR, LIST is not allowed */
13252+
/* diag_listed_as: all EXPR, LIST is not allowed */
13253+
croak("%s EXPR, LIST is not allowed",
13254+
o->op_type == OP_ANYSTART ? "any" : "all");
13255+
}
13256+
break;
13257+
}
13258+
1324113259
gwop = alloc_LOGOP(type, o, LINKLIST(kid));
1324213260
kid->op_next = (OP*)gwop;
1324313261
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)