summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2022-11-17 14:41:35 +1100
committerJames E Keenan <jkeenan@cpan.org>2022-11-18 18:12:45 -0500
commit970609e17c79578d2051de18f156f48701755715 (patch)
treed9de3ab70e16c64e9202bf197c299d514ecce8f8
parent2e4090b82403991910f1fe64866048b62ccf5402 (diff)
downloadperl-970609e17c79578d2051de18f156f48701755715.tar.gz
change HvENAME_HEK() to HvENAME_HEK_NN() where NULLs would crash anyway
gcc 12 was producing a confusing message complaining that references to with hek_key[] were beyond the end of the array, even though a properly HEK has bytes beyond the first we declare. From experimentation I theorize the confusing message was produced because HvENAME_HEK() can return a NULL pointer, and the array pointed to by any NULL pointer is zero length, producing the array bounds warning we were seeing. Fixed by changing each hv_(fetch|delete)hek() call to use the HvENAME_HEK_NN() macro variant, which doesn't include an explicit NULL return value. mro_method_changed_in() was a bit special, it evaluated the hv_fetchhek() before the check for an anonymous stash, so I reordered the code to take advantage of C99, checking the assertions before we dereference the stash pointer, checking we have a name before trying to look it up.
-rw-r--r--hv.c8
-rw-r--r--mro_core.c13
2 files changed, 11 insertions, 10 deletions
diff --git a/hv.c b/hv.c
index 5fc9ea122d..669f766705 100644
--- a/hv.c
+++ b/hv.c
@@ -2286,8 +2286,8 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
mro_isa_changed_in(hv);
if (PL_stashcache) {
DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for effective name '%"
- HEKf "'\n", HEKfARG(HvENAME_HEK(hv))));
- (void)hv_deletehek(PL_stashcache, HvENAME_HEK(hv), G_DISCARD);
+ HEKf "'\n", HEKfARG(HvENAME_HEK_NN(hv))));
+ (void)hv_deletehek(PL_stashcache, HvENAME_HEK_NN(hv), G_DISCARD);
}
}
@@ -2300,8 +2300,8 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
{
if (name && PL_stashcache) {
DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for name '%"
- HEKf "'\n", HEKfARG(HvNAME_HEK(hv))));
- (void)hv_deletehek(PL_stashcache, HvNAME_HEK(hv), G_DISCARD);
+ HEKf "'\n", HEKfARG(HvNAME_HEK_NN(hv))));
+ (void)hv_deletehek(PL_stashcache, HvNAME_HEK_NN(hv), G_DISCARD);
}
hv_name_set(hv, NULL, 0, flags);
}
diff --git a/mro_core.c b/mro_core.c
index 2be181e102..3bd05af901 100644
--- a/mro_core.c
+++ b/mro_core.c
@@ -1327,17 +1327,18 @@ via, C<mro::method_changed_in(classname)>.
void
Perl_mro_method_changed_in(pTHX_ HV *stash)
{
- const char * const stashname = HvENAME_get(stash);
- const STRLEN stashname_len = HvENAMELEN_get(stash);
-
- SV ** const svp = hv_fetchhek(PL_isarev, HvENAME_HEK(stash), 0);
- HV * const isarev = svp ? MUTABLE_HV(*svp) : NULL;
-
PERL_ARGS_ASSERT_MRO_METHOD_CHANGED_IN;
+ const char * const stashname = HvENAME_get(stash);
+
if(!stashname)
Perl_croak(aTHX_ "Can't call mro_method_changed_in() on anonymous symbol table");
+ const STRLEN stashname_len = HvENAMELEN_get(stash);
+
+ SV ** const svp = hv_fetchhek(PL_isarev, HvENAME_HEK_NN(stash), 0);
+ HV * const isarev = svp ? MUTABLE_HV(*svp) : NULL;
+
/* Inc the package generation, since a local method changed */
HvMROMETA(stash)->pkg_gen++;