diff options
author | Tony Cook <tony@develop-help.com> | 2022-11-17 14:30:39 +1100 |
---|---|---|
committer | James E Keenan <jkeenan@cpan.org> | 2022-11-18 18:12:45 -0500 |
commit | 2e4090b82403991910f1fe64866048b62ccf5402 (patch) | |
tree | 8ca250b0bfb4e386128336ee73db71caba26c032 | |
parent | a33534361e54c6342c59edd0c06b6bbb9ac5776c (diff) | |
download | perl-2e4090b82403991910f1fe64866048b62ccf5402.tar.gz |
only fully calculate the stash (effective) name where needed
gcc 12 was complaining that evaluating (somehekptr)->hek_key
was always true in many places where HvNAME() or HvENAME() was
being called in boolean context.
Add new macros to check whether the names should be available and
use those instead.
-rw-r--r-- | ext/XS-APItest/APItest.xs | 2 | ||||
-rw-r--r-- | gv.c | 8 | ||||
-rw-r--r-- | hv.c | 14 | ||||
-rw-r--r-- | hv.h | 20 | ||||
-rw-r--r-- | mg.c | 4 | ||||
-rw-r--r-- | mro_core.c | 10 | ||||
-rw-r--r-- | pp.c | 4 | ||||
-rw-r--r-- | pp_sys.c | 2 | ||||
-rw-r--r-- | scope.c | 6 | ||||
-rw-r--r-- | sv.c | 29 | ||||
-rw-r--r-- | util.c | 2 |
11 files changed, 52 insertions, 49 deletions
diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs index cd2eb2b8ae..5fd90cd19b 100644 --- a/ext/XS-APItest/APItest.xs +++ b/ext/XS-APItest/APItest.xs @@ -4310,7 +4310,7 @@ CODE: SV * HvENAME(HV *hv) CODE: - RETVAL = hv && HvENAME(hv) + RETVAL = hv && HvHasENAME(hv) ? newSVpvn_flags( HvENAME(hv),HvENAMELEN(hv), (HvENAMEUTF8(hv) ? SVf_UTF8 : 0) @@ -1628,7 +1628,7 @@ S_gv_stashpvn_internal(pTHX_ const char *name, U32 namelen, I32 flags) stash = GvHV(tmpgv); if (!(flags & ~GV_NOADD_MASK) && !stash) return NULL; assert(stash); - if (!HvNAME_get(stash)) { + if (!HvHasNAME(stash)) { hv_name_set(stash, name, namelen, flags & SVf_UTF8 ? SVf_UTF8 : 0 ); /* FIXME: This is a repeat of logic in gv_fetchpvn_flags */ @@ -1834,7 +1834,7 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name, if (!(*stash = GvHV(*gv))) { *stash = GvHV(*gv) = newHV(); - if (!HvNAME_get(*stash)) { + if (!HvHasNAME(*stash)) { if (GvSTASH(*gv) == PL_defstash && *len == 6 && strBEGINs(*name, "CORE")) hv_name_sets(*stash, "CORE", 0); @@ -1848,7 +1848,7 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name, mro_package_moved(*stash, NULL, *gv, 1); } } - else if (!HvNAME_get(*stash)) + else if (!HvHasNAME(*stash)) hv_name_set(*stash, nambeg, name_cursor - nambeg, is_utf8); } @@ -3298,7 +3298,7 @@ Perl_gv_handler(pTHX_ HV *stash, I32 id) U32 newgen; struct mro_meta* stash_meta; - if (!stash || !HvNAME_get(stash)) + if (!stash || !HvHasNAME(stash)) return NULL; stash_meta = HvMROMETA(stash); @@ -1439,7 +1439,7 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, /* If this is a stash and the key ends with ::, then someone is * deleting a package. */ - if (sv && SvTYPE(sv) == SVt_PVGV && HvENAME_get(hv)) { + if (sv && SvTYPE(sv) == SVt_PVGV && HvHasENAME(hv)) { gv = (GV *)sv; if (( (klen > 1 && key[klen-2] == ':' && key[klen-1] == ':') @@ -1448,7 +1448,7 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, ) && (klen != 6 || hv!=PL_defstash || memNE(key,"main::",6)) && (stash = GvHV((GV *)gv)) - && HvENAME_get(stash)) { + && HvHasENAME(stash)) { /* A previous version of this code checked that the * GV was still in the symbol table by fetching the * GV with its name. That is not necessary (and @@ -1537,7 +1537,7 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, if (sv) { /* deletion of method from stash */ if (isGV(sv) && isGV_with_GP(sv) && GvCVu(sv) - && HvENAME_get(hv)) + && HvHasENAME(hv)) mro_method_changed_in(hv); if (d_flags & G_DISCARD) { @@ -2190,9 +2190,9 @@ Perl_hfree_next_entry(pTHX_ HV *hv, STRLEN *indexp) array[*indexp] = HeNEXT(entry); ((XPVHV*) SvANY(hv))->xhv_keys--; - if ( PL_phase != PERL_PHASE_DESTRUCT && HvENAME(hv) + if ( PL_phase != PERL_PHASE_DESTRUCT && HvHasENAME(hv) && HeVAL(entry) && isGV(HeVAL(entry)) - && GvHV(HeVAL(entry)) && HvENAME(GvHV(HeVAL(entry))) + && GvHV(HeVAL(entry)) && HvHasENAME(GvHV(HeVAL(entry))) ) { STRLEN klen; const char * const key = HePV(entry,klen); @@ -2243,7 +2243,7 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) if they will be freed anyway. */ /* note that the code following prior to hv_free_entries is duplicated * in sv_clear(), and changes here should be done there too */ - if (PL_phase != PERL_PHASE_DESTRUCT && HvNAME(hv)) { + if (PL_phase != PERL_PHASE_DESTRUCT && HvHasNAME(hv)) { if (PL_stashcache) { DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for '%" HEKf "'\n", HEKfARG(HvNAME_HEK(hv)))); @@ -2281,7 +2281,7 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) struct mro_meta *meta; const char *name; - if (HvENAME_get(hv)) { + if (HvHasENAME(hv)) { if (PL_phase != PERL_PHASE_DESTRUCT) mro_isa_changed_in(hv); if (PL_stashcache) { @@ -328,9 +328,10 @@ whether it is valid to call C<HvAUX()>. /* This macro may go away without notice. */ #define HvNAME_HEK(hv) \ (HvHasAUX(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name ? HvNAME_HEK_NN(hv) : NULL) +#define HvHasNAME(hv) \ + (HvHasAUX(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name && HvNAME_HEK_NN(hv)) #define HvNAME_get(hv) \ - ((HvHasAUX(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name && HvNAME_HEK_NN(hv)) \ - ? HEK_KEY(HvNAME_HEK_NN(hv)) : NULL) + (HvHasNAME(hv) ? HEK_KEY(HvNAME_HEK_NN(hv)) : NULL) #define HvNAMELEN_get(hv) \ ((HvHasAUX(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name && HvNAME_HEK_NN(hv)) \ ? HEK_LEN(HvNAME_HEK_NN(hv)) : 0) @@ -344,17 +345,18 @@ whether it is valid to call C<HvAUX()>. HvAUX(hv)->xhv_name_count == -1 ? NULL : \ HvAUX(hv)->xhv_name_u.xhvnameu_name \ ) +#define HvHasENAME_HEK(hv) \ + (HvHasAUX(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name) #define HvENAME_HEK(hv) \ - (HvHasAUX(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name ? HvENAME_HEK_NN(hv) : NULL) + (HvHasENAME_HEK(hv) ? HvENAME_HEK_NN(hv) : NULL) +#define HvHasENAME(hv) \ + (HvHasENAME_HEK(hv) && HvAUX(hv)->xhv_name_count != -1) #define HvENAME_get(hv) \ - ((HvHasAUX(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name && HvAUX(hv)->xhv_name_count != -1) \ - ? HEK_KEY(HvENAME_HEK_NN(hv)) : NULL) + (HvHasENAME(hv) ? HEK_KEY(HvENAME_HEK_NN(hv)) : NULL) #define HvENAMELEN_get(hv) \ - ((HvHasAUX(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name && HvAUX(hv)->xhv_name_count != -1) \ - ? HEK_LEN(HvENAME_HEK_NN(hv)) : 0) + (HvHasENAME(hv) ? HEK_LEN(HvENAME_HEK_NN(hv)) : 0) #define HvENAMEUTF8(hv) \ - ((HvHasAUX(hv) && HvAUX(hv)->xhv_name_u.xhvnameu_name && HvAUX(hv)->xhv_name_count != -1) \ - ? HEK_UTF8(HvENAME_HEK_NN(hv)) : 0) + (HvHasENAME(hv) ? HEK_UTF8(HvENAME_HEK_NN(hv)) : 0) /* * HvKEYS gets the number of keys that actually exist(), and is provided @@ -1858,7 +1858,7 @@ Perl_magic_clearisa(pTHX_ SV *sv, MAGIC *mg) I32 items = AvFILLp((AV *)mg->mg_obj) + 1; while (items--) { stash = GvSTASH((GV *)*svp++); - if (stash && HvENAME(stash)) mro_isa_changed_in(stash); + if (stash && HvHasENAME(stash)) mro_isa_changed_in(stash); } return 0; @@ -1870,7 +1870,7 @@ Perl_magic_clearisa(pTHX_ SV *sv, MAGIC *mg) /* The stash may have been detached from the symbol table, so check its name before doing anything. */ - if (stash && HvENAME_get(stash)) + if (stash && HvHasENAME(stash)) mro_isa_changed_in(stash); return 0; diff --git a/mro_core.c b/mro_core.c index 09fbc27ab4..2be181e102 100644 --- a/mro_core.c +++ b/mro_core.c @@ -425,8 +425,8 @@ Perl_mro_get_linear_isa(pTHX_ HV *stash) if (meta->mro_which != &dfs_alg) { /* skip for dfs, for speed */ SV * const namesv = - (HvENAME(stash)||HvNAME(stash)) - ? newSVhek(HvENAME_HEK(stash) + (HvHasENAME_HEK(stash) || HvHasNAME(stash)) + ? newSVhek(HvHasENAME_HEK(stash) ? HvENAME_HEK(stash) : HvNAME_HEK(stash)) : NULL; @@ -787,7 +787,7 @@ Perl_mro_package_moved(pTHX_ HV * const stash, HV * const oldstash, if(!(flags & 1)) { SV **svp; if( - !GvSTASH(gv) || !HvENAME(GvSTASH(gv)) || + !GvSTASH(gv) || !HvHasENAME(GvSTASH(gv)) || !(svp = hv_fetchhek(GvSTASH(gv), GvNAME_HEK(gv), 0)) || *svp != (SV *)gv ) return; @@ -903,7 +903,7 @@ S_mro_gather_and_rename(pTHX_ HV * const stashes, HV * const seen_stashes, HE *entry; I32 riter = -1; I32 items = 0; - const bool stash_had_name = stash && HvENAME(stash); + const bool stash_had_name = stash && HvHasENAME(stash); bool fetched_isarev = FALSE; HV *seen = NULL; HV *isarev = NULL; @@ -1163,7 +1163,7 @@ S_mro_gather_and_rename(pTHX_ HV * const stashes, HV * const seen_stashes, stashentry && *stashentry && isGV(*stashentry) && (substash = GvHV(*stashentry)) ) - || (oldsubstash && HvENAME_get(oldsubstash)) + || (oldsubstash && HvHasENAME(oldsubstash)) ) { /* Add :: and the key (minus the trailing ::) @@ -943,7 +943,7 @@ PP(pp_undef) /* undef *Pkg::meth_name ... */ bool method_changed = GvCVu((const GV *)sv) && (stash = GvSTASH((const GV *)sv)) - && HvENAME_get(stash); + && HvHasENAME(stash); /* undef *Foo:: */ if((stash = GvHV((const GV *)sv))) { if(HvENAME_get(stash)) @@ -968,7 +968,7 @@ PP(pp_undef) /* undef *Foo::ISA */ if( strEQ(GvNAME((const GV *)sv), "ISA") && (stash = GvSTASH((const GV *)sv)) - && (method_changed || HvENAME(stash)) ) + && (method_changed || HvHasENAME(stash)) ) mro_isa_changed_in(stash); else if(method_changed) mro_method_changed_in( @@ -1348,7 +1348,7 @@ PP(pp_select) if (!egv) egv = PL_defoutgv; hv = isGV_with_GP(egv) ? GvSTASH(egv) : NULL; - gvp = hv && HvENAME(hv) + gvp = hv && HvHasENAME(hv) ? (GV**)hv_fetch(hv, GvNAME(egv), HEK_UTF8(GvNAME_HEK(egv)) ? -GvNAMELEN(egv) : GvNAMELEN(egv), FALSE) : NULL; if (gvp && *gvp == egv) { @@ -451,7 +451,7 @@ Perl_save_gp(pTHX_ GV *gv, I32 empty) HV * const stash = GvSTASH(gv); bool isa_changed = 0; - if (stash && HvENAME(stash)) { + if (stash && HvHasENAME(stash)) { if (memEQs(GvNAME(gv), GvNAMELEN(gv), "ISA")) isa_changed = TRUE; else if (GvCVu(gv)) @@ -1171,7 +1171,7 @@ Perl_leave_scope(pTHX_ I32 base) HV * hv; a0 = ap[0]; a1 = ap[1]; a2 = ap[2]; hv = GvSTASH(a0.any_gv); - if (hv && HvENAME(hv) && ( + if (hv && HvHasENAME(hv) && ( (a2.any_sv && SvTYPE(a2.any_sv) == SVt_PVCV) || (*a1.any_svp && SvTYPE(*a1.any_svp) == SVt_PVCV) )) @@ -1286,7 +1286,7 @@ Perl_leave_scope(pTHX_ I32 base) had_method = cBOOL(GvCVu(a0.any_gv)); gp_free(a0.any_gv); GvGP_set(a0.any_gv, (GP*)a1.any_ptr); - if ((hv=GvSTASH(a0.any_gv)) && HvENAME_get(hv)) { + if ((hv=GvSTASH(a0.any_gv)) && HvHasENAME(hv)) { if (memEQs(GvNAME(a0.any_gv), GvNAMELEN(a0.any_gv), "ISA")) mro_isa_changed_in(hv); else if (had_method || GvCVu(a0.any_gv)) @@ -3728,7 +3728,7 @@ S_glob_assign_glob(pTHX_ SV *const dsv, SV *const ssv, const int dtype) /* If source has a real method, then a method is going to change */ else if( - GvCV((const GV *)ssv) && GvSTASH(dsv) && HvENAME(GvSTASH(dsv)) + GvCV((const GV *)ssv) && GvSTASH(dsv) && HvHasENAME(GvSTASH(dsv)) ) { mro_changes = 1; } @@ -3737,7 +3737,7 @@ S_glob_assign_glob(pTHX_ SV *const dsv, SV *const ssv, const int dtype) /* If dest already had a real method, that's a change as well */ if( !mro_changes && GvGP(MUTABLE_GV(dsv)) && GvCVu((const GV *)dsv) - && GvSTASH(dsv) && HvENAME(GvSTASH(dsv)) + && GvSTASH(dsv) && HvHasENAME(GvSTASH(dsv)) ) { mro_changes = 1; } @@ -3750,7 +3750,7 @@ S_glob_assign_glob(pTHX_ SV *const dsv, SV *const ssv, const int dtype) if(memEQs(name, len, "ISA") /* The stash may have been detached from the symbol table, so check its name. */ - && GvSTASH(dsv) && HvENAME(GvSTASH(dsv)) + && GvSTASH(dsv) && HvHasENAME(GvSTASH(dsv)) ) mro_changes = 2; else { @@ -3808,7 +3808,7 @@ S_glob_assign_glob(pTHX_ SV *const dsv, SV *const ssv, const int dtype) } else if(mro_changes == 3) { HV * const stash = GvHV(dsv); - if(old_stash ? (HV *)HvENAME_get(old_stash) : stash) + if(old_stash ? HvHasENAME(old_stash) : cBOOL(stash)) mro_package_moved( stash, old_stash, (GV *)dsv, 0 @@ -3958,7 +3958,7 @@ Perl_gv_setref(pTHX_ SV *const dsv, SV *const ssv) (len > 1 && name[len-2] == ':' && name[len-1] == ':') || (len == 1 && name[0] == ':') ) - && (!dref || HvENAME_get(dref)) + && (!dref || HvHasENAME(dref)) ) { mro_package_moved( (HV *)sref, (HV *)dref, @@ -3971,7 +3971,7 @@ Perl_gv_setref(pTHX_ SV *const dsv, SV *const ssv) && memEQs(GvNAME((GV*)dsv), GvNAMELEN((GV*)dsv), "ISA") /* The stash may have been detached from the symbol table, so check its name before doing anything. */ - && GvSTASH(dsv) && HvENAME(GvSTASH(dsv)) + && GvSTASH(dsv) && HvHasENAME(GvSTASH(dsv)) ) { MAGIC *mg; MAGIC * const omg = dref && SvSMAGICAL(dref) @@ -4432,7 +4432,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dsv, SV* ssv, const I32 flags) if (reset_isa) { HV * const stash = GvHV(dsv); if( - old_stash ? (HV *)HvENAME_get(old_stash) : stash + old_stash ? HvHasENAME(old_stash) : cBOOL(stash) ) mro_package_moved( stash, old_stash, @@ -6558,7 +6558,7 @@ S_anonymise_cv_maybe(pTHX_ GV *gv, CV* cv) } /* if not, anonymise: */ - gvname = (GvSTASH(gv) && HvNAME(GvSTASH(gv)) && HvENAME(GvSTASH(gv))) + gvname = (GvSTASH(gv) && HvHasNAME(GvSTASH(gv)) && HvHasENAME(GvSTASH(gv))) ? newSVhek(HvENAME_HEK(GvSTASH(gv))) : newSVpvn_flags( "__ANON__", 8, 0 ); sv_catpvs(gvname, "::__ANON__"); @@ -6793,7 +6793,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv) case SVt_PVGV: if (isGV_with_GP(sv)) { if(GvCVu((const GV *)sv) && (stash = GvSTASH(MUTABLE_GV(sv))) - && HvENAME_get(stash)) + && HvHasENAME(stash)) mro_method_changed_in(stash); gp_free(MUTABLE_GV(sv)); if (GvNAME_HEK(sv)) @@ -10082,7 +10082,7 @@ Perl_sv_resetpvn(pTHX_ const char *s, STRLEN len, HV * const stash) if (GvAV(gv)) { av_clear(GvAV(gv)); } - if (GvHV(gv) && !HvNAME_get(GvHV(gv))) { + if (GvHV(gv) && !HvHasNAME(GvHV(gv))) { hv_clear(GvHV(gv)); } } @@ -10458,9 +10458,10 @@ Perl_sv_ref(pTHX_ SV *dst, const SV *const sv, const int ob) dst = sv_newmortal(); if (ob && SvOBJECT(sv)) { - HvNAME_get(SvSTASH(sv)) - ? sv_sethek(dst, HvNAME_HEK(SvSTASH(sv))) - : sv_setpvs(dst, "__ANON__"); + if (HvHasNAME(SvSTASH(sv))) + sv_sethek(dst, HvNAME_HEK(SvSTASH(sv))); + else + sv_setpvs(dst, "__ANON__"); } else { const char * reftype = sv_reftype(sv, 0); @@ -10774,7 +10775,7 @@ S_sv_unglob(pTHX_ SV *const sv, U32 flags) SvREFCNT_inc_simple_void_NN(sv_2mortal(sv)); if (GvGP(sv)) { if(GvCVu((const GV *)sv) && (stash = GvSTASH(MUTABLE_GV(sv))) - && HvNAME_get(stash)) + && HvHasNAME(stash)) mro_method_changed_in(stash); gp_free(MUTABLE_GV(sv)); } @@ -5933,7 +5933,7 @@ S_gv_has_usable_name(pTHX_ GV *gv) { GV **gvp; return GvSTASH(gv) - && HvENAME(GvSTASH(gv)) + && HvHasENAME(GvSTASH(gv)) && (gvp = (GV **)hv_fetchhek( GvSTASH(gv), GvNAME_HEK(gv), 0 )) |