-
Notifications
You must be signed in to change notification settings - Fork 601
Description
As part of research into issue #23618 and pull request #23782, I had occasion to peer into the depths of pp_ctl.c -- specifically, the definition of PP(pp_goto) running from lines 3247 to 3705. (The deprecation warning which, in GH #23618 we will turn into an exception message occurs starting at line 3654 of this file.)
In the course of looking at this function I began to wonder whether our test suite exercised all the currently existing exceptions defined therewithin. I set up an outline of that function and then searched the test suite (under t/) for tests where the various exception messages were set as the "expected" value in unit tests.
3228 static void
3229 S_check_op_type(pTHX_ OP * const o) /* Used at blead lines 3646 and 3680 */
3230 {
3231 /* Eventually we may want to stack the needed arguments
3232 * for each op. For now, we punt on the hard ones. */
3233 /* XXX This comment seems to me like wishful thinking. --sprout */
3234 if (o == UNENTERABLE)
3235 croak( /* t/lib/croak/pp_ctl */
3236 "Can't \"goto\" into a binary or list expression");
3237 if (o->op_type == OP_ENTERITER)
3238 croak( /* t/op/goto.t, t/op/eval.t */
3239 "Can't \"goto\" into the middle of a foreach loop");
3240 if (o->op_type == OP_ENTERGIVEN)
3241 croak( /* t/lib/croak/pp_ctl */
3242 "Can't \"goto\" into a \"given\" block");
3243 }
3247 PP(pp_goto)
3248 {
... /* t/op/sort.t */
3295: DIE(aTHX_ "Can't goto subroutine outside a subroutine");
... /* t/op/goto-sub.t */
3302: DIE(aTHX_ "Can't goto subroutine from an eval-string");
... /* t/op/goto-sub.t */
3305: DIE(aTHX_ "Can't goto subroutine from an eval-block");
... /* t/op/sort.t */
3308: DIE(aTHX_ "Can't goto subroutine from a sort sub (or similar callback)");
... /* UNCLEAR; see 3605 */
3314 croak("Can't \"%s\" out of a \"%s\" block",
3315 "goto", S_defer_blockname(&cxstack[ix]));
...
3554 if (label_len) {
...
3602: DIE(aTHX_ "Can't \"goto\" out of a pseudo block");
/* t/op/sort.t line 813 */
...
3605: DIE(aTHX_ "Can't \"%s\" out of a \"%s\" block", "goto", S_defer_blockname(cx));
... /* UNCLEAR; see 3314 */
3632: DIE(aTHX_ "Can't \"goto\" out of a pseudo block");
...
/* t/lib/croak/pp_ctl, t/op/goto.t, t/op/tie.t, t/op/runlevel.t */
3636: DIE(aTHX_ "Can't find label %" UTF8f,
...
3649 if (*enterops && enterops[1]) {
3650 I32 i = enterops[1] != UNENTERABLE
3651 && enterops[1]->op_type == OP_ENTER && in_block
3652 ? 2
3653 : 1;
3654 if (enterops[i])
3655 deprecate_fatal_in(WARN_DEPRECATED__GOTO_CONSTRUCT,
3656 "5.42",
3657 "Use of \"goto\" to jump into a construct");
3658 }
...
3687 } /* END if (label_len */
...
3705 } /* END PP(pp_goto) */
What I noticed was that there were 3 very similar exception messages:
3314 croak("Can't \"%s\" out of a \"%s\" block",
3315 "goto", S_defer_blockname(&cxstack[ix]));
...
3601 case CXt_NULL:
3602 DIE(aTHX_ "Can't \"goto\" out of a pseudo block");
...
3603 case CXt_DEFER:
3604 /* diag_listed_as: Can't "%s" out of a "defer" block */
3605 DIE(aTHX_ "Can't \"%s\" out of a \"%s\" block", "goto", S_defer_blockname(cx) );
I then created a branch in which I changed the word out in the 3 different exception messages to xout, yout and zout, respectively. I then ran make test_harness. Setting aside a porting test failure, the only code failure I found was in t/op/sort.t:
ok 164 - overload string called twice
AAA:
# Failed test 147 - goto out of a pseudo block 1 at op/sort.t line 813
# got "Can\'t \"goto\" yout of a pseudo bloc"
# expected eq "Can\'t \"goto\" out of a pseudo block"
# Can't "goto" yout of a pseudo block at op/sort.t line 811.
BBB:
CCC:
So it appears that the exceptions where I used xout and zout are not being exercised by the test suite. In blead, these would be at pp_ctl.c lines 3314-3315 and line 3605.
Can someone confirm my hypothesis?
Are these lines in pp_ctl.c actually reachable?
If so, can we write tests that throw the exception which triggers those two messages?