This is a hangover from when a magic (e.g. tied) var, after calling
mg_get(), would only set the private (SVp_IOK,SVp_NOK,SVp_POK)
flags on the result, indicating that although it now had a valid integer
value (say), it wasn't a "real" integer. This was achieved by, after
calling mg_get(), shifting all the public flags by PRIVSHIFT to convert
them to private flags.
Since 5.18.0, that's not been the case (i.e. mg_get() on a tied var leaves
Svf_IOK etc set). But there are still a couple of vestigial uses of
PRIVSHIFT in the core, and this commit removes them.
For one of them, I added a test that shows that (in slightly contrived
circumnstances), it was possible for a SVp_IOK NV to be upgraded
to a SVf_IOK int on return from localisation, losing its fractional
component.
The other one, in S_sv_unmagicext_flags(), only seemed to get called
when setting a new value (e.g. from mg_set()), so its unlikely that such a
var would still have private flags set that could be incorrectly upgraded
to public.
PERL_ARGS_ASSERT_SAVE_SCALAR_AT;
osv = *sptr;
- sv = (flags & SAVEf_KEEPOLDELEM) ? osv : (*sptr = newSV(0));
-
- if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv)) {
- if (SvGMAGICAL(osv)) {
- SvFLAGS(osv) |= (SvFLAGS(osv) &
- (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
- }
- if (!(flags & SAVEf_KEEPOLDELEM))
- mg_localize(osv, sv, cBOOL(flags & SAVEf_SETMAGIC));
+ if (flags & SAVEf_KEEPOLDELEM)
+ sv = osv;
+ else {
+ sv = (*sptr = newSV(0));
+ if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv))
+ mg_localize(osv, sv, cBOOL(flags & SAVEf_SETMAGIC));
}
return sv;
if (SvMAGICAL(sv)) /* if we're under save_magic, wait for restore_magic; */
mg_magical(sv); /* else fix the flags now */
}
- else {
+ else
SvMAGICAL_off(sv);
- SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
- }
+
return 0;
}
use strict;
use Config;
-plan tests => 807;
+plan tests => 808;
$| = 1;
is_tainted $n3, "* SETn";
}
+# check that localizing something with get magic (e.g. taint) doesn't
+# upgrade pIOK to IOK
+
+{
+ local our $x = 1.1 + $TAINT0; # $x should be NOK
+ my $ix = int($x); # now NOK, pIOK
+ {
+ local $x = 0;
+ }
+ my $x1 = $x * 1;
+ isnt($x, 1); # it should be 1.1, not 1
+}
+
# This may bomb out with the alarm signal so keep it last
SKIP: {