NAME

Perl::Critic::Policy::ControlStructures::ProhibitGotoIntoConstruct - Prohibit goto LABEL that jumps into a loop or block construct

VERSION

version 0.07

DESCRIPTION

This policy flags goto LABEL when the target label is inside a loop or block construct and the goto statement is outside that construct. Jumping into a construct with goto is deprecated in Perl (since 5.12) and will become a fatal error in Perl 5.44 (see "Goto Block Construct" in perldeprecation, perl5#23618).

The three forms of goto are handled as follows:

goto LABEL

Flagged if the label is inside a loop, if/unless block, given, eval, do, sub, map, or grep, and the goto is outside that construct.

goto &NAME

Not flagged -- this is a subroutine restart, not a label jump.

goto EXPR

Not flagged -- the target cannot be determined statically.

EXAMPLES

while (1) {
    LABEL:
        do_stuff();
}
goto LABEL;    # not ok -- jumps into a while loop

if ($x) {
    LABEL:
        do_stuff();
}
goto LABEL;    # not ok -- jumps into an if block

eval {
    LABEL:
        do_stuff();
};
goto LABEL;    # not ok -- jumps into an eval

do {
    LABEL:
        do_stuff();
};
goto LABEL;    # not ok -- jumps into a do block

LABEL:
do_stuff();
goto LABEL;    # ok -- label is at the same scope level

LABEL:
while (1) {
    do_stuff();
}
goto LABEL;    # ok -- label is on the loop, not inside it

while (1) {
    LABEL:
        do_stuff();
    goto LABEL;    # ok -- goto and label in the same construct
}

goto &some_sub;    # ok -- not a label jump

my $label = 'LABEL';
goto $label;       # ok -- goto EXPR, target unknown statically

CONFIGURATION

This policy has no configurable parameters.

AFFILIATION

This policy is part of Perl::Critic::PolicyBundle::LoopsAndLabels.

LIMITATIONS

defer blocks (Perl 5.36+) are not detected. PPI does not recognize defer as a keyword, so code following a defer block may be parsed incorrectly and the goto statement inside it may not be identified as PPI::Statement::Break.

Labels that are ON a compound statement (e.g., LABEL: while (...) {...}) are not flagged. In Perl, jumping to such a label targets the loop it itself, not the loop body.

SEE ALSO

Perl::Critic, "goto" in perlfunc, perldeprecation, https://github.com/Perl/perl5/issues/23618

AUTHOR

Dean Hamstead <dean@fragfest.com.au>

COPYRIGHT AND LICENSE

This software is Copyright (c) 2026 by Dean Hamstead.

This is free software, licensed under:

The MIT (X11) License