{
dVAR;
SV *tmpRef;
+ HV *oldstash = NULL;
PERL_ARGS_ASSERT_SV_BLESS;
if (SvREADONLY(tmpRef))
Perl_croak_no_modify();
if (SvOBJECT(tmpRef)) {
- SvREFCNT_dec(SvSTASH(tmpRef));
+ oldstash = SvSTASH(tmpRef);
}
}
SvOBJECT_on(tmpRef);
SvUPGRADE(tmpRef, SVt_PVMG);
SvSTASH_set(tmpRef, MUTABLE_HV(SvREFCNT_inc_simple(stash)));
+ SvREFCNT_dec(oldstash);
if(SvSMAGICAL(tmpRef))
if(mg_find(tmpRef, PERL_MAGIC_ext) || mg_find(tmpRef, PERL_MAGIC_uvar))
require './test.pl';
}
-plan (112);
+plan (114);
+# Please do not eliminate the plan. We have tests in DESTROY blocks.
sub expected {
my($object, $package, $type) = @_;
tie $tied, main => $untied = [];
eval { bless $tied };
is ref $untied, "main", 'blessing through tied refs' or diag $@;
+
+bless \$victim, "Food";
+eval 'bless \$Food::bard, "Bard"';
+sub Bard::DESTROY {
+ isnt ref(\$victim), '__ANON__',
+ 'reblessing does not leave an object in limbo temporarily';
+ bless \$victim
+}
+undef *Food::;
+{
+ my $w;
+ # This should catch ‘Attempt to free unreferenced scalar’.
+ local $SIG{__WARN__} = sub { $w .= shift };
+ bless \$victim;
+ is $w, undef,
+ 'no warnings when reblessing inside DESTROY triggered by reblessing'
+}