Skip to content

pp_ctl.c: PP(pp_goto): Two exceptions not exercised by test suite #23889

@jkeenan

Description

@jkeenan

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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions