In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/85f22e05efca6c0fbc035b09cb5f0e6e1a4ca717?hp=177ee6a3ebda2fa85768cab5f086fd1e706fc36c>
- Log ----------------------------------------------------------------- commit 85f22e05efca6c0fbc035b09cb5f0e6e1a4ca717 Author: Father Chrysostomos <[email protected]> Date: Sat Nov 8 10:41:23 2014 -0800 Remove OA_DANGEROUS from non-integer postdec/inc OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. While pp_postinc may return a lexical scalar, that only happens when the OPpTARGET_MY optimisation is happening; and aassign_common_vars in op.c checks specifically for that. Otherwise, it only returns a mortal or target, so it is not OA_DANGEROUS. M opcode.h M regen/opcodes commit 9e319cc4fd53e7fda8d24a3e32cedcd89cb2f66c Author: Father Chrysostomos <[email protected]> Date: Sat Nov 8 10:12:30 2014 -0800 Allow OPpTARGET_MY on non-integer postdec/inc I donât know why this was not done to begin with. The previous two commits fixed the only outstanding problems I am aware of. M lib/B/Op_private.pm M opcode.h M regen/opcodes commit e87de4ab85d86a0df65940af0f52ef44b70e0e50 Author: Father Chrysostomos <[email protected]> Date: Sat Nov 8 10:11:53 2014 -0800 Make pp_postinc call set-magic on its target Its target may be a lexical scalar (under âuse integerâ currently, and soon even outside of âuse integerâ). The assignment in $lex = $foo++ currently gets optimised away and ++ writes directly to $lex. M pp.c M t/op/inc.t commit b454703a4259660f770f2d4a9cbb39379016df58 Author: Father Chrysostomos <[email protected]> Date: Sat Nov 8 10:05:15 2014 -0800 Fix $lex = $ref++ under use integer Operators generally have targets, that is, scalars in the pad that are used to return values. The same scalar is used again and again for efficiency. If the value assigned to a target is a reference, that can be bad, because the referent will last longer than expected, even forever. $ref++ used to have this problem (bug #9466). So commit v5.13.4-148-g7dcb9b9 fixed it by returning a new mortal if the return value was a reference. However, under âuse integerâ, the OPpTARGET_MY optimisation is per- mitted on postdec and postinc (why only under âuse integerâ I donât know). Under that optimisation, $lexicalvariable = <some op> has the assignment optimised away and the lexical variable becomes the operat- orâs target. If we skip assigning to the target and it is a lexical variable, then the assignment never happens: $ perl5.14.4 -le 'my $x=7; $_={}; $x = $_++; print $x' HASH(0x7ff4a8806d00) $ perl5.14.4 -Minteger -le 'my $x=7; $_={}; $x = $_++; print $x' 7 M pp.c M t/op/inc.t ----------------------------------------------------------------------- Summary of changes: lib/B/Op_private.pm | 2 +- opcode.h | 610 ++++++++++++++++++++++++++-------------------------- pp.c | 4 +- regen/opcodes | 8 +- t/op/inc.t | 35 +++ 5 files changed, 347 insertions(+), 312 deletions(-) diff --git a/lib/B/Op_private.pm b/lib/B/Op_private.pm index 7fc1de6..7ba71b9 100644 --- a/lib/B/Op_private.pm +++ b/lib/B/Op_private.pm @@ -144,7 +144,7 @@ $bits{$_}{7} = 'OPpPV_IS_UTF8' for qw(dump goto last next redo); $bits{$_}{6} = 'OPpREFCOUNTED' for qw(leave leaveeval leavesub leavesublv leavewrite); $bits{$_}{6} = 'OPpRUNTIME' for qw(match pushre qr subst substcont); $bits{$_}{2} = 'OPpSLICEWARNING' for qw(aslice hslice padav padhv rv2av rv2hv); -$bits{$_}{4} = 'OPpTARGET_MY' for qw(abs add atan2 chdir chmod chomp chown chr chroot concat cos crypt divide exec exp flock getpgrp getppid getpriority hex i_add i_divide i_modulo i_multiply i_negat ... [315 chars truncated] +$bits{$_}{4} = 'OPpTARGET_MY' for qw(abs add atan2 chdir chmod chomp chown chr chroot concat cos crypt divide exec exp flock getpgrp getppid getpriority hex i_add i_divide i_modulo i_multiply i_negat ... [331 chars truncated] $bits{$_}{5} = 'OPpTRANS_COMPLEMENT' for qw(trans transr); $bits{$_}{7} = 'OPpTRANS_DELETE' for qw(trans transr); $bits{$_}{0} = 'OPpTRANS_FROM_UTF' for qw(trans transr); diff --git a/opcode.h b/opcode.h index 854c8d2..a99c4c0 100644 --- a/opcode.h +++ b/opcode.h @@ -1791,10 +1791,10 @@ EXTCONST U32 PL_opargs[] = { 0x00001144, /* i_preinc */ 0x00001164, /* predec */ 0x00001144, /* i_predec */ - 0x0000116c, /* postinc */ - 0x0000115c, /* i_postinc */ - 0x0000116c, /* postdec */ - 0x0000115c, /* i_postdec */ + 0x0000113c, /* postinc */ + 0x0000111c, /* i_postinc */ + 0x0000113c, /* postdec */ + 0x0000111c, /* i_postdec */ 0x0001121e, /* pow */ 0x0001123e, /* multiply */ 0x0001121e, /* i_multiply */ @@ -2417,337 +2417,337 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 105, /* predec */ 106, /* i_predec */ 107, /* postinc */ - 108, /* i_postinc */ - 110, /* postdec */ - 111, /* i_postdec */ - 113, /* pow */ - 115, /* multiply */ - 117, /* i_multiply */ - 119, /* divide */ - 121, /* i_divide */ - 123, /* modulo */ - 125, /* i_modulo */ - 127, /* repeat */ - 130, /* add */ - 132, /* i_add */ - 134, /* subtract */ - 136, /* i_subtract */ - 138, /* concat */ - 140, /* stringify */ - 142, /* left_shift */ - 144, /* right_shift */ - 146, /* lt */ - 147, /* i_lt */ - 148, /* gt */ - 149, /* i_gt */ - 150, /* le */ - 151, /* i_le */ - 152, /* ge */ - 153, /* i_ge */ - 154, /* eq */ - 155, /* i_eq */ - 156, /* ne */ - 157, /* i_ne */ - 158, /* ncmp */ - 159, /* i_ncmp */ - 160, /* slt */ - 161, /* sgt */ - 162, /* sle */ - 163, /* sge */ - 164, /* seq */ - 165, /* sne */ - 166, /* scmp */ - 167, /* bit_and */ - 168, /* bit_xor */ - 169, /* bit_or */ - 170, /* negate */ - 171, /* i_negate */ - 173, /* not */ - 174, /* complement */ - 175, /* smartmatch */ - 176, /* atan2 */ - 178, /* sin */ - 180, /* cos */ - 182, /* rand */ - 184, /* srand */ - 186, /* exp */ - 188, /* log */ - 190, /* sqrt */ - 192, /* int */ - 194, /* hex */ - 196, /* oct */ - 198, /* abs */ - 200, /* length */ - 202, /* substr */ - 205, /* vec */ - 208, /* index */ - 210, /* rindex */ - 212, /* sprintf */ - 213, /* formline */ - 214, /* ord */ - 216, /* chr */ - 218, /* crypt */ - 220, /* ucfirst */ - 221, /* lcfirst */ - 222, /* uc */ - 223, /* lc */ - 224, /* quotemeta */ - 225, /* rv2av */ - 231, /* aelemfast */ - 232, /* aelemfast_lex */ - 233, /* aelem */ - 238, /* aslice */ - 241, /* kvaslice */ - 242, /* aeach */ - 243, /* akeys */ - 244, /* avalues */ - 245, /* each */ - 246, /* values */ - 247, /* keys */ - 249, /* delete */ - 252, /* exists */ - 254, /* rv2hv */ - 262, /* helem */ - 267, /* hslice */ - 270, /* kvhslice */ - 271, /* unpack */ - 272, /* pack */ - 273, /* split */ - 276, /* join */ - 277, /* list */ - 279, /* lslice */ - 280, /* anonlist */ - 281, /* anonhash */ - 282, /* splice */ - 283, /* push */ - 285, /* pop */ - 286, /* shift */ - 287, /* unshift */ - 289, /* sort */ - 296, /* reverse */ - 298, /* grepstart */ - 299, /* grepwhile */ - 301, /* mapstart */ - 302, /* mapwhile */ - 304, /* range */ - 305, /* flip */ - 307, /* flop */ - 309, /* and */ - 310, /* or */ - 311, /* xor */ - 312, /* dor */ - 313, /* cond_expr */ - 315, /* andassign */ - 316, /* orassign */ - 317, /* dorassign */ - 318, /* method */ - 319, /* entersub */ - 326, /* leavesub */ - 328, /* leavesublv */ - 330, /* caller */ - 332, /* warn */ - 333, /* die */ - 334, /* reset */ + 109, /* i_postinc */ + 111, /* postdec */ + 113, /* i_postdec */ + 115, /* pow */ + 117, /* multiply */ + 119, /* i_multiply */ + 121, /* divide */ + 123, /* i_divide */ + 125, /* modulo */ + 127, /* i_modulo */ + 129, /* repeat */ + 132, /* add */ + 134, /* i_add */ + 136, /* subtract */ + 138, /* i_subtract */ + 140, /* concat */ + 142, /* stringify */ + 144, /* left_shift */ + 146, /* right_shift */ + 148, /* lt */ + 149, /* i_lt */ + 150, /* gt */ + 151, /* i_gt */ + 152, /* le */ + 153, /* i_le */ + 154, /* ge */ + 155, /* i_ge */ + 156, /* eq */ + 157, /* i_eq */ + 158, /* ne */ + 159, /* i_ne */ + 160, /* ncmp */ + 161, /* i_ncmp */ + 162, /* slt */ + 163, /* sgt */ + 164, /* sle */ + 165, /* sge */ + 166, /* seq */ + 167, /* sne */ + 168, /* scmp */ + 169, /* bit_and */ + 170, /* bit_xor */ + 171, /* bit_or */ + 172, /* negate */ + 173, /* i_negate */ + 175, /* not */ + 176, /* complement */ + 177, /* smartmatch */ + 178, /* atan2 */ + 180, /* sin */ + 182, /* cos */ + 184, /* rand */ + 186, /* srand */ + 188, /* exp */ + 190, /* log */ + 192, /* sqrt */ + 194, /* int */ + 196, /* hex */ + 198, /* oct */ + 200, /* abs */ + 202, /* length */ + 204, /* substr */ + 207, /* vec */ + 210, /* index */ + 212, /* rindex */ + 214, /* sprintf */ + 215, /* formline */ + 216, /* ord */ + 218, /* chr */ + 220, /* crypt */ + 222, /* ucfirst */ + 223, /* lcfirst */ + 224, /* uc */ + 225, /* lc */ + 226, /* quotemeta */ + 227, /* rv2av */ + 233, /* aelemfast */ + 234, /* aelemfast_lex */ + 235, /* aelem */ + 240, /* aslice */ + 243, /* kvaslice */ + 244, /* aeach */ + 245, /* akeys */ + 246, /* avalues */ + 247, /* each */ + 248, /* values */ + 249, /* keys */ + 251, /* delete */ + 254, /* exists */ + 256, /* rv2hv */ + 264, /* helem */ + 269, /* hslice */ + 272, /* kvhslice */ + 273, /* unpack */ + 274, /* pack */ + 275, /* split */ + 278, /* join */ + 279, /* list */ + 281, /* lslice */ + 282, /* anonlist */ + 283, /* anonhash */ + 284, /* splice */ + 285, /* push */ + 287, /* pop */ + 288, /* shift */ + 289, /* unshift */ + 291, /* sort */ + 298, /* reverse */ + 300, /* grepstart */ + 301, /* grepwhile */ + 303, /* mapstart */ + 304, /* mapwhile */ + 306, /* range */ + 307, /* flip */ + 309, /* flop */ + 311, /* and */ + 312, /* or */ + 313, /* xor */ + 314, /* dor */ + 315, /* cond_expr */ + 317, /* andassign */ + 318, /* orassign */ + 319, /* dorassign */ + 320, /* method */ + 321, /* entersub */ + 328, /* leavesub */ + 330, /* leavesublv */ + 332, /* caller */ + 334, /* warn */ + 335, /* die */ + 336, /* reset */ -1, /* lineseq */ - 335, /* nextstate */ - 338, /* dbstate */ + 337, /* nextstate */ + 340, /* dbstate */ -1, /* unstack */ -1, /* enter */ - 341, /* leave */ + 343, /* leave */ -1, /* scope */ - 343, /* enteriter */ - 347, /* iter */ + 345, /* enteriter */ + 349, /* iter */ -1, /* enterloop */ - 348, /* leaveloop */ + 350, /* leaveloop */ -1, /* return */ - 350, /* last */ - 352, /* next */ - 354, /* redo */ - 356, /* dump */ - 358, /* goto */ - 360, /* exit */ - 361, /* method_named */ - 362, /* entergiven */ - 363, /* leavegiven */ - 364, /* enterwhen */ - 365, /* leavewhen */ + 352, /* last */ + 354, /* next */ + 356, /* redo */ + 358, /* dump */ + 360, /* goto */ + 362, /* exit */ + 363, /* method_named */ + 364, /* entergiven */ + 365, /* leavegiven */ + 366, /* enterwhen */ + 367, /* leavewhen */ -1, /* break */ -1, /* continue */ - 366, /* open */ - 371, /* close */ - 372, /* pipe_op */ - 373, /* fileno */ - 374, /* umask */ - 375, /* binmode */ - 376, /* tie */ - 377, /* untie */ - 378, /* tied */ - 379, /* dbmopen */ - 380, /* dbmclose */ - 381, /* sselect */ - 382, /* select */ - 383, /* getc */ - 384, /* read */ - 385, /* enterwrite */ - 386, /* leavewrite */ + 368, /* open */ + 373, /* close */ + 374, /* pipe_op */ + 375, /* fileno */ + 376, /* umask */ + 377, /* binmode */ + 378, /* tie */ + 379, /* untie */ + 380, /* tied */ + 381, /* dbmopen */ + 382, /* dbmclose */ + 383, /* sselect */ + 384, /* select */ + 385, /* getc */ + 386, /* read */ + 387, /* enterwrite */ + 388, /* leavewrite */ -1, /* prtf */ -1, /* print */ -1, /* say */ - 388, /* sysopen */ - 389, /* sysseek */ - 390, /* sysread */ - 391, /* syswrite */ - 392, /* eof */ - 393, /* tell */ - 394, /* seek */ - 395, /* truncate */ - 396, /* fcntl */ - 397, /* ioctl */ - 398, /* flock */ - 400, /* send */ - 401, /* recv */ - 402, /* socket */ - 403, /* sockpair */ - 404, /* bind */ - 405, /* connect */ - 406, /* listen */ - 407, /* accept */ - 408, /* shutdown */ - 409, /* gsockopt */ - 410, /* ssockopt */ - 411, /* getsockname */ - 412, /* getpeername */ - 413, /* lstat */ - 414, /* stat */ - 415, /* ftrread */ - 420, /* ftrwrite */ - 425, /* ftrexec */ - 430, /* fteread */ - 435, /* ftewrite */ - 440, /* fteexec */ - 445, /* ftis */ - 449, /* ftsize */ - 453, /* ftmtime */ - 457, /* ftatime */ - 461, /* ftctime */ - 465, /* ftrowned */ - 469, /* fteowned */ - 473, /* ftzero */ - 477, /* ftsock */ - 481, /* ftchr */ - 485, /* ftblk */ - 489, /* ftfile */ - 493, /* ftdir */ - 497, /* ftpipe */ - 501, /* ftsuid */ - 505, /* ftsgid */ - 509, /* ftsvtx */ - 513, /* ftlink */ - 517, /* fttty */ - 521, /* fttext */ - 525, /* ftbinary */ - 529, /* chdir */ - 531, /* chown */ - 533, /* chroot */ - 535, /* unlink */ - 537, /* chmod */ - 539, /* utime */ - 541, /* rename */ - 543, /* link */ - 545, /* symlink */ - 547, /* readlink */ - 548, /* mkdir */ - 550, /* rmdir */ - 552, /* open_dir */ - 553, /* readdir */ - 554, /* telldir */ - 555, /* seekdir */ - 556, /* rewinddir */ - 557, /* closedir */ + 390, /* sysopen */ + 391, /* sysseek */ + 392, /* sysread */ + 393, /* syswrite */ + 394, /* eof */ + 395, /* tell */ + 396, /* seek */ + 397, /* truncate */ + 398, /* fcntl */ + 399, /* ioctl */ + 400, /* flock */ + 402, /* send */ + 403, /* recv */ + 404, /* socket */ + 405, /* sockpair */ + 406, /* bind */ + 407, /* connect */ + 408, /* listen */ + 409, /* accept */ + 410, /* shutdown */ + 411, /* gsockopt */ + 412, /* ssockopt */ + 413, /* getsockname */ + 414, /* getpeername */ + 415, /* lstat */ + 416, /* stat */ + 417, /* ftrread */ + 422, /* ftrwrite */ + 427, /* ftrexec */ + 432, /* fteread */ + 437, /* ftewrite */ + 442, /* fteexec */ + 447, /* ftis */ + 451, /* ftsize */ + 455, /* ftmtime */ + 459, /* ftatime */ + 463, /* ftctime */ + 467, /* ftrowned */ + 471, /* fteowned */ + 475, /* ftzero */ + 479, /* ftsock */ + 483, /* ftchr */ + 487, /* ftblk */ + 491, /* ftfile */ + 495, /* ftdir */ + 499, /* ftpipe */ + 503, /* ftsuid */ + 507, /* ftsgid */ + 511, /* ftsvtx */ + 515, /* ftlink */ + 519, /* fttty */ + 523, /* fttext */ + 527, /* ftbinary */ + 531, /* chdir */ + 533, /* chown */ + 535, /* chroot */ + 537, /* unlink */ + 539, /* chmod */ + 541, /* utime */ + 543, /* rename */ + 545, /* link */ + 547, /* symlink */ + 549, /* readlink */ + 550, /* mkdir */ + 552, /* rmdir */ + 554, /* open_dir */ + 555, /* readdir */ + 556, /* telldir */ + 557, /* seekdir */ + 558, /* rewinddir */ + 559, /* closedir */ -1, /* fork */ - 558, /* wait */ - 559, /* waitpid */ - 561, /* system */ - 563, /* exec */ - 565, /* kill */ - 567, /* getppid */ - 568, /* getpgrp */ - 570, /* setpgrp */ - 572, /* getpriority */ - 574, /* setpriority */ - 576, /* time */ + 560, /* wait */ + 561, /* waitpid */ + 563, /* system */ + 565, /* exec */ + 567, /* kill */ + 569, /* getppid */ + 570, /* getpgrp */ + 572, /* setpgrp */ + 574, /* getpriority */ + 576, /* setpriority */ + 578, /* time */ -1, /* tms */ - 577, /* localtime */ - 578, /* gmtime */ - 579, /* alarm */ - 580, /* sleep */ - 582, /* shmget */ - 583, /* shmctl */ - 584, /* shmread */ - 585, /* shmwrite */ - 586, /* msgget */ - 587, /* msgctl */ - 588, /* msgsnd */ - 589, /* msgrcv */ - 590, /* semop */ - 591, /* semget */ - 592, /* semctl */ - 593, /* require */ - 594, /* dofile */ + 579, /* localtime */ + 580, /* gmtime */ + 581, /* alarm */ + 582, /* sleep */ + 584, /* shmget */ + 585, /* shmctl */ + 586, /* shmread */ + 587, /* shmwrite */ + 588, /* msgget */ + 589, /* msgctl */ + 590, /* msgsnd */ + 591, /* msgrcv */ + 592, /* semop */ + 593, /* semget */ + 594, /* semctl */ + 595, /* require */ + 596, /* dofile */ -1, /* hintseval */ - 595, /* entereval */ - 601, /* leaveeval */ - 603, /* entertry */ + 597, /* entereval */ + 603, /* leaveeval */ + 605, /* entertry */ -1, /* leavetry */ - 604, /* ghbyname */ - 605, /* ghbyaddr */ + 606, /* ghbyname */ + 607, /* ghbyaddr */ -1, /* ghostent */ - 606, /* gnbyname */ - 607, /* gnbyaddr */ + 608, /* gnbyname */ + 609, /* gnbyaddr */ -1, /* gnetent */ - 608, /* gpbyname */ - 609, /* gpbynumber */ + 610, /* gpbyname */ + 611, /* gpbynumber */ -1, /* gprotoent */ - 610, /* gsbyname */ - 611, /* gsbyport */ + 612, /* gsbyname */ + 613, /* gsbyport */ -1, /* gservent */ - 612, /* shostent */ - 613, /* snetent */ - 614, /* sprotoent */ - 615, /* sservent */ + 614, /* shostent */ + 615, /* snetent */ + 616, /* sprotoent */ + 617, /* sservent */ -1, /* ehostent */ -1, /* enetent */ -1, /* eprotoent */ -1, /* eservent */ - 616, /* gpwnam */ - 617, /* gpwuid */ + 618, /* gpwnam */ + 619, /* gpwuid */ -1, /* gpwent */ -1, /* spwent */ -1, /* epwent */ - 618, /* ggrnam */ - 619, /* ggrgid */ + 620, /* ggrnam */ + 621, /* ggrgid */ -1, /* ggrent */ -1, /* sgrent */ -1, /* egrent */ -1, /* getlogin */ - 620, /* syscall */ - 621, /* lock */ - 622, /* once */ + 622, /* syscall */ + 623, /* lock */ + 624, /* once */ -1, /* custom */ - 623, /* reach */ - 624, /* rkeys */ - 626, /* rvalues */ - 627, /* coreargs */ - 631, /* runcv */ - 632, /* fc */ + 625, /* reach */ + 626, /* rkeys */ + 628, /* rvalues */ + 629, /* coreargs */ + 633, /* runcv */ + 634, /* fc */ -1, /* padcv */ -1, /* introcv */ -1, /* clonecv */ - 633, /* padrange */ - 635, /* refassign */ - 641, /* lvref */ - 647, /* lvrefslice */ - 648, /* lvavref */ + 635, /* padrange */ + 637, /* refassign */ + 643, /* lvref */ + 649, /* lvrefslice */ + 650, /* lvavref */ }; @@ -2812,9 +2812,9 @@ EXTCONST U16 PL_op_private_bitdefs[] = { /* i_preinc */ 0x0003, /* predec */ 0x0003, /* i_predec */ 0x0003, - /* postinc */ 0x0003, + /* postinc */ 0x3d30, 0x0003, /* i_postinc */ 0x3d30, 0x0003, - /* postdec */ 0x0003, + /* postdec */ 0x3d30, 0x0003, /* i_postdec */ 0x3d30, 0x0003, /* pow */ 0x3d30, 0x0067, /* multiply */ 0x3d30, 0x0067, @@ -3169,9 +3169,9 @@ EXTCONST U8 PL_op_private_valid[] = { /* I_PREINC */ (OPpARG1_MASK), /* PREDEC */ (OPpARG1_MASK), /* I_PREDEC */ (OPpARG1_MASK), - /* POSTINC */ (OPpARG1_MASK), + /* POSTINC */ (OPpARG1_MASK|OPpTARGET_MY), /* I_POSTINC */ (OPpARG1_MASK|OPpTARGET_MY), - /* POSTDEC */ (OPpARG1_MASK), + /* POSTDEC */ (OPpARG1_MASK|OPpTARGET_MY), /* I_POSTDEC */ (OPpARG1_MASK|OPpTARGET_MY), /* POW */ (OPpARG2_MASK|OPpTARGET_MY), /* MULTIPLY */ (OPpARG2_MASK|OPpTARGET_MY), diff --git a/pp.c b/pp.c index c796dcc..2903d1f 100644 --- a/pp.c +++ b/pp.c @@ -1080,7 +1080,7 @@ PP(pp_postinc) PL_op->op_type == OP_POSTINC || PL_op->op_type == OP_I_POSTINC; if (SvTYPE(TOPs) >= SVt_PVAV || (isGV_with_GP(TOPs) && !SvFAKE(TOPs))) Perl_croak_no_modify(); - if (SvROK(TOPs)) + if (!(PL_op->op_private & OPpTARGET_MY) && SvROK(TOPs)) TARG = sv_newmortal(); sv_setsv(TARG, TOPs); if (!SvREADONLY(TOPs) && !SvGMAGICAL(TOPs) && SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) @@ -1096,7 +1096,7 @@ PP(pp_postinc) /* special case for undef: see thread at 2003-03/msg00536.html in archive */ if (inc && !SvOK(TARG)) sv_setiv(TARG, 0); - SETs(TARG); + SETTARG; return NORMAL; } diff --git a/regen/opcodes b/regen/opcodes index f2110cc..6d0e417 100644 --- a/regen/opcodes +++ b/regen/opcodes @@ -111,10 +111,10 @@ preinc preincrement (++) ck_lfun dIs1 S i_preinc integer preincrement (++) ck_lfun dis1 S predec predecrement (--) ck_lfun dIs1 S i_predec integer predecrement (--) ck_lfun dis1 S -postinc postincrement (++) ck_lfun dIst1 S -i_postinc integer postincrement (++) ck_lfun disT1 S -postdec postdecrement (--) ck_lfun dIst1 S -i_postdec integer postdecrement (--) ck_lfun disT1 S +postinc postincrement (++) ck_lfun IsT1 S +i_postinc integer postincrement (++) ck_lfun isT1 S +postdec postdecrement (--) ck_lfun IsT1 S +i_postdec integer postdecrement (--) ck_lfun isT1 S # Ordinary operators. diff --git a/t/op/inc.t b/t/op/inc.t index 71dfef5..7fa7592 100644 --- a/t/op/inc.t +++ b/t/op/inc.t @@ -287,6 +287,29 @@ isnt(scalar eval { my $pvbm = PVBM; --$pvbm }, undef, "predecrement defined"); } } +# *Do* use pad TARG if it is actually a named variable, even when the thing +# youâre copying is a ref. The fix for #9466 broke this. +{ + package P9466_2; + my $x; + sub DESTROY { $x = 1 } + for (2..3) { + $x = 0; + my $a = bless {}; + my $b; + use integer; + if ($_ == 2) { + $b = $a--; # sassign optimised away + } + else { + $b = $a++; + } + ::is(ref $b, __PACKAGE__, 'i_post(in|de)c/TARGMY on ref'); + undef $a; undef $b; + ::is($x, 1, "9466 case $_"); + } +} + $_ = ${qr //}; $_--; is($_, -1, 'regexp--'); @@ -301,4 +324,16 @@ $_ = v97; $_++; isnt(ref\$_, 'VSTRING', '++ flattens vstrings'); +sub TIESCALAR {bless\my $x} +sub STORE { ++$store::called } +tie my $t, ""; +{ + $t = $_++; + $t = $_--; + use integer; + $t = $_++; + $t = $_--; +} +is $store::called, 4, 'STORE called on "my" target'; + done_testing(); -- Perl5 Master Repository
