summaryrefslogtreecommitdiff
path: root/t/op/sub.t
diff options
context:
space:
mode:
Diffstat (limited to 't/op/sub.t')
-rw-r--r--t/op/sub.t52
1 files changed, 51 insertions, 1 deletions
diff --git a/t/op/sub.t b/t/op/sub.t
index 154ab1ec87..e8a561ad23 100644
--- a/t/op/sub.t
+++ b/t/op/sub.t
@@ -6,7 +6,7 @@ BEGIN {
set_up_inc('../lib');
}
-plan( tests => 36 );
+plan(tests => 39);
sub empty_sub {}
@@ -245,3 +245,53 @@ sub predeclared {
predeclared(); # set $x to 42
$main::x = $main::x = "You should not see this.";
inside_predeclared(); # run test
+
+# RT #124156 death during unwinding causes crash
+# the tie allows us to trigger another die while cleaning up the stack
+# from an earlier die.
+
+{
+ package RT124156;
+
+ sub TIEHASH { bless({}, $_[0]) }
+ sub EXISTS { 0 }
+ sub FETCH { undef }
+ sub STORE { }
+ sub DELETE { die "outer\n" }
+
+ my @value;
+ eval {
+ @value = sub {
+ @value = sub {
+ my %a;
+ tie %a, "RT124156";
+ local $a{foo} = "bar";
+ die "inner";
+ ("dd2a", "dd2b");
+ }->();
+ ("cc3a", "cc3b");
+ }->();
+ };
+ ::is($@, "outer\n", "RT124156 plain");
+
+ my $destroyed = 0;
+ sub DESTROY { $destroyed = 1 }
+
+ sub f {
+ my $x;
+ my $f = sub {
+ $x = 1; # force closure
+ my %a;
+ tie %a, "RT124156";
+ local $a{foo} = "bar";
+ die "inner";
+ };
+ bless $f, 'RT124156';
+ $f->();
+ }
+
+ eval { f(); };
+ # as opposed to $@ eq "Can't undef active subroutine"
+ ::is($@, "outer\n", "RT124156 depth");
+ ::is($destroyed, 1, "RT124156 freed cv");
+}