X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/49a54bbe5e246f5f51e51453d9cc5a19e72a4433..ede1273d4e7ecb92df498e88937c3198127171a4:/gv.c diff --git a/gv.c b/gv.c index 24dabf6..ebcfabb 100644 --- a/gv.c +++ b/gv.c @@ -213,7 +213,7 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi) dVAR; const U32 old_type = SvTYPE(gv); const bool doproto = old_type > SVt_NULL; - const char * const proto = (doproto && SvPOK(gv)) ? SvPVX_const(gv) : NULL; + char * const proto = (doproto && SvPOK(gv)) ? SvPVX(gv) : NULL; const STRLEN protolen = proto ? SvCUR(gv) : 0; SV *const has_constant = doproto && SvROK(gv) ? SvRV(gv) : NULL; const U32 exported_constant = has_constant ? SvPCS_IMPORTED(gv) : 0; @@ -575,6 +575,17 @@ S_gv_get_super_pkg(pTHX_ const char* name, I32 namelen) return stash; } +/* FIXME. If changing this function note the comment in pp_hot's + S_method_common: + + This code tries to figure out just what went wrong with + gv_fetchmethod. It therefore needs to duplicate a lot of + the internals of that function. ... + + I'd guess that with one more flag bit that could all be moved inside + here. +*/ + GV * Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload) { @@ -875,6 +886,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, const I32 add = flags & ~GV_NOADD_MASK; const char *const name_end = nambeg + full_len; const char *const name_em1 = name_end - 1; + U32 faking_it; if (flags & GV_NOTQUAL) { /* Caller promised that there is no stash, so we can skip the check. */ @@ -1071,12 +1083,19 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, return gv; } - /* Adding a new symbol */ + /* Adding a new symbol. + Unless of course there was already something non-GV here, in which case + we want to behave as if there was always a GV here, containing some sort + of subroutine. + Otherwise we run the risk of creating things like GvIO, which can cause + subtle bugs. eg the one that tripped up SQL::Translator */ + + faking_it = SvOK(gv); if (add & GV_ADDWARN && ckWARN_d(WARN_INTERNAL)) Perl_warner(aTHX_ packWARN(WARN_INTERNAL), "Had to create %s unexpectedly", nambeg); gv_init(gv, stash, name, len, add & GV_ADDMULTI); - gv_init_sv(gv, sv_type); + gv_init_sv(gv, faking_it ? SVt_PVCV : sv_type); if (isALPHA(name[0]) && ! (isLEXWARN_on ? ckWARN(WARN_ONCE) : (PL_dowarn & G_WARN_ON ) ) ) @@ -2038,8 +2057,8 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags) PUSHs(lr>0? left: right); PUSHs( lr > 0 ? &PL_sv_yes : ( assign ? &PL_sv_undef : &PL_sv_no )); if (notfound) { - PUSHs( sv_2mortal(newSVpvn(AMG_id2name(method + assignshift), - AMG_id2namelen(method + assignshift)))); + PUSHs(newSVpvn_flags(AMG_id2name(method + assignshift), + AMG_id2namelen(method + assignshift), SVs_TEMP)); } PUSHs((SV*)cv); PUTBACK;