summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-11-21 16:12:50 -0800
committerFather Chrysostomos <sprout@cpan.org>2011-11-21 16:24:45 -0800
commit8f82b567179d2b438689e3b9818104ecfaee6373 (patch)
treeb73e2fd6e0a32ce326053af217d6cf2481eb21a9 /op.c
parentfeb8397238ac35fa664623f94191b2f117ff687e (diff)
downloadperl-8f82b567179d2b438689e3b9818104ecfaee6373.tar.gz
Make const redef warnings default in newXS
There is no reason why constant redefinition warnings should be default warnings for sub foo(){1}, but not for newCONSTSUB (which calls newXS, which triggers the warning). To make this work properly, I also had to import sv.c’s ‘are these const subs from the same SV originally?’ logic. Constants created with XS can have NULL for the SV (they return an empty list or &PL_sv_undef), which means sv.c’s logic will stop *this=\&that from warning if both this and that are such XS-created constants. newCONSTSUB needed to be consistent with that. It required tweaking a test I added a few commits ago, which arguably shouldn’t have warned the way it was written. As of this commit (and before it, too, come to think of it), newXS_len_flags’s calling convention is quite awful and would need to be throughly re-thunk before being made into an API, or probably sim- ply never made into an API.
Diffstat (limited to 'op.c')
-rw-r--r--op.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/op.c b/op.c
index 1dcfcad45a..096fe48950 100644
--- a/op.c
+++ b/op.c
@@ -6961,7 +6961,7 @@ Perl_newCONSTSUB_flags(pTHX_ HV *stash, const char *name, STRLEN len,
processor __FILE__ directive). But we need a dynamically allocated one,
and we need it to get freed. */
cv = newXS_len_flags(name, len, const_sv_xsub, file ? file : "", "",
- XS_DYNAMIC_FILENAME | flags);
+ &sv, XS_DYNAMIC_FILENAME | flags);
CvXSUBANY(cv).any_ptr = sv;
CvCONST_on(cv);
@@ -6981,14 +6981,15 @@ Perl_newXS_flags(pTHX_ const char *name, XSUBADDR_t subaddr,
{
PERL_ARGS_ASSERT_NEWXS_FLAGS;
return newXS_len_flags(
- name, name ? strlen(name) : 0, subaddr, filename, proto, flags
+ name, name ? strlen(name) : 0, subaddr, filename, proto, NULL, flags
);
}
CV *
Perl_newXS_len_flags(pTHX_ const char *name, STRLEN len,
XSUBADDR_t subaddr, const char *const filename,
- const char *const proto, U32 flags)
+ const char *const proto, SV **const_svp,
+ U32 flags)
{
CV *cv;
@@ -7015,13 +7016,29 @@ Perl_newXS_len_flags(pTHX_ const char *name, STRLEN len,
else if (CvROOT(cv) || CvXSUB(cv) || GvASSUMECV(gv)) {
/* already defined (or promised) */
const char *redefined_name;
- if (ckWARN(WARN_REDEFINE)
+ if (CvCONST(cv) && const_svp
+ && cv_const_sv(cv) == *const_svp) {
+ NOOP;
+ /* They are 2 constant subroutines generated from
+ the same constant. This probably means that
+ they are really the "same" proxy subroutine
+ instantiated in 2 places. Most likely this is
+ when a constant is exported twice. Don't warn.
+ */
+ }
+ else if ((ckWARN(WARN_REDEFINE)
&& !(
CvGV(cv) && GvSTASH(CvGV(cv))
&& HvNAMELEN(GvSTASH(CvGV(cv))) == 7
&& (redefined_name = HvNAME(GvSTASH(CvGV(cv))),
strEQ(redefined_name, "autouse"))
)
+ )
+ || (CvCONST(cv)
+ && ckWARN_d(WARN_REDEFINE)
+ && ( !const_svp
+ || sv_cmp(cv_const_sv(cv), *const_svp) )
+ )
) {
const line_t oldline = CopLINE(PL_curcop);
if (PL_parser && PL_parser->copline != NOLINE)