In perl.git, the branch sprout/pok-bug-hunt has been created
<http://perl5.git.perl.org/perl.git/commitdiff/cc0c2f1c7a601027d38d1b7d52eb8f87bf23313d?hp=0000000000000000000000000000000000000000>
at cc0c2f1c7a601027d38d1b7d52eb8f87bf23313d (commit)
- Log -----------------------------------------------------------------
commit cc0c2f1c7a601027d38d1b7d52eb8f87bf23313d
Author: Father Chrysostomos <[email protected]>
Date: Tue Jun 5 22:38:12 2012 -0700
pp_negate: Donât treat nummified str as num
I think itâs a bug that this prints 0:
$ ./perl -lIlib -MDevel::Peek -e '$x = "dogs"; 0+$x; Dump $x; print -$x'
SV = PVNV(0x802340) at 0x821b90
REFCNT = 1
FLAGS = (POK,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x301620 "dogs"\0
CUR = 4
LEN = 16
0
This variable is a string, not a number. The number 0 is just a
cached value. It lacks the IOK flag precisely because the IV is not
representative of the actual value of the scalar.
This logic here is a little bit odd:
if( !SvNIOK( sv ) && looks_like_number( sv ) ){
SvIV_please( sv );
}
if ((flags & SVf_IOK) || ((flags & (SVp_IOK | SVp_NOK)) == SVp_IOK)) {
SvIV_please sets the flags on sv but then they are ignored when check-
ing for integrality.
To fix the bug mentioned above, I had to change this logic to use sv
directly, rather than the saved flags.
That meant that this bug was also fixed at the same time, since the
integer code is no longer bypassed when it is SvIV_please that sets
the integer flags:
$ ./perl -Ilib -le 'print -97656250000000000'
-97656250000000000
$ ./perl -Ilib -le 'print -"97656250000000000"'
-9.765625e+16
M pp.c
M t/op/negate.t
commit 7976051136d387a2b4afafe91e93cd9eed94ed2b
Author: Father Chrysostomos <[email protected]>
Date: Tue Jun 5 20:09:32 2012 -0700
[perl #109542] Make num ops treat $1 as "$1"
Numeric ops were not taking magical variables into account. So $1 (a
magical variable) would be treated differently from "$1" (a non-magi-
cal variable0.
In determining whether to use an integer operation, they would call
SvIV_please_nomg, and then check whether the sv was SvIOK as a result.
SvIV_please_nomg would call SvIV_nomg if the sv were SvPOK or SvNOK.
The problem here is that gmagical variables are never SvIOK, but
only SvIOKp.
In fact, the private flags are used differently for gmagical and non-
magical variables. For non-gmagical variables, the private flag indi-
cates that there is a cached value. If the public flag is not set,
then the cached value is imprecise. For gmagical variables, imprecise
values are never cached; only the private flags are used, and they are
equivalent to the public flags on non-gmagical variables.
This commit changes SvIV_please_nomg to take gmagical variables
into account, using the newly-added sv_gmagical_2iv_please (see the
docs for it in the diff). SvIV_please_nomg now returns true or
false, not void, since a subsequent SvIOK is not reliable. So
âSvIV_please_nomg(sv); if(SvIOK)â becomes
âif(SvIV_please_nomg(sv))â.
M embed.fnc
M embed.h
M pp.c
M pp_hot.c
M proto.h
M sv.c
M sv.h
M t/op/arith.t
commit 9dd13ad477d39d8791eedccef6e3514b66aaf773
Author: Father Chrysostomos <[email protected]>
Date: Sun May 27 00:11:31 2012 -0700
Make warn handle magic vars (fixes [perl #97480])
pp_warn was checking flags before calling get-magic, resulting in sev-
eral bugs that I fixed all at once::
⢠warn now calls get-magic exactly once on its argument, when there
is just one argument (it always worked correctly for multiple)
[perl #97480].
⢠warn calls get-magic exactly once on $@ when falling back to it,
instead of zero times.
⢠A tied variable returning an object that stringifies as an empty
string is no longer ignored if the tied variable was not ROK
before FETCH.
⢠A tied $@ containing a string, or $@ aliased to $1, is no
longer ignored.
â¢Â A tied $@ that last returned a reference but will return a string on
the next FETCH now gets "\t...caught" appended.
M pp_sys.c
M t/op/tie_fetch_count.t
M t/op/warn.t
commit f4abf6be8e4f092e8daed74a231ca8e5c901817e
Author: Father Chrysostomos <[email protected]>
Date: Sat May 26 06:00:01 2012 -0700
Make prototype call FETCH before checking CORE:: prefix
$ perl5.16.0 -e '"CORE::length" =~ /(.*)/; warn prototype $1;'
Warning: something's wrong at -e line 1.
$ perl5.16.0 -e 'warn prototype "CORE::length"'
_ at -e line 1.
Since sv_2cv calls get-magic, the easiest solution is to copy the
argument if it is magical.
M pp.c
M t/comp/proto.t
commit 51dc64dea5efd5df1c6b5cbd2c5899115f12addc
Author: Father Chrysostomos <[email protected]>
Date: Fri May 25 22:44:39 2012 -0700
Make strict refs report $1 the same way as "$1"
A magical variable is never SvPOK, but only SvPOKp. The code that
determined whether to put an ellipsis mark after a truncated symbol
name was only checking SvPOK, resulting in this discrepancy:
$ perl5.15.9 -e 'use strict; *{"a"x40}'
Can't use string ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"...) as a symbol ref
while "strict refs" in use at -e line 1.
$ perl5.15.9 -e 'use strict; ("a"x40)=~/(.*)/; *{$1}'
Can't use string ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as a symbol ref while
"strict refs" in use at -e line 1.
$ perl5.15.9 -e 'use strict; ${"a"x40}'
Can't use string ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"...) as a SCALAR ref
while "strict refs" in use at -e line 1.
$ perl5.15.9 -e 'use strict; ("a"x40)=~/(.*)/; ${$1}'
Can't use string ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as a SCALAR ref while
"strict refs" in use at -e line 1.
SvPOK variables are also SvPOKp, so checking just the latter suffices.
M pp.c
M t/lib/strict/refs
commit ab58cba3fe0fb217e8ba3e2d94b77d33eb327b8f
Author: Father Chrysostomos <[email protected]>
Date: Thu May 24 23:13:37 2012 -0700
Make open(... "<&", $fileno) respect magic
A magical variable is never SvPOK, but only SvPOKp. The code for
checking whether a duplicatee is a numeric file descriptor was only
checking SvPOK. So a regular variable containing a fileno-as-a-string
would work, such as the $a below, as would a stringified magical vari-
able ("$1"), but not $1 itself.
$ echo foo | perl -le '$a = "0"; open a, "<&", $a; warn <a>'
foo
$ echo foo | perl -le '"0" =~ /(.)/; open a, "<&", $1; warn <a>'
Can't use an undefined value as filehandle reference at -e line 1.
$ echo foo | perl -le '"0" =~ /(.)/; open a, "<&", "$1"; warn <a>'
foo
SvPOK variables are also SvPOKp, so checking only the latter suffices.
M doio.c
M t/io/open.t
commit bf5d29555409063ec434671298cf61870e4ea7f6
Author: Father Chrysostomos <[email protected]>
Date: Thu May 24 22:46:56 2012 -0700
util.c:report_evil_fh: Report name w/initial null
In the error message, we shouldnât omit a handle whose name begins
with "\0", but, rather, a handle whose name has no length to it.
M t/lib/warnings/pp_hot
M util.c
commit 991c8ed2b00ecc868ec994b056d78f350af74e85
Author: Father Chrysostomos <[email protected]>
Date: Thu May 24 22:46:16 2012 -0700
util.c:report_evil_fh: Rmv redundant SvPOK
newSVhek (used to create this SV) always returns an SvPOK scalar.
M util.c
commit 36231a2c43167211d3ab32b501df9a6c18f8ddd0
Author: Father Chrysostomos <[email protected]>
Date: Thu May 24 22:41:53 2012 -0700
util.c:report_wrongway_fh: Report name w/initial null
In the error message, we shouldnât omit a handle whose name begins
with "\0", but, rather, a handle whose name has no length to it.
M t/lib/warnings/pp_hot
M util.c
commit e608cf97033fd912a5515d1c4d10d8586743d0dd
Author: Father Chrysostomos <[email protected]>
Date: Thu May 24 22:19:29 2012 -0700
util.c:report_evil_fh: Rmv redundant isGV check
Checking isGV_with_GP makes the isGV check redundant. The only case
in which isGV could be true when isGV_with_GP is false could be a GV
playing PVBM, but those donât exist any more. When they did exist,
this check was probably wrong (and crashable).
M util.c
commit aed55735ab8d5f54ed705f6a70c3737b94d55659
Author: Father Chrysostomos <[email protected]>
Date: Thu May 24 22:16:52 2012 -0700
util.c:report_wrongway_fh: Donât create an SV
Now that sv_vcatpvfn supports HEKs directly, we donât need to create a
temporary SV out of one.
M util.c
commit 193e556f828e430a1939be294c97fbf5dea97c73
Author: Father Chrysostomos <[email protected]>
Date: Thu May 24 22:10:32 2012 -0700
util.c:report_wrongway_fh: Rmv redundant isGV check
Checking isGV_with_GP makes the isGV check redundant. The only case
in which isGV could be true when isGV_with_GP is false could be a GV
playing PVBM, but those donât exist any more. When they did exist,
this check was probably wrong (and crashable).
M util.c
commit 1c1aaa2a08d0c4f9a9b1d45d85ca217eba883fcf
Author: Father Chrysostomos <[email protected]>
Date: Thu May 24 20:37:01 2012 -0700
Make UNIVERSAL::can treats str and num the same way
M t/op/universal.t
M universal.c
commit ebe684bfef03ad3b7b2ce1d864fe4891ac852459
Author: Father Chrysostomos <[email protected]>
Date: Thu May 24 12:45:58 2012 -0700
Use the same top format error for ""
See also the previous commit.
2dd78f96 added the âUndefined top format calledâ message for those
cases where a GV doesnât have a name. That was a bug that used to
happen with *{$io}, which canât happen any more.
The code that 2dd78f96 added ended up changing a zero-length name to
be treated the same way as no name. It also checked the length by
cheating and checking the first character instead.
Now that we have support for embedded nulls, that logic ends up wrong
for names like "\0foo". And there is no need to treat "" differently
from "foo" anyway.
So this patch restores things the way they were before 2dd78f96.
It also improves the tests for âUndefined formatâ.
Writing tests for âUndefined top formatâ was quite painful, as that
error seems to leave the internal state out of synch. I suspect
PL_formtarget needs to be localised, or the error just needs to come
earlier in pp_leavewrite. But Iâll save that for later, or for Dave
Mitchell. :-)
M pp_sys.c
M t/op/write.t
M t/porting/diag.t
commit 3653574f887fc0ed01c33990cf29af30127cc72e
Author: Father Chrysostomos <[email protected]>
Date: Thu May 24 12:17:02 2012 -0700
Get rid of âNot a format referenceâ
This commit:
commit 2dd78f96d61cc6382dc72214930c993567209597
Author: Jarkko Hietaniemi <[email protected]>
Date: Sun Aug 6 01:33:55 2000 +0000
Continue fixing the io warnings. This also
sort of fixes bug ID 20000802.003: the core dump
is no more. Whether the current behaviour is correct
(giving a warning: "Not a format reference"), is another matter.
p4raw-id: //depot/perl@6531
added a check to see whether the format GVâs name is null, and, if
so, it dies with âNot a format referenceâ. Before that, that message
occurred only for lack of a GV.
The bug mentioned is now #3617, involving write(*STDOUT{IO}). write
puts an implicit *{} around its argument.
*{$io} has historically been very buggy in its stringification, so
this patch seems to have been working around that bugginess, by fall-
ing back to the âNot a format referenceâ error if the name couldnât be
determined for âUndefined format "foo" calledâ.
*{$io} was fixed once and for all in 5.16. It now stringifies as
*foopackage::__ANONIO__.
I donât think producing a completetly different error based on the
name of the GV (whether itâs "foo" or "") is correct at all. And the
patch that made it happen was just a fix for a crash that canât hap-
pen any more.
So the only case that should produce âNot a format referenceâ is that
in which there is no format GV (fgv).
I can prove that fgv is always set (see below), and has been at least
since 5.000, so that âNot a format referenceâ actually could never
occur before 2dd78f96d61c. (Actually, XS code could set PL_defoutgv
to null until the previous commit, but everything would start crashing
as a result, so it has never been done in practice.)
gv_efullname4 always returns a name, so checking SvPOK(tmpsv) is
redundant; checking whether the string buffer begins with a non-null
char is not even correct, as "\0foo" fails that test.
Proof that fgv is always set:
The current (prior to this commit) code in pp_enterwrite is like this:
if (MAXARG == 0) {
gv = PL_defoutgv;
EXTEND(SP, 1);
}
else {
gv = MUTABLE_GV(POPs);
if (!gv)
gv = PL_defoutgv;
}
If the stack value is null (which actually canât happen), PL_defoutgv
is used. PL_defoutgv canât be null.
At this point, gv is set to something non-null.
io = GvIO(gv);
if (!io) {
RETPUSHNO;
}
Here we only set fgv to IoFMT_GV(io) if it is non-null. Otherwise we
use gv, which we know is non-null.
if (IoFMT_GV(io))
fgv = IoFMT_GV(io);
else
fgv = gv;
M pod/perldiag.pod
M pp_sys.c
M t/op/write.t
commit 7452b05709b191f33f5add072076db030a9cf6e3
Author: Father Chrysostomos <[email protected]>
Date: Thu May 24 12:07:37 2012 -0700
Make setdefout accept only NN
Just search through the source for GvIOp(PL_defoutgv) and you will see
that perl assumes that PL_defoutgv is never null.
I tried setting it to null from XS and got crashes, unsurprisingly.
The only CPAN user of PL_defoutgv sets it to STDOUT.
M embed.fnc
M pp_sys.c
M proto.h
commit 20bb7cb1b4c2268546c9e7656b09bc0a7ba21efb
Author: Father Chrysostomos <[email protected]>
Date: Wed May 23 23:24:35 2012 -0700
Assertion failure with $/=*foo; warn;
$ ./perl -Ilib -e '$/=*foo; <>; warn' <./perl
Assertion failed: (!isGV_with_GP(_svcur)), function Perl_mess_sv, file
util.c, line 1467.
Abort trap
The assertion happens when â<...> line 42â is being appended to
the message.
The line of code in question is this:
const bool line_mode = (RsSIMPLE(PL_rs) &&
SvCUR(PL_rs) == 1 && *SvPVX_const(PL_rs) == '\n');
It uses this macro in perl.h:
#define RsSIMPLE(sv) (SvOK(sv) && (! SvPOK(sv) || SvCUR(sv)))
which was last modified by commit af7d13df559:
-#define RsSIMPLE(sv) (SvOK(sv) && SvCUR(sv))
-#define RsPARA(sv) (SvOK(sv) && ! SvCUR(sv))
+#define RsSIMPLE(sv) (SvOK(sv) && (! SvPOK(sv) || SvCUR(sv)))
+#define RsPARA(sv) (SvPOK(sv) && ! SvCUR(sv))
So it looks as though it has always called SvCUR on something that is
not necessarily a PV. As of commit af7d13df559, it has also called
SvPVX on a potential non-PV.
Fixing this simply involves using SvPV instead of SvPVX.
I donât know that t/io/open.t is the best place for the test, but all
the other â<...> line 42â tests are there.
M t/io/open.t
M util.c
commit eb2f7e15e4d818d99217500a871db049c72c2e8c
Author: Father Chrysostomos <[email protected]>
Date: Wed May 23 22:44:25 2012 -0700
Donât clone closures in rv2cv
Commit 07055b4c536 (Support named closures) added code to make refer-
encing a closure prototype clone the prototype. Commit 28757baaaeaa
(inseparable changes from patch from perl5.003_19 to perl5.003_20),
which includes âSubject: Rescind named closuresâ in its log, appar-
ently did not rescind ânamed closuresâ completely, leaving a line of
code that was completetly unused and untested, until just now when I
tried doing something bizarre to see whether some other piece of code
was buggy. This wasnât what I expected. :-)
$ ./perl -Ilib -e 'sub MODIFY_CODE_ATTRIBUTES{\&{$_[1]};} my $x; +sub
:bar{$x}'
Assertion failed: (depth || SvTYPE(proto) == SVt_PVFM), function
Perl_cv_clone, file pad.c, line 1890.
Abort trap
M pp.c
M t/op/attrs.t
commit 864eec77c01ce4712d85615eb733fd7427ab0cad
Author: Father Chrysostomos <[email protected]>
Date: Wed May 23 21:51:45 2012 -0700
Remove âRunaway prototypeâ warning
This has been here since commit 8472ac73d, which was merged into blead
in commit 55d729e4e15, if I understand the history correctly.
This warning is undocumented, and triggerable only by stash
manipulation.
It appears to be an internal check, similar to a âpanicâ error, but
its wording doesnât suggest anything of the sort.
A âsub foo;â declaration doesnât actually create the sub yet, but
simply puts -1 in the stash element. âsub foo($);â puts '$' in the
stash element.
If newATTRSUB sees something there it doesnât recognise, it unhelp-
fully carps âRunaway prototypeâ, but it is pretty random:
This is OK:
$ perl -e 'BEGIN{$::{foo}=undef} sub foo;'
But this is not:
$ perl -e 'BEGIN{$::{foo}=-1; $::{foo}=undef} sub foo;'
Runaway prototype at -e line 1.
Also, it only happens when the sub has no body, not for âsub foo {}â:
$ perl -e 'BEGIN{$::{foo}=56} sub foo{}'
$ perl -e 'BEGIN{$::{foo}=56} sub foo;'
Runaway prototype at -e line 1.
This warning is random, incomprehensible, and not at all helpful, so
we should just remove it.
M op.c
M t/lib/warnings/op
M t/porting/diag.t
-----------------------------------------------------------------------
--
Perl5 Master Repository