Skip to content

Commit b1414dc

Browse files
committed
warn on redefining an array constant sub
The code in report_redefined_cv() would check whether the old constant and the new constant were the same SV to avoid warning on duplicate imports of the same constant. Since both gv_setref() and report_redefined_cv() used cv_const_sv() to fetch the constant SV, which returns NULL for an AV based constant sub, the check for the equivalent SV would compare NULL to NULL and report_redefined_cv() would return early. Additional checks were required further down to prevent sv_cmp() being called on AVs. The check for simple SV's allow redefinition of constant subs if the new value string compares the same as the old value. The AV check does not try to allow that. Fixed #20742
1 parent 6c19911 commit b1414dc

File tree

3 files changed

+17
-5
lines changed

3 files changed

+17
-5
lines changed

op.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15321,7 +15321,7 @@ Perl_report_redefined_cv(pTHX_ const SV *name, const CV *old_cv,
1532115321
{
1532215322
const char *hvname;
1532315323
bool is_const = cBOOL(CvCONST(old_cv));
15324-
SV *old_const_sv = is_const ? cv_const_sv(old_cv) : NULL;
15324+
SV *old_const_sv = is_const ? cv_const_sv_or_av(old_cv) : NULL;
1532515325

1532615326
PERL_ARGS_ASSERT_REPORT_REDEFINED_CV;
1532715327

@@ -15344,14 +15344,20 @@ Perl_report_redefined_cv(pTHX_ const SV *name, const CV *old_cv,
1534415344
)
1534515345
|| (is_const
1534615346
&& ckWARN_d(WARN_REDEFINE)
15347-
&& (!new_const_svp || sv_cmp(old_const_sv, *new_const_svp))
15347+
&& (!new_const_svp ||
15348+
!*new_const_svp ||
15349+
!old_const_sv ||
15350+
SvTYPE(old_const_sv) == SVt_PVAV ||
15351+
SvTYPE(*new_const_svp) == SVt_PVAV ||
15352+
sv_cmp(old_const_sv, *new_const_svp))
1534815353
)
15349-
)
15354+
) {
1535015355
Perl_warner(aTHX_ packWARN(WARN_REDEFINE),
1535115356
is_const
1535215357
? "Constant subroutine %" SVf " redefined"
1535315358
: "Subroutine %" SVf " redefined",
1535415359
SVfARG(name));
15360+
}
1535515361
}
1535615362

1535715363
/*

sv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3913,7 +3913,7 @@ Perl_gv_setref(pTHX_ SV *const dsv, SV *const ssv)
39133913
{
39143914
SV * const new_const_sv =
39153915
CvCONST((const CV *)sref)
3916-
? cv_const_sv((const CV *)sref)
3916+
? cv_const_sv_or_av((const CV *)sref)
39173917
: NULL;
39183918
HV * const stash = GvSTASH((const GV *)dsv);
39193919
report_redefined_cv(

t/lib/warnings/op

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ my @s = @f["]", "a"];
284284
@h[glob ""];
285285
@h[readline ""];
286286
@h[m ""];
287-
use constant phoo => 1..3;
288287
@h[+phoo]; # rv2av
289288
@h[sort foo];
290289
@h[reverse foo];
@@ -1019,6 +1018,13 @@ sub fred () { 1 }
10191018
EXPECT
10201019
Constant subroutine main::fred redefined at - line 3.
10211020
########
1021+
# op.c github #20742
1022+
use constant fred => 1, 2;
1023+
use constant fred => 2, 3;
1024+
EXPECT
1025+
OPTIONS regex
1026+
Constant subroutine main::fred redefined at .*lib/constant\.pm line \d+
1027+
########
10221028
# op.c
10231029
use feature "lexical_subs", "state";
10241030
my sub fred () { 1 }

0 commit comments

Comments
 (0)