Patch attached.
--
Paul Evans
=== modified file 'lib/Syntax/Keyword/Try.xs'
--- lib/Syntax/Keyword/Try.xs 2016-11-25 00:10:28 +0000
+++ lib/Syntax/Keyword/Try.xs 2016-11-25 15:05:12 +0000
@@ -77,6 +77,14 @@
return op;
}
+#define newLOCALISEOP(gv) MY_newLOCALISEOP(aTHX_ gv)
+static OP *MY_newLOCALISEOP(pTHX_ GV *gv)
+{
+ OP *op = newGVOP(OP_GVSV, 0, gv);
+ op->op_private |= OPpLVAL_INTRO;
+ return op;
+}
+
#define lex_consume(s) MY_lex_consume(aTHX_ s)
static int MY_lex_consume(pTHX_ char *s)
{
@@ -270,19 +278,24 @@
),
newLISTOP(OP_SCOPE, 0, catch, NULL)
);
+
+ /* localise $@ beforehand */
+ ret = op_prepend_elem(OP_LINESEQ, newLOCALISEOP(PL_errgv), ret);
}
/* If there's a finally, make
- * $RET = { OP_PUSHFINALLY($FINALLY); $RET }
+ * $RET = OP_PUSHFINALLY($FINALLY); $RET
*/
if(finally) {
+ ret = op_prepend_elem(OP_LINESEQ, newPUSHFINALLYOP(finally), ret);
+ }
+
+ /* If there's either catch or finally, block-wrap the result
+ */
+ if(catch || finally) {
ret = newLISTOP(OP_LEAVE, 0,
- op_prepend_elem(OP_LINESEQ, newOP(OP_ENTER, 0),
- op_prepend_elem(OP_LINESEQ, newPUSHFINALLYOP(finally),
- ret
- )
- ), NULL
- );
+ op_prepend_elem(OP_LINESEQ, newOP(OP_ENTER, 0), ret),
+ NULL);
}
*op = ret;
=== added file 't/14try-localises.t'
--- t/14try-localises.t 1970-01-01 00:00:00 +0000
+++ t/14try-localises.t 2016-11-25 15:05:12 +0000
@@ -0,0 +1,20 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use Syntax::Keyword::Try;
+
+# try/catch localises $@ (RT118415)
+{
+ eval { die "oopsie" };
+ like( $@, qr/^oopsie at /, '$@ before try/catch' );
+
+ try { die "another failure" } catch {}
+
+ like( $@, qr/^oopsie at /, '$@ after try/catch' );
+}
+
+done_testing;