From 376ccf8b794f87b0c0a827bdcadc14b71179ff42 Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Sat, 10 Aug 2013 10:38:08 -0700 Subject: [PATCH] Make ++ handle regexps and vstrings $ ./perl -Ilib -e 'use Devel::Peek; $x = v97; ++$x; Dump $x' SV = PVMG(0x7fbfa402b698) at 0x7fbfa402eed8 REFCNT = 1 FLAGS = (RMG,POK,pPOK) IV = 0 NV = 0 PV = 0x7fbfa3c066a8 "b"\0 CUR = 1 LEN = 24 MAGIC = 0x7fbfa3c06348 MG_VIRTUAL = 0 MG_TYPE = PERL_MAGIC_vstring(V) MG_LEN = 3 MG_PTR = 0x7fbfa3c13ee8 "v97" The vstring magic is still attached (with something that does not match the contents of the string), even after modifying it. I probably broke that in 5.18 after fixing it in 5.16, but I am too lazy to check. $ ./perl -le '$x = ${qr//}; $x++; print "$x"' Assertion failed: (PL_valid_types_IVX[SvTYPE(_svivx) & SVt_MASK]), function Perl_sv_2pv_flags, file sv.c, line 2908. Abort trap: 6 That I broke when I stopped regexps from being POK in perl 5.18.0. It was creating a corrupt SV by setting the IOK flag on something of type SVt_REGEXP. --- sv.c | 3 +-- t/op/inc.t | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/sv.c b/sv.c index c71c0f1..9ea3182 100644 --- a/sv.c +++ b/sv.c @@ -8268,8 +8268,6 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv) if (!sv) return; if (SvTHINKFIRST(sv)) { - if (SvIsCOW(sv) || isGV_with_GP(sv)) - sv_force_normal_flags(sv, 0); if (SvREADONLY(sv)) { Perl_croak_no_modify(); } @@ -8281,6 +8279,7 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv) sv_unref(sv); sv_setiv(sv, i); } + else sv_force_normal_flags(sv, 0); } flags = SvFLAGS(sv); if ((flags & (SVp_NOK|SVp_IOK)) == SVp_NOK) { diff --git a/t/op/inc.t b/t/op/inc.t index 2475b5e..8db0660 100644 --- a/t/op/inc.t +++ b/t/op/inc.t @@ -274,5 +274,12 @@ isnt(scalar eval { my $pvbm = PVBM; --$pvbm }, undef, "predecrement defined"); $_ = ${qr //}; $_--; is($_, -1, 'regexp--'); +$_ = ${qr //}; +$_++; +is($_, 1, 'regexp++'); + +$_ = v97; +$_++; +isnt(ref\$_, 'VSTRING', '++ flattens vstrings'); done_testing(); -- 2.7.4