if (o->op_type == OP_LEAVE ||
o->op_type == OP_SCOPE ||
o->op_type == OP_LEAVELOOP ||
+ o->op_type == OP_LEAVESUB ||
o->op_type == OP_LEAVETRY)
{
*ops++ = cUNOPo->op_first;
if (label && *label) {
OP *gotoprobe = 0;
bool leaving_eval = FALSE;
+ bool in_block = FALSE;
PERL_CONTEXT *last_eval_cx = 0;
/* find label */
case CXt_SUBST:
continue;
case CXt_BLOCK:
- if (ix)
+ if (ix) {
gotoprobe = cx->blk_oldcop->op_sibling;
- else
+ in_block = TRUE;
+ } else
gotoprobe = PL_main_root;
break;
case CXt_SUB:
if (*enterops && enterops[1]) {
OP *oldop = PL_op;
- for (ix = 1; enterops[ix]; ix++) {
+ ix = enterops[1]->op_type == OP_ENTER && in_block ? 2 : 1;
+ for (; enterops[ix]; ix++) {
PL_op = enterops[ix];
/* Eventually we may want to stack the needed arguments
* for each op. For now, we punt on the hard ones. */
# "This IS structured code. It's just randomly structured."
-print "1..22\n";
+print "1..27\n";
while ($?) {
$foo = 1;
}
print ($ok ? "ok 22\n" : "not ok 22\n");
+{
+ my $false = 0;
+
+ $ok = 0;
+ { goto A; A: $ok = 1 } continue { }
+ print "not " unless $ok;
+ print "ok 23 - #20357 goto inside /{ } continue { }/ loop\n";
+
+ $ok = 0;
+ { do { goto A; A: $ok = 1 } while $false }
+ print "not " unless $ok;
+ print "ok 24 - #20154 goto inside /do { } while ()/ loop\n";
+
+ $ok = 0;
+ foreach(1) { goto A; A: $ok = 1 } continue { };
+ print "not " unless $ok;
+ print "ok 25 - goto inside /foreach () { } continue { }/ loop\n";
+
+ $ok = 0;
+ sub a {
+ A: { if ($false) { redo A; B: $ok = 1; redo A; } }
+ goto B unless $r++
+ }
+ a();
+ print "not " unless $ok;
+ print "ok 26 - #19061 loop label wiped away by goto\n";
+
+ $ok = 0;
+ for ($p=1;$p && goto A;$p=0) { A: $ok = 1 }
+ print "not " unless $ok;
+ print "ok 27 - weird case of goto and for(;;) loop\n";
+}
+
exit;
bypass: