This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
sv.c: Make most warnings utf8-clean
authorBrian Fraser <fraserbn@gmail.com>
Thu, 6 Oct 2011 00:57:20 +0000 (17:57 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 6 Oct 2011 20:01:14 +0000 (13:01 -0700)
sv.c
t/io/open.t
t/op/method.t
t/uni/method.t

diff --git a/sv.c b/sv.c
index 3cfbe7c..069ef06 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -6351,8 +6351,8 @@ S_curse(pTHX_ SV * const sv, const bool check_refcnt) {
        if (check_refcnt && SvREFCNT(sv)) {
            if (PL_in_clean_objs)
                Perl_croak(aTHX_
-                   "DESTROY created new reference to dead object '%s'",
-                   HvNAME_get(stash));
+                   "DESTROY created new reference to dead object '%"SVf"'",
+                   SVfARG(sv_2mortal(newSVhek(HvNAME_HEK(stash)))));
            /* DESTROY gave object new lease on life */
            return FALSE;
        }
@@ -8858,7 +8858,8 @@ Perl_sv_2io(pTHX_ SV *const sv)
            gv = MUTABLE_GV(sv);
            io = GvIO(gv);
            if (!io)
-               Perl_croak(aTHX_ "Bad filehandle: %s", GvNAME(gv));
+               Perl_croak(aTHX_ "Bad filehandle: %"SVf,
+                                    SVfARG(sv_2mortal(newSVhek(GvNAME_HEK(gv)))));
            break;
        }
        /* FALL THROUGH */
@@ -13824,7 +13825,7 @@ S_varname(pTHX_ const GV *const gv, const char gvtype, PADOFFSET targ,
            return NULL;
        av = MUTABLE_AV((*av_fetch(CvPADLIST(cv), 0, FALSE)));
        sv = *av_fetch(av, targ, FALSE);
-       sv_setpvn(name, SvPV_nolen_const(sv), SvCUR(sv));
+       sv_setsv(name, sv);
     }
 
     if (subscript_type == FUV_SUBSCRIPT_HASH) {
index dce0e23..8066391 100644 (file)
@@ -10,7 +10,7 @@ $|  = 1;
 use warnings;
 use Config;
 
-plan tests => 115;
+plan tests => 119;
 
 my $Perl = which_perl();
 
@@ -105,6 +105,15 @@ EOC
 ok( !eval { open my $f, '<&', $afile; 1; },    '<& on a non-filehandle' );
 like( $@, qr/Bad filehandle:\s+$afile/,          '       right error' );
 
+ok( !eval { *some_glob = 1; open my $f, '<&', *some_glob; 1; },    '<& on a non-filehandle glob' );
+like( $@, qr/Bad filehandle:\s+some_glob/,          '       right error' );
+
+{
+    use utf8;
+    use open qw( :utf8 :std );
+    ok( !eval { use utf8; *ǡfilḛ = 1; open my $f, '<&', *ǡfilḛ; 1; },    '<& on a non-filehandle glob' );
+    like( $@, qr/Bad filehandle:\s+ǡfilḛ/u,          '       right error' );
+}
 
 # local $file tests
 {
index 8ed3dcf..5a1c754 100644 (file)
@@ -13,7 +13,7 @@ BEGIN {
 use strict;
 no warnings 'once';
 
-plan(tests => 82);
+plan(tests => 83);
 
 @A::ISA = 'B';
 @B::ISA = 'C';
@@ -343,3 +343,13 @@ is $kalled, 1, 'calling a class method via a magic variable';
 
     like(NulTest->${ \"nul\0test" }, "nul\0test", "AUTOLOAD is nul-clean");
 }
+
+
+{
+    fresh_perl_is(
+    q! sub T::DESTROY { $x = $_[0]; } bless [], "T";!,
+    "DESTROY created new reference to dead object 'T' during global destruction.",
+    {},
+       "DESTROY creating a new reference to the object generates a warning."
+    );
+}
index 5009a1c..7c458b8 100644 (file)
@@ -15,7 +15,7 @@ use utf8;
 use open qw( :utf8 :std );
 no warnings 'once';
 
-plan(tests => 16);
+plan(tests => 25);
 
 #Can't use bless yet, as it might not be clean
 
@@ -40,3 +40,59 @@ ok $@, "Even if both stash and method are in UTF-8, lookup is nul-clean";
 
 eval { my $ref = \my $var; $ref->method };
 like $@, qr/Can't call method "method" on unblessed reference /u;
+
+{
+    use utf8;
+    use open qw( :utf8 :std );
+
+    my $e;
+    
+    eval '$e = bless {}, "E::A"; E::A->foo()';
+    like ($@, qr/^\QCan't locate object method "foo" via package "E::A" at/u);
+    eval '$e = bless {}, "E::B"; $e->foo()';  
+    like ($@, qr/^\QCan't locate object method "foo" via package "E::B" at/u);
+    eval 'E::C->foo()';
+    like ($@, qr/^\QCan't locate object method "foo" via package "E::C" (perhaps /u);
+    
+    eval 'UNIVERSAL->E::D::foo()';
+    like ($@, qr/^\QCan't locate object method "foo" via package "E::D" (perhaps /u);
+    eval 'my $e = bless {}, "UNIVERSAL"; $e->E::E::foo()';
+    like ($@, qr/^\QCan't locate object method "foo" via package "E::E" (perhaps /u);
+    
+    $e = bless {}, "E::F";  # force package to exist
+    eval 'UNIVERSAL->E::F::foo()';
+    like ($@, qr/^\QCan't locate object method "foo" via package "E::F" at/u);
+    eval '$e = bless {}, "UNIVERSAL"; $e->E::F::foo()';
+    like ($@, qr/^\QCan't locate object method "foo" via package "E::F" at/u);
+}
+
+is(do { use utf8; use open qw( :utf8 :std ); eval 'Foo->boogie()';
+         $@ =~ /^\QCan't locate object method "boogie" via package "Foo" (perhaps /u ? 1 : $@}, 1);
+
+#This reimplements a bit of _fresh_perl() from test.pl, as we want to decode
+#the output of that program before using it.
+SKIP: {
+    skip_if_miniperl('no dynamic loading on miniperl, no Encode');
+
+    my $prog = q!use utf8; use open qw( :utf8 :std ); sub T::DESTROY { $x = $_[0]; } bless [], "T";!;
+    utf8::decode($prog);
+
+    my $tmpfile = tempfile();
+    my $runperl_args = {};
+    $runperl_args->{progfile} = $tmpfile;
+    $runperl_args->{stderr} = 1;
+
+    open TEST, '>', $tmpfile or die "Cannot open $tmpfile: $!";
+
+    print TEST $prog;
+    close TEST or die "Cannot close $tmpfile: $!";
+
+    my $results = runperl(%$runperl_args);
+
+    require Encode;
+    $results = Encode::decode("UTF-8", $results);
+
+    like($results,
+            qr/DESTROY created new reference to dead object 'T' during global destruction./u,
+            "DESTROY creating a new reference to the object generates a warning in UTF-8.");
+}