summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2015-02-06 10:14:47 -0800
committerFather Chrysostomos <sprout@cpan.org>2015-02-06 10:14:47 -0800
commitfb0c7c3c47fb17bb0b685b957af9a0cc581c8996 (patch)
tree0703db1d1eb07eaa79a426915f889d1d254c3208
parent488bc5795891132d29daec7a860cab2a6266230c (diff)
downloadperl-fb0c7c3c47fb17bb0b685b957af9a0cc581c8996.tar.gz
[perl #123753] Fix assertion failure with map+map
ck_grep calls ck_fun, which sets the lower private bits to indicate the number of operands. ck_grep usually undoes that, by clobbering op_private completetly. If an error has occurred, it doesn’t, so we may fail an assertion if the lower bits are not expected to be set on mapstart and grepstart.
-rw-r--r--lib/B/Op_private.pm2
-rw-r--r--opcode.h127
-rw-r--r--regen/op_private3
-rw-r--r--t/comp/parser.t4
4 files changed, 72 insertions, 64 deletions
diff --git a/lib/B/Op_private.pm b/lib/B/Op_private.pm
index 03a5a83647..e1cc2ce307 100644
--- a/lib/B/Op_private.pm
+++ b/lib/B/Op_private.pm
@@ -349,6 +349,7 @@ $bits{gpbyname}{0} = $bf[0];
@{$bits{gpbynumber}}{3,2,1,0} = ($bf[3], $bf[3], $bf[3], $bf[3]);
$bits{gpwnam}{0} = $bf[0];
$bits{gpwuid}{0} = $bf[0];
+$bits{grepstart}{0} = $bf[0];
$bits{grepwhile}{0} = $bf[0];
@{$bits{gsbyname}}{3,2,1,0} = ($bf[3], $bf[3], $bf[3], $bf[3]);
@{$bits{gsbyport}}{3,2,1,0} = ($bf[3], $bf[3], $bf[3], $bf[3]);
@@ -404,6 +405,7 @@ $bits{lstat}{0} = $bf[0];
@{$bits{lt}}{1,0} = ($bf[1], $bf[1]);
$bits{lvavref}{0} = $bf[0];
@{$bits{lvref}}{5,4,0} = ($bf[7], $bf[7], $bf[0]);
+$bits{mapstart}{0} = $bf[0];
$bits{mapwhile}{0} = $bf[0];
$bits{method}{0} = $bf[0];
$bits{method_named}{0} = $bf[0];
diff --git a/opcode.h b/opcode.h
index cf39a4b57a..ef5f432f96 100644
--- a/opcode.h
+++ b/opcode.h
@@ -2602,45 +2602,45 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
128, /* sort */
135, /* reverse */
137, /* grepstart */
- 138, /* grepwhile */
+ 137, /* grepwhile */
137, /* mapstart */
- 138, /* mapwhile */
+ 137, /* mapwhile */
0, /* range */
- 140, /* flip */
- 140, /* flop */
+ 139, /* flip */
+ 139, /* flop */
0, /* and */
0, /* or */
12, /* xor */
0, /* dor */
- 142, /* cond_expr */
+ 141, /* cond_expr */
0, /* andassign */
0, /* orassign */
0, /* dorassign */
0, /* method */
- 144, /* entersub */
- 151, /* leavesub */
- 151, /* leavesublv */
- 153, /* caller */
+ 143, /* entersub */
+ 150, /* leavesub */
+ 150, /* leavesublv */
+ 152, /* caller */
48, /* warn */
48, /* die */
48, /* reset */
-1, /* lineseq */
- 155, /* nextstate */
- 155, /* dbstate */
+ 154, /* nextstate */
+ 154, /* dbstate */
-1, /* unstack */
-1, /* enter */
- 156, /* leave */
+ 155, /* leave */
-1, /* scope */
- 158, /* enteriter */
- 162, /* iter */
+ 157, /* enteriter */
+ 161, /* iter */
-1, /* enterloop */
- 163, /* leaveloop */
+ 162, /* leaveloop */
-1, /* return */
- 165, /* last */
- 165, /* next */
- 165, /* redo */
- 165, /* dump */
- 165, /* goto */
+ 164, /* last */
+ 164, /* next */
+ 164, /* redo */
+ 164, /* dump */
+ 164, /* goto */
48, /* exit */
0, /* method_named */
0, /* method_super */
@@ -2652,7 +2652,7 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
0, /* leavewhen */
-1, /* break */
-1, /* continue */
- 167, /* open */
+ 166, /* open */
48, /* close */
48, /* pipe_op */
48, /* fileno */
@@ -2668,7 +2668,7 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
48, /* getc */
48, /* read */
48, /* enterwrite */
- 151, /* leavewrite */
+ 150, /* leavewrite */
-1, /* prtf */
-1, /* print */
-1, /* say */
@@ -2698,33 +2698,33 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
0, /* getpeername */
0, /* lstat */
0, /* stat */
- 172, /* ftrread */
- 172, /* ftrwrite */
- 172, /* ftrexec */
- 172, /* fteread */
- 172, /* ftewrite */
- 172, /* fteexec */
- 177, /* ftis */
- 177, /* ftsize */
- 177, /* ftmtime */
- 177, /* ftatime */
- 177, /* ftctime */
- 177, /* ftrowned */
- 177, /* fteowned */
- 177, /* ftzero */
- 177, /* ftsock */
- 177, /* ftchr */
- 177, /* ftblk */
- 177, /* ftfile */
- 177, /* ftdir */
- 177, /* ftpipe */
- 177, /* ftsuid */
- 177, /* ftsgid */
- 177, /* ftsvtx */
- 177, /* ftlink */
- 177, /* fttty */
- 177, /* fttext */
- 177, /* ftbinary */
+ 171, /* ftrread */
+ 171, /* ftrwrite */
+ 171, /* ftrexec */
+ 171, /* fteread */
+ 171, /* ftewrite */
+ 171, /* fteexec */
+ 176, /* ftis */
+ 176, /* ftsize */
+ 176, /* ftmtime */
+ 176, /* ftatime */
+ 176, /* ftctime */
+ 176, /* ftrowned */
+ 176, /* fteowned */
+ 176, /* ftzero */
+ 176, /* ftsock */
+ 176, /* ftchr */
+ 176, /* ftblk */
+ 176, /* ftfile */
+ 176, /* ftdir */
+ 176, /* ftpipe */
+ 176, /* ftsuid */
+ 176, /* ftsgid */
+ 176, /* ftsvtx */
+ 176, /* ftlink */
+ 176, /* fttty */
+ 176, /* fttext */
+ 176, /* ftbinary */
79, /* chdir */
79, /* chown */
72, /* chroot */
@@ -2744,17 +2744,17 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
0, /* rewinddir */
0, /* closedir */
-1, /* fork */
- 181, /* wait */
+ 180, /* wait */
79, /* waitpid */
79, /* system */
79, /* exec */
79, /* kill */
- 181, /* getppid */
+ 180, /* getppid */
79, /* getpgrp */
79, /* setpgrp */
79, /* getpriority */
79, /* setpriority */
- 181, /* time */
+ 180, /* time */
-1, /* tms */
0, /* localtime */
48, /* gmtime */
@@ -2774,8 +2774,8 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
0, /* require */
0, /* dofile */
-1, /* hintseval */
- 182, /* entereval */
- 151, /* leaveeval */
+ 181, /* entereval */
+ 150, /* leaveeval */
0, /* entertry */
-1, /* leavetry */
0, /* ghbyname */
@@ -2816,17 +2816,17 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
0, /* reach */
39, /* rkeys */
0, /* rvalues */
- 188, /* coreargs */
+ 187, /* coreargs */
3, /* runcv */
0, /* fc */
-1, /* padcv */
-1, /* introcv */
-1, /* clonecv */
- 192, /* padrange */
- 194, /* refassign */
- 200, /* lvref */
- 206, /* lvrefslice */
- 207, /* lvavref */
+ 191, /* padrange */
+ 193, /* refassign */
+ 199, /* lvref */
+ 205, /* lvrefslice */
+ 206, /* lvavref */
0, /* anonconst */
};
@@ -2887,8 +2887,7 @@ EXTCONST U16 PL_op_private_bitdefs[] = {
0x29dc, 0x1e99, /* list */
0x3af8, 0x3194, 0x0fb0, 0x254c, 0x34e8, 0x2644, 0x2e61, /* sort */
0x254c, 0x0003, /* reverse */
- 0x1cc5, /* grepstart, mapstart */
- 0x1cc4, 0x0003, /* grepwhile, mapwhile */
+ 0x1cc4, 0x0003, /* grepstart, grepwhile, mapstart, mapwhile */
0x2778, 0x0003, /* flip, flop */
0x29dc, 0x0003, /* cond_expr */
0x29dc, 0x0b98, 0x0256, 0x028c, 0x3e48, 0x3c84, 0x2301, /* entersub */
@@ -3088,9 +3087,9 @@ EXTCONST U8 PL_op_private_valid[] = {
/* UNSHIFT */ (OPpARG4_MASK|OPpTARGET_MY),
/* SORT */ (OPpSORT_NUMERIC|OPpSORT_INTEGER|OPpSORT_REVERSE|OPpSORT_INPLACE|OPpSORT_DESCEND|OPpSORT_QSORT|OPpSORT_STABLE),
/* REVERSE */ (OPpARG1_MASK|OPpREVERSE_INPLACE),
- /* GREPSTART */ (OPpGREP_LEX),
+ /* GREPSTART */ (OPpARG1_MASK|OPpGREP_LEX),
/* GREPWHILE */ (OPpARG1_MASK|OPpGREP_LEX),
- /* MAPSTART */ (OPpGREP_LEX),
+ /* MAPSTART */ (OPpARG1_MASK|OPpGREP_LEX),
/* MAPWHILE */ (OPpARG1_MASK|OPpGREP_LEX),
/* RANGE */ (OPpARG1_MASK),
/* FLIP */ (OPpARG1_MASK|OPpFLIP_LINENUM),
diff --git a/regen/op_private b/regen/op_private
index c8c09d6d93..e47f5d3ba8 100644
--- a/regen/op_private
+++ b/regen/op_private
@@ -202,6 +202,9 @@ use strict;
$args1{$_} = 1 for (
qw(reverse), # ck_fun(), but most bits stolen
+ qw(mapstart grepstart), # set in ck_fun, but
+ # cleared in ck_grep,
+ # unless there is an error
grep !$maxarg{$_} && !$args0{$_},
ops_with_flag('1'), # UNOP
ops_with_flag('+'), # UNOP_AUX
diff --git a/t/comp/parser.t b/t/comp/parser.t
index 56c23d1d16..a84cfc2c08 100644
--- a/t/comp/parser.t
+++ b/t/comp/parser.t
@@ -530,6 +530,10 @@ eval 's /${<>{}) //';
# Also used to crash [perl #123652]
eval{$1=eval{a:}};
+# Used to fail assertions [perl #123753]
+eval "map+map";
+eval "grep+grep";
+
# Add new tests HERE (above this line)
# bug #74022: Loop on characters in \p{OtherIDContinue}