From 1b218d2bd985e171257dd20f3d3b90098dd1bc82 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 7027f18f036c..9f325c03757a 100644 --- a/op.c +++ b/op.c @@ -11716,11 +11716,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;