Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 524 forks source link

h2ph: define all symbols at runtime #22110

Closed mauke closed 4 weeks ago

mauke commented 1 month ago

Preprocessor directives must be processed strictly in order. #if and #ifdef directives can inspect the current state of defined symbols. That's why it is wrong to translate #define FOO() ... to sub foo() { ... } since subroutine definitions are processed unconditionally at compile time, before the rest of the code starts running.

In particular,

unless(defined(&FOO)) {
    sub FOO () { eval q(1); }
}

is equivalent to

# at compile time:
sub FOO () { eval q(1); }

# ... later, at runtime:
unless(defined(&FOO)) {
    # does nothing
}

Fix this case by always wrapping subroutines in eval '...', which moves the symbol definition to runtime, regardless of what $t (our indentation state) is.

Similarly, generate _h2ph_pre.ph without the functionally useless unless (defined &...) { } blocks. We don't need runtime definitions (via eval) here because nothing in this file depends on the dynamic state of macro definitions. It's all #defines, no #ifs.

Fixes #22109.