summaryrefslogtreecommitdiff
path: root/ext
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 /ext
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 'ext')
-rw-r--r--ext/XS-APItest/APItest.xs9
-rw-r--r--ext/XS-APItest/t/newCONSTSUB.t38
2 files changed, 36 insertions, 11 deletions
diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs
index 46cc458d52..4f84c60d3e 100644
--- a/ext/XS-APItest/APItest.xs
+++ b/ext/XS-APItest/APItest.xs
@@ -1878,11 +1878,12 @@ call_method(methname, flags, ...)
PUSHs(sv_2mortal(newSViv(i)));
void
-newCONSTSUB_type(stash, name, flags, type)
+newCONSTSUB_type(stash, name, flags, type, sv)
HV* stash
SV* name
I32 flags
int type
+ SV* sv
PREINIT:
CV* cv;
STRLEN len;
@@ -1890,10 +1891,12 @@ newCONSTSUB_type(stash, name, flags, type)
PPCODE:
switch (type) {
case 0:
- cv = newCONSTSUB(stash, pv, NULL);
+ cv = newCONSTSUB(stash, pv, SvOK(sv) ? sv : NULL);
break;
case 1:
- cv = newCONSTSUB_flags(stash, pv, len, flags | SvUTF8(name), NULL);
+ cv = newCONSTSUB_flags(
+ stash, pv, len, flags | SvUTF8(name), SvOK(sv) ? sv : NULL
+ );
break;
}
EXTEND(SP, 2);
diff --git a/ext/XS-APItest/t/newCONSTSUB.t b/ext/XS-APItest/t/newCONSTSUB.t
index b6e672d986..afd44262da 100644
--- a/ext/XS-APItest/t/newCONSTSUB.t
+++ b/ext/XS-APItest/t/newCONSTSUB.t
@@ -1,24 +1,46 @@
#!perl
use strict;
-use warnings;
use utf8;
use open qw( :utf8 :std );
-use Test::More tests => 11;
+use Test::More tests => 14;
use XS::APItest;
-my ($const, $glob) = XS::APItest::newCONSTSUB_type(\%::, "sanity_check", 0, 0);
+# This test must happen outside of any warnings scope
+{
+ local $^W;
+ my $w;
+ local $SIG{__WARN__} = sub { $w .= shift };
+ sub frimple() { 78 }
+ newCONSTSUB_type(\%::, "frimple", 0, 1, undef);
+ like $w, qr/Constant subroutine frimple redefined at /,
+ 'newCONSTSUB constant redefinition warning is unaffected by $^W=0';
+ undef $w;
+ newCONSTSUB_type(\%::, "frimple", 0, 1, undef);
+ is $w, undef, '...unless the const SVs are the same';
+ eval 'sub frimple() { 78 }';
+ undef $w;
+ newCONSTSUB_type(\%::, "frimple", 0, 1, "78");
+ is $w, undef, '...or the const SVs have the same value';
+}
+
+use warnings;
+
+my ($const, $glob) =
+ XS::APItest::newCONSTSUB_type(\%::, "sanity_check", 0, 0, undef);
ok $const;
ok *{$glob}{CODE};
-($const, $glob) = XS::APItest::newCONSTSUB_type(\%::, "\x{30cb}", 0, 0);
+($const, $glob) =
+ XS::APItest::newCONSTSUB_type(\%::, "\x{30cb}", 0, 0, undef);
ok $const, "newCONSTSUB generates the constant,";
ok *{$glob}{CODE}, "..and the glob,";
ok !$::{"\x{30cb}"}, "...but not the right one";
-($const, $glob) = XS::APItest::newCONSTSUB_type(\%::, "\x{30cd}", 0, 1);
+($const, $glob) =
+ XS::APItest::newCONSTSUB_type(\%::, "\x{30cd}", 0, 1, undef);
ok $const, "newCONSTSUB_flags generates the constant,";
ok *{$glob}{CODE}, "..and the glob,";
ok $::{"\x{30cd}"}, "...the right one!";
@@ -29,7 +51,7 @@ eval q{
my $w;
local $SIG{__WARN__} = sub { $w .= shift };
*foo = sub(){123};
- newCONSTSUB_type(\%::, "foo", 0, 1);
+ newCONSTSUB_type(\%::, "foo", 0, 1, undef);
is $w, undef, 'newCONSTSUB uses calling scope for redefinition warnings';
}
};
@@ -39,11 +61,11 @@ eval q{
*{"foo::\x{100}"} = sub(){return 123};
my $w;
local $SIG{__WARN__} = sub { $w .= shift };
- newCONSTSUB_type(\%foo::, "\x{100}", 0, 1);
+ newCONSTSUB_type(\%foo::, "\x{100}", 0, 1, undef);
like $w, qr/Subroutine \x{100} redefined at /,
'newCONSTSUB redefinition warning + utf8';
undef $w;
- newCONSTSUB_type(\%foo::, "\x{100}", 0, 1);
+ newCONSTSUB_type(\%foo::, "\x{100}", 0, 1, 54);
like $w, qr/Constant subroutine \x{100} redefined at /,
'newCONSTSUB constant redefinition warning + utf8';
}