#define opslab_force_free(a) Perl_opslab_force_free(aTHX_ a)
#define opslab_free(a) Perl_opslab_free(aTHX_ a)
#define opslab_free_nopad(a) Perl_opslab_free_nopad(aTHX_ a)
+#define parser_free_nexttoke_ops(a,b) Perl_parser_free_nexttoke_ops(aTHX_ a,b)
# if defined(PERL_DEBUG_READONLY_OPS)
#define Slab_to_ro(a) Perl_Slab_to_ro(aTHX_ a)
#define Slab_to_rw(a) Perl_Slab_to_rw(aTHX_ a)
#define PERL_ARGS_ASSERT_OPSLAB_FREE_NOPAD \
assert(slab)
+PERL_CALLCONV void Perl_parser_free_nexttoke_ops(pTHX_ yy_parser *parser, OPSLAB *slab)
+ __attribute__nonnull__(pTHX_1)
+ __attribute__nonnull__(pTHX_2);
+#define PERL_ARGS_ASSERT_PARSER_FREE_NEXTTOKE_OPS \
+ assert(parser); assert(slab)
+
# if defined(PERL_DEBUG_READONLY_OPS)
PERL_CALLCONV void Perl_Slab_to_ro(pTHX_ OPSLAB *slab)
__attribute__nonnull__(pTHX_1);
'implicit "use Errno" after syntax error');
}
eleak(2, 0, "\"\$\0\356\"", 'qq containing $ <null> something');
-{
- local $::TODO = 'eval "END blah blah" still leaks';
- eleak(2, 0, 'END OF TERMS AND CONDITIONS', 'END followed by words');
-}
+eleak(2, 0, 'END OF TERMS AND CONDITIONS', 'END followed by words');
# [perl #114764] Attributes leak scalars
void
Perl_parser_free(pTHX_ const yy_parser *parser)
{
-#ifdef PERL_MAD
- I32 nexttoke = parser->lasttoke;
-#else
- I32 nexttoke = parser->nexttoke;
-#endif
-
PERL_ARGS_ASSERT_PARSER_FREE;
PL_curcop = parser->saved_curcop;
SvREFCNT_dec(parser->rsfp_filters);
SvREFCNT_dec(parser->lex_stuff);
SvREFCNT_dec(parser->sublex_info.repl);
+
+ Safefree(parser->lex_brackstack);
+ Safefree(parser->lex_casestack);
+ Safefree(parser->lex_shared);
+ PL_parser = parser->old_parser;
+ Safefree(parser);
+}
+
+void
+Perl_parser_free_nexttoke_ops(pTHX_ yy_parser *parser, OPSLAB *slab)
+{
+#ifdef PERL_MAD
+ I32 nexttoke = parser->lasttoke;
+#else
+ I32 nexttoke = parser->nexttoke;
+#endif
+ PERL_ARGS_ASSERT_PARSER_FREE_NEXTTOKE_OPS;
while (nexttoke--) {
#ifdef PERL_MAD
if (S_is_opval_token(parser->nexttoke[nexttoke].next_type
- & 0xffff))
- op_free(parser->nexttoke[nexttoke].next_val.opval);
+ & 0xffff)
+ && parser->nexttoke[nexttoke].next_val.opval
+ && parser->nexttoke[nexttoke].next_val.opval->op_slabbed
+ && OpSLAB(parser->nexttoke[nexttoke].next_val.opval) == slab) {
+ op_free(parser->nexttoke[nexttoke].next_val.opval);
+ parser->nexttoke[nexttoke].next_val.opval = NULL;
+ }
#else
- if (S_is_opval_token(parser->nexttype[nexttoke] & 0xffff))
+ if (S_is_opval_token(parser->nexttype[nexttoke] & 0xffff)
+ && parser->nextval[nexttoke].opval
+ && parser->nextval[nexttoke].opval->op_slabbed
+ && OpSLAB(parser->nextval[nexttoke].opval) == slab) {
op_free(parser->nextval[nexttoke].opval);
+ parser->nextval[nexttoke].opval = NULL;
+ }
#endif
}
-
- Safefree(parser->lex_brackstack);
- Safefree(parser->lex_casestack);
- Safefree(parser->lex_shared);
- PL_parser = parser->old_parser;
- Safefree(parser);
}
tokereport(type, &NEXTVAL_NEXTTOKE);
}
#endif
- /* Don’t let opslab_force_free snatch it */
- if (S_is_opval_token(type & 0xffff) && NEXTVAL_NEXTTOKE.opval) {
- assert(!NEXTVAL_NEXTTOKE.opval->op_savefree);
- NEXTVAL_NEXTTOKE.opval->op_savefree = 1;
- }
#ifdef PERL_MAD
if (PL_curforce < 0)
start_force(PL_lasttoke);
PL_lex_allbrackets--;
next_type &= 0xffff;
}
- if (S_is_opval_token(next_type) && pl_yylval.opval)
- pl_yylval.opval->op_savefree = 0; /* release */
return REPORT(next_type == 'p' ? pending_ident() : next_type);
}