In perl.git, the branch smoke-me/remove-regcomp-setjmp has been updated <http://perl5.git.perl.org/perl.git/commitdiff/543c1290dcc11ae2ad5e44d1f870747771887c01?hp=2c4e40455f15d9b1cdc122814d345bdacdd5fad8>
- Log ----------------------------------------------------------------- commit 543c1290dcc11ae2ad5e44d1f870747771887c01 Author: Nicholas Clark <[email protected]> Date: Fri Jan 18 11:32:44 2013 +0100 In S_regclass(), create listsv as a mortal, claiming a reference if needed. The SV listsv is sometimes stored in an array generated near the end of S_regclass(). In other cases it is not used, and it needs to be freed if any of the warnings that S_regclass() can trigger turn out to be fatal. The simplest solution to this problem is to declare it from the start as a mortal, and claim a (new) reference to it if it is *not* to be freed. This permits the removal of all other code related to ensuring that it is freed at the right time, but not freed prematurely if a call to a warning returns. ----------------------------------------------------------------------- Summary of changes: embed.fnc | 2 +- embed.h | 2 +- proto.h | 2 +- regcomp.c | 24 +++++------------------- 4 files changed, 8 insertions(+), 22 deletions(-) diff --git a/embed.fnc b/embed.fnc index 9495849..e4e110a 100644 --- a/embed.fnc +++ b/embed.fnc @@ -2028,7 +2028,7 @@ EsRn |U32 |add_data |NN struct RExC_state_t *pRExC_state|U32 n \ |NN const char *s rs |void |re_croak2 |NN const char* pat1|NN const char* pat2|... Ei |I32 |regpposixcc |NN struct RExC_state_t *pRExC_state \ - |I32 value|NULLOK SV *free_me|const bool strict + |I32 value|const bool strict Es |I32 |make_trie |NN struct RExC_state_t *pRExC_state \ |NN regnode *startbranch|NN regnode *first \ |NN regnode *last|NN regnode *tail \ diff --git a/embed.h b/embed.h index 470805d..da91167 100644 --- a/embed.h +++ b/embed.h @@ -941,7 +941,7 @@ #define reginsert(a,b,c,d) S_reginsert(aTHX_ a,b,c,d) #define regpatws S_regpatws #define regpiece(a,b,c) S_regpiece(aTHX_ a,b,c) -#define regpposixcc(a,b,c,d) S_regpposixcc(aTHX_ a,b,c,d) +#define regpposixcc(a,b,c) S_regpposixcc(aTHX_ a,b,c) #define regtail(a,b,c,d) S_regtail(aTHX_ a,b,c,d) #define reguni(a,b,c) S_reguni(aTHX_ a,b,c) #define regwhite S_regwhite diff --git a/proto.h b/proto.h index e0c3279..56eec1d 100644 --- a/proto.h +++ b/proto.h @@ -6694,7 +6694,7 @@ STATIC regnode* S_regpiece(pTHX_ struct RExC_state_t *pRExC_state, I32 *flagp, U #define PERL_ARGS_ASSERT_REGPIECE \ assert(pRExC_state); assert(flagp) -PERL_STATIC_INLINE I32 S_regpposixcc(pTHX_ struct RExC_state_t *pRExC_state, I32 value, SV *free_me, const bool strict) +PERL_STATIC_INLINE I32 S_regpposixcc(pTHX_ struct RExC_state_t *pRExC_state, I32 value, const bool strict) __attribute__nonnull__(pTHX_1); #define PERL_ARGS_ASSERT_REGPPOSIXCC \ assert(pRExC_state) diff --git a/regcomp.c b/regcomp.c index 2c0cd97..55b9135 100644 --- a/regcomp.c +++ b/regcomp.c @@ -11166,8 +11166,7 @@ S_regpatws( RExC_state_t *pRExC_state, char *p , const bool recognize_comment ) #define POSIXCC(c) (POSIXCC_DONE(c) || POSIXCC_NOTYET(c)) PERL_STATIC_INLINE I32 -S_regpposixcc(pTHX_ RExC_state_t *pRExC_state, I32 value, SV *free_me, - const bool strict) +S_regpposixcc(pTHX_ RExC_state_t *pRExC_state, I32 value, const bool strict) { dVAR; I32 namedclass = OOB_NAMEDCLASS; @@ -11291,7 +11290,6 @@ S_regpposixcc(pTHX_ RExC_state_t *pRExC_state, I32 value, SV *free_me, the class closes */ while (UCHARAT(RExC_parse) && UCHARAT(RExC_parse) != ']') RExC_parse++; - SvREFCNT_dec(free_me); vFAIL3("POSIX syntax [%c %c] is reserved for future extensions", c, c); } } else { @@ -11869,8 +11867,9 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth, if (LOC) { ANYOF_FLAGS(ret) |= ANYOF_LOCALE; } - listsv = newSVpvs("# comment\n"); + listsv = newSVpvs_flags("# comment\n", SVs_TEMP); initial_listsv_len = SvCUR(listsv); + SvTEMP_off(listsv); /* Grr, TEMPs and mortals are conflated. */ } if (skip_white) { @@ -11898,12 +11897,10 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth, s++; if (*s && c == *s && s[1] == ']') { SAVEFREESV(RExC_rx_sv); - SAVEFREESV(listsv); ckWARN3reg(s+2, "POSIX syntax [%c %c] belongs inside character classes", c, c); (void)ReREFCNT_inc(RExC_rx_sv); - SvREFCNT_inc_simple_void_NN(listsv); } } @@ -11955,7 +11952,7 @@ parseit: && RExC_parse < RExC_end && POSIXCC(UCHARAT(RExC_parse))) { - namedclass = regpposixcc(pRExC_state, value, listsv, strict); + namedclass = regpposixcc(pRExC_state, value, strict); } else if (value == '\\') { if (UTF) { @@ -12192,7 +12189,6 @@ parseit: value = grok_oct(--RExC_parse, &numlen, &flags, NULL); RExC_parse += numlen; if (numlen != 3) { - SAVEFREESV(listsv); /* In case warnings are fatalized */ if (strict) { RExC_parse += (UTF) ? UTF8SKIP(RExC_parse) : 1; vFAIL("Need exactly 3 octal digits"); @@ -12209,7 +12205,6 @@ parseit: form_short_octal_warning(RExC_parse, numlen)); (void)ReREFCNT_inc(RExC_rx_sv); } - SvREFCNT_inc_simple_void_NN(listsv); } if (PL_encoding && value < 0x100) goto recode_encoding; @@ -12233,7 +12228,6 @@ parseit: default: /* Allow \_ to not give an error */ if (!SIZE_ONLY && isWORDCHAR(value) && value != '_') { - SAVEFREESV(listsv); if (strict) { vFAIL2("Unrecognized escape \\%c in character class", (int)value); @@ -12245,7 +12239,6 @@ parseit: (int)value); (void)ReREFCNT_inc(RExC_rx_sv); } - SvREFCNT_inc_simple_void_NN(listsv); } break; } /* End of switch on char following backslash */ @@ -12291,7 +12284,6 @@ parseit: const int w = (RExC_parse >= rangebegin) ? RExC_parse - rangebegin : 0; - SAVEFREESV(listsv); /* in case of fatal warnings */ if (strict) { vFAIL4("False [] range \"%*.*s\"", w, w, rangebegin); } @@ -12304,7 +12296,6 @@ parseit: cp_list = add_cp_to_invlist(cp_list, '-'); cp_list = add_cp_to_invlist(cp_list, prevvalue); } - SvREFCNT_inc_simple_void_NN(listsv); } range = 0; /* this was not a true range */ @@ -12846,7 +12837,6 @@ parseit: RExC_end = save_end; RExC_in_multi_char_class = 0; SvREFCNT_dec_NN(multi_char_matches); - SvREFCNT_dec_NN(listsv); return ret; } @@ -13004,7 +12994,6 @@ parseit: RExC_parse = (char *) cur_parse; SvREFCNT_dec(posixes); - SvREFCNT_dec_NN(listsv); SvREFCNT_dec(cp_list); return ret; } @@ -13506,7 +13495,6 @@ parseit: } SvREFCNT_dec_NN(cp_list); - SvREFCNT_dec_NN(listsv); return ret; } } @@ -13594,7 +13582,6 @@ parseit: && ! HAS_NONLOCALE_RUNTIME_PROPERTY_DEFINITION) { ARG_SET(ret, ANYOF_NONBITMAP_EMPTY); - SvREFCNT_dec_NN(listsv); } else { /* av[0] stores the character class description in its textual form: @@ -13611,8 +13598,7 @@ parseit: SV *rv; av_store(av, 0, (HAS_NONLOCALE_RUNTIME_PROPERTY_DEFINITION) - ? listsv - : (SvREFCNT_dec_NN(listsv), &PL_sv_undef)); + ? SvREFCNT_inc(listsv) : &PL_sv_undef); if (swash) { av_store(av, 1, swash); SvREFCNT_dec_NN(cp_list); -- Perl5 Master Repository
