This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pp_leavesublv(): croak on *all* PADTMPs
[perl5.git] / pp_ctl.c
index 82189bb..b49f86d 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2047,12 +2047,16 @@ S_leave_common(pTHX_ SV **newsp, SV **mark, I32 gimme,
 
     TAINT_NOT;
     if (gimme == G_SCALAR) {
-       if (MARK < SP)
-           *++newsp = (SvFLAGS(*SP) & flags)
-                           ? *SP
+       if (MARK < SP) {
+            SV *sv = *SP;
+
+           *++newsp = ((SvFLAGS(sv) & flags) && SvREFCNT(sv) == 1
+                         && !SvMAGICAL(sv))
+                           ? sv 
                            : lvalue
-                               ? sv_2mortal(SvREFCNT_inc_simple_NN(*SP))
-                               : sv_mortalcopy(*SP);
+                               ? sv_2mortal(SvREFCNT_inc_simple_NN(sv))
+                               : sv_mortalcopy(sv);
+        }
        else {
            EXTEND(newsp, 1);
            *++newsp = &PL_sv_undef;
@@ -2061,12 +2065,14 @@ S_leave_common(pTHX_ SV **newsp, SV **mark, I32 gimme,
     else if (gimme == G_ARRAY) {
        /* in case LEAVE wipes old return values */
        while (++MARK <= SP) {
-           if (SvFLAGS(*MARK) & flags)
-               *++newsp = *MARK;
+            SV *sv = *MARK;
+           if ((SvFLAGS(sv) & flags) && SvREFCNT(sv) == 1
+                         && !SvMAGICAL(sv))
+               *++newsp = sv;
            else {
                *++newsp = lvalue
-                           ? sv_2mortal(SvREFCNT_inc_simple_NN(*MARK))
-                           : sv_mortalcopy(*MARK);
+                           ? sv_2mortal(SvREFCNT_inc_simple_NN(sv))
+                           : sv_mortalcopy(sv);
                TAINT_NOT;      /* Each item is independent */
            }
        }
@@ -2331,8 +2337,7 @@ PP(pp_leavesublv)
     if (gimme == G_SCALAR) {
        if (CxLVAL(cx) && !ref) {     /* Leave it as it is if we can. */
            if (MARK <= SP) {
-               if ((SvPADTMP(TOPs) || SvREADONLY(TOPs)) &&
-                   !SvSMAGICAL(TOPs)) {
+               if ((SvPADTMP(TOPs) || SvREADONLY(TOPs))) {
                    what =
                        SvREADONLY(TOPs) ? (TOPs == &PL_sv_undef) ? "undef"
                        : "a readonly value" : "a temporary";