Search code examples
perlsubroutine

How can I smoke out undefined subroutines?


I want to scan a code base to identify all instances of undefined subroutines that are not presently reachable.

As an example:

use strict;
use warnings;

my $flag = 0;
if ( $flag ) {
  undefined_sub();
}

Observations

  • When $flag evaluates to true, the following warning is emitted:

    Undefined subroutine &main::undefined_sub called at - line 6
    

    I don't want to rely on warnings issued at run-time to identify undefined subroutines

  • The strict and warnings pragmas don't help here. use strict 'subs' has no effect.

  • Even the following code snippet is silent

    $ perl -Mstrict -we 'exit 0; undefined_sub()'
    

Solution

  • Perhaps Subroutines::ProhibitCallsToUndeclaredSubs policy from Perl::Critic can help

    This Policy checks that every unqualified subroutine call has a matching subroutine declaration in the current file, or that it explicitly appears in the import list for one of the included modules.

    This "policy" is a part of Perl::Critic::StricterSubs, which needs to be installed. There are a few more policies there. This is considered a severity 4 violation, so you can do

    perlcritic -4 script.pl
    

    and parse the output for neither declared nor explicitly imported, or use

    perlcritic -4 --single-policy ProhibitCallsToUndeclaredSubs script.pl
    

    Some legitimate uses are still flagged, since it requires all subs to be imported explicitly.

    This is a static analyzer, which I think should fit your purpose.