change#3511 was not defensive enough about try blocks, causing
Gurusamy Sarathy [Sat, 11 Mar 2000 18:11:22 +0000 (18:11 +0000)]
bogus attempts to free closures, and thence, segfaults

p4raw-link: @3511 on //depot/perl: 067f92a0e46641b4b3e89afcde43bf134105f7b7

p4raw-id: //depot/perl@5658

cop.h
perl.c
pp_ctl.c
t/op/misc.t

diff --git a/cop.h b/cop.h
index 2f1f676..5dd937e 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -361,6 +361,7 @@ struct context {
 
 /* private flags for CXt_EVAL */
 #define CXp_REAL       0x00000100      /* truly eval'', not a lookalike */
+#define CXp_TRYBLOCK   0x00000200      /* eval{}, not eval'' or similar */
 
 #ifdef USE_ITHREADS
 /* private flags for CXt_LOOP */
@@ -374,6 +375,8 @@ struct context {
 #define CxTYPE(c)      ((c)->cx_type & CXTYPEMASK)
 #define CxREALEVAL(c)  (((c)->cx_type & (CXt_EVAL|CXp_REAL))           \
                         == (CXt_EVAL|CXp_REAL))
+#define CxTRYBLOCK(c)  (((c)->cx_type & (CXt_EVAL|CXp_TRYBLOCK))       \
+                        == (CXt_EVAL|CXp_TRYBLOCK))
 
 #define CXINC (cxstack_ix < cxstack_max ? ++cxstack_ix : (cxstack_ix = cxinc()))
 
diff --git a/perl.c b/perl.c
index f26acb4..3569e93 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -1645,7 +1645,7 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags)
            SAVETMPS;
            
            push_return(PL_op->op_next);
-           PUSHBLOCK(cx, CXt_EVAL, PL_stack_sp);
+           PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
            PUSHEVAL(cx, 0, 0);
            PL_eval_root = PL_op;             /* Only needed so that goto works right. */
            
index 42811f5..533a7c3 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1815,6 +1815,8 @@ PP(pp_return)
        break;
     case CXt_EVAL:
        POPEVAL(cx);
+       if (CxTRYBLOCK(cx))
+           break;
        if (AvFILLp(PL_comppad_name) >= 0)
            free_closures();
        lex_end();
@@ -3348,7 +3350,7 @@ PP(pp_entertry)
     SAVETMPS;
 
     push_return(cLOGOP->op_other->op_next);
-    PUSHBLOCK(cx, CXt_EVAL, SP);
+    PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), SP);
     PUSHEVAL(cx, 0, 0);
     PL_eval_root = PL_op;              /* Only needed so that goto works right. */
 
index a595694..501efba 100755 (executable)
@@ -508,3 +508,10 @@ else {
 }
 EXPECT
 Use of uninitialized value in numeric eq (==) at - line 4.
+########
+$x = sub {};
+foo();
+sub foo { eval { return }; }
+print "ok\n";
+EXPECT
+ok