summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-06-02 00:31:27 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-06-02 00:38:06 -0700
commit70e5f2b56cbcbdf658cf4172827db4611d322148 (patch)
tree6988b09f1791ebd508c0db88f953f77d9092f904 /gv.c
parentd8b87a9b781df570fca05131b8d4e8855eb8c5e3 (diff)
downloadperl-70e5f2b56cbcbdf658cf4172827db4611d322148.tar.gz
Stop constant inlining from countermanding ‘use subs’
Ever since commit f7461760003db2ce68155c97ea6c1658e96fcd27 Author: Zefram <zefram@fysh.org> Date: Sun Nov 8 15:03:45 2009 +0100 Bareword sub lookups ... this has failed: $ perl5.10 -le 'use subs "abs"; sub abs() {44}; print abs + abs' 88 $ perl5.12 -le 'use subs "abs"; sub abs() {44}; print abs + abs' 44 A GV holding a single constant is a candidate for downgrading after it uhas been used. The GV gets downgraded after the first ‘abs’ is inlined. In the process, the CV-imported flag, which is stored in the GV, not the CV, is lost, preventing &abs from overriding the built-in function on the second mention. There is a special flag for RVs, namely SVprv_PCS_IMPORTED, which indicates that, when expanded to GVs, they should have the GVf_IMPORTED_CV flag set. But gv_try_downgrade wasn‘t setting that flag.
Diffstat (limited to 'gv.c')
-rw-r--r--gv.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/gv.c b/gv.c
index 23251940a3..b89181e061 100644
--- a/gv.c
+++ b/gv.c
@@ -3174,10 +3174,11 @@ Perl_gv_try_downgrade(pTHX_ GV *gv)
HEK_LEN(namehek)*(HEK_UTF8(namehek) ? -1 : 1), 0)) &&
*gvp == (SV*)gv) {
SV *value = SvREFCNT_inc(CvXSUBANY(cv).any_ptr);
+ const bool imported = !!GvIMPORTED_CV(gv);
SvREFCNT(gv) = 0;
sv_clear((SV*)gv);
SvREFCNT(gv) = 1;
- SvFLAGS(gv) = SVt_IV|SVf_ROK;
+ SvFLAGS(gv) = SVt_IV|SVf_ROK|SVprv_PCS_IMPORTED * imported;
SvANY(gv) = (XPVGV*)((char*)&(gv->sv_u.svu_iv) -
STRUCT_OFFSET(XPVIV, xiv_iv));
SvRV_set(gv, value);