RT #127786: assertion failure with eval in DB pkg.
authorDavid Mitchell <davem@iabyn.com>
Mon, 28 Mar 2016 14:36:42 +0000 (15:36 +0100)
committerDavid Mitchell <davem@iabyn.com>
Mon, 28 Mar 2016 14:36:42 +0000 (15:36 +0100)
Normally a cloned anon sud has a NULL CvOUTSIDE(), unless that
sub can contain code that will do an eval.
However, calling eval from within the DB package pretends that the eval
was done in the caller's scope. which then trips up on the NULL
CvOUTSIDE().

ts)

op.c
t/op/eval.t

diff --git a/op.c b/op.c
index b1c480b..e58f711 100644 (file)
--- a/op.c
+++ b/op.c
@@ -2622,7 +2622,13 @@ S_mark_padname_lvalue(pTHX_ PADNAME *pn)
     PadnameLVALUE_on(pn);
     while (PadnameOUTER(pn) && PARENT_PAD_INDEX(pn)) {
        cv = CvOUTSIDE(cv);
-       assert(cv);
+        /* RT #127786: cv can be NULL due to an eval within the DB package
+         * called from an anon sub - anon subs don't have CvOUTSIDE() set
+         * unless they contain an eval, but calling eval within DB
+         * pretends the eval was done in the caller's scope.
+         */
+       if (!cv)
+            break;
        assert(CvPADLIST(cv));
        pn =
           PadlistNAMESARRAY(CvPADLIST(cv))[PARENT_PAD_INDEX(pn)];
index 14f9565..7b9fb17 100644 (file)
@@ -6,7 +6,7 @@ BEGIN {
     set_up_inc('../lib');
 }
 
-plan(tests => 133);
+plan(tests => 134);
 
 eval 'pass();';
 
@@ -653,3 +653,15 @@ pass("eval in freed package does not crash");
     eval q{$@ = 2};
     ok(!$@, 'eval clearing $@');
 }
+
+# RT #127786
+# this used to give an assertion failure
+
+{
+    package DB {
+        sub f127786 { eval q/\$s/ }
+    }
+    my $s;
+    sub { $s; DB::f127786}->();
+    pass("RT #127786");
+}