From 27c740ba3c2825f5a27bee3d496e0daaf0a639c3 Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Wed, 23 Apr 2025 11:01:51 +1000 Subject: [PATCH] we aren't going to run late INIT blocks, so don't save them I was looking over #1674, where it was suggested that late INIT blocks behave like BEGIN, and Larry approved of that (25 years ago). But history has moved on, we have 25 years of code developed under the current behaviour of INIT and I suspect such a change is more likely to break existing code than fix anything. But looking at the code in S_process_special_blocks() we do still push the CV onto PL_initav, even though that CV will never be called. So don't push the CV if it's too late to call it. --- op.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/op.c b/op.c index f616532c491c..38eeef3c465c 100644 --- a/op.c +++ b/op.c @@ -11717,11 +11717,17 @@ S_process_special_blocks(pTHX_ I32 floor, const char *const fullname, } #endif - if (PL_main_start) + if (PL_main_start) { /* diag_listed_as: Too late to run %s block */ ck_warner(packWARN(WARN_VOID), "Too late to run INIT block"); - Perl_av_create_and_push(aTHX_ &PL_initav, MUTABLE_SV(cv)); + /* callers may touch cv after we return so don't + just release it. + */ + SAVEFREESV(cv); + } + else + Perl_av_create_and_push(aTHX_ &PL_initav, MUTABLE_SV(cv)); } else return FALSE;