summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2022-11-17 14:30:39 +1100
committerJames E Keenan <jkeenan@cpan.org>2022-11-18 18:12:45 -0500
commit2e4090b82403991910f1fe64866048b62ccf5402 (patch)
tree8ca250b0bfb4e386128336ee73db71caba26c032
parenta33534361e54c6342c59edd0c06b6bbb9ac5776c (diff)
downloadperl-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.xs2
-rw-r--r--gv.c8
-rw-r--r--hv.c14
-rw-r--r--hv.h20
-rw-r--r--mg.c4
-rw-r--r--mro_core.c10
-rw-r--r--pp.c4
-rw-r--r--pp_sys.c2
-rw-r--r--scope.c6
-rw-r--r--sv.c29
-rw-r--r--util.c2
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)
diff --git a/gv.c b/gv.c
index 0145644e47..0982fee380 100644
--- a/gv.c
+++ b/gv.c
@@ -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);
diff --git a/hv.c b/hv.c
index 7ab14a84f7..5fc9ea122d 100644
--- a/hv.c
+++ b/hv.c
@@ -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) {
diff --git a/hv.h b/hv.h
index 2083ce9b2c..c005ec653a 100644
--- a/hv.h
+++ b/hv.h
@@ -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
diff --git a/mg.c b/mg.c
index d4925fbf02..82b9178517 100644
--- a/mg.c
+++ b/mg.c
@@ -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 ::)
diff --git a/pp.c b/pp.c
index 5b4c1efe64..490649f01f 100644
--- a/pp.c
+++ b/pp.c
@@ -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(
diff --git a/pp_sys.c b/pp_sys.c
index bdf458bb4d..3c831408e2 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -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) {
diff --git a/scope.c b/scope.c
index 4584dd47de..6cb1433d1c 100644
--- a/scope.c
+++ b/scope.c
@@ -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))
diff --git a/sv.c b/sv.c
index 139d3fefa2..8d80b5e31b 100644
--- a/sv.c
+++ b/sv.c
@@ -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));
}
diff --git a/util.c b/util.c
index 1669008287..bc129d272b 100644
--- a/util.c
+++ b/util.c
@@ -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
))