#define TO_OUTPUT_WARNINGS(loc) \
(PASS2 && RExC_copy_start_in_constructed)
+#define UPDATE_WARNINGS_LOC(loc) NOOP
+
+/* 'warns' is the output of the packWARNx macro used in 'code' */
#define _WARN_HELPER(loc, warns, code) \
STMT_START { \
if (! RExC_copy_start_in_constructed) { \
__FILE__, __LINE__, loc); \
} \
if (TO_OUTPUT_WARNINGS(loc)) { \
+ if (ckDEAD(warns)) \
+ PREPARE_TO_DIE; \
code; \
+ UPDATE_WARNINGS_LOC(loc); \
} \
} STMT_END
&& maxcount <= REG_INFTY/3) /* Complement check for big
count */
{
- /* Fatal warnings may leak the regexp without this: */
- SAVEFREESV(RExC_rx_sv);
- Perl_ck_warner(aTHX_ packWARN(WARN_REGEXP),
- "Quantifier unexpected on zero-length expression "
- "in regex m/%" UTF8f "/",
- UTF8fARG(UTF, RExC_precomp_end - RExC_precomp,
- RExC_precomp));
- (void)ReREFCNT_inc(RExC_rx_sv);
- }
+ _WARN_HELPER(RExC_precomp_end, packWARN(WARN_REGEXP),
+ Perl_ck_warner(aTHX_ packWARN(WARN_REGEXP),
+ "Quantifier unexpected on zero-length expression "
+ "in regex m/%" UTF8f "/",
+ UTF8fARG(UTF, RExC_precomp_end - RExC_precomp,
+ RExC_precomp)));
+ }
min += minnext * mincount;
is_inf_internal |= deltanext == SSize_t_MAX
}
nest_check:
if (!SIZE_ONLY && !(flags&(HASWIDTH|POSTPONED)) && max > REG_INFTY/3) {
- SAVEFREESV(RExC_rx_sv); /* in case of fatal warnings */
ckWARN2reg(RExC_parse,
"%" UTF8f " matches null string many times",
UTF8fARG(UTF, (RExC_parse >= origparse
? RExC_parse - origparse
: 0),
origparse));
- (void)ReREFCNT_inc(RExC_rx_sv);
}
if (*RExC_parse == '?') {
to exact spot of failure */
vFAIL(error_msg);
}
+ UPDATE_WARNINGS_LOC(p - 1);
ender = result;
if (ender > 0xff) {
REQUIRE_UTF8(flagp);
to exact spot of failure */
vFAIL(error_msg);
}
+ UPDATE_WARNINGS_LOC(p - 1);
ender = result;
if (ender < 0x100) {
case 'c':
p++;
ender = grok_bslash_c(*p, TO_OUTPUT_WARNINGS(p));
+ UPDATE_WARNINGS_LOC(p);
p++;
break;
case '8': case '9': /* must be a backreference */
array is mortal, but is a
fail-safe */
(void) sv_2mortal(msg);
- if (PASS2) {
- SAVEFREESV(RExC_rx_sv);
+ if (ckDEAD(packWARN(WARN_REGEXP))) {
+ PREPARE_TO_DIE;
}
}
Perl_warner(aTHX_ packWARN(WARN_REGEXP), "%s",
SvREFCNT_dec_NN(msg);
}
}
+
+ if (! return_posix_warnings) {
+ UPDATE_WARNINGS_LOC(RExC_parse);
+ }
}
STATIC AV *
one. */
U8 anyof_flags = 0; /* flag bits if the node is an ANYOF-type */
U32 posixl = 0; /* bit field of posix classes matched under /l */
+ bool use_anyofd = FALSE; /* ? Is this to be an ANYOFD node */
GET_RE_DEBUG_FLAGS_DECL;
NULL,
TRUE /* checking only */);
if (PASS2 && maybe_class >= OOB_NAMEDCLASS && do_posix_warnings) {
- SAVEFREESV(RExC_rx_sv);
ckWARN4reg(not_posix_region_end,
"POSIX syntax [%c %c] belongs inside character classes%s",
*RExC_parse, *RExC_parse,
: " (but this one isn't fully valid)")
: ""
);
- (void)ReREFCNT_inc(RExC_rx_sv);
}
}
if (! valid) {
vFAIL(error_msg);
}
+ UPDATE_WARNINGS_LOC(RExC_parse - 1);
}
non_portable_endpoint++;
break;
if (! valid) {
vFAIL(error_msg);
}
+ UPDATE_WARNINGS_LOC(RExC_parse - 1);
}
non_portable_endpoint++;
break;
case 'c':
value = grok_bslash_c(*RExC_parse, TO_OUTPUT_WARNINGS(RExC_parse));
+ UPDATE_WARNINGS_LOC(RExC_parse);
RExC_parse++;
non_portable_endpoint++;
break;
&& isDIGIT(*RExC_parse)
&& ckWARN(WARN_REGEXP))
{
- SAVEFREESV(RExC_rx_sv);
reg_warn_non_literal_string(
RExC_parse + 1,
form_short_octal_warning(RExC_parse, numlen));
- (void)ReREFCNT_inc(RExC_rx_sv);
}
}
non_portable_endpoint++;
(int)value);
}
else {
- SAVEFREESV(RExC_rx_sv);
ckWARN2reg(RExC_parse,
"Unrecognized escape \\%c in character class passed through",
(int)value);
- (void)ReREFCNT_inc(RExC_rx_sv);
}
}
break;
UTF8fARG(UTF, w, rangebegin));
}
else {
- SAVEFREESV(RExC_rx_sv); /* in case of fatal warnings */
ckWARN2reg(RExC_parse,
"False [] range \"%" UTF8f "\"",
UTF8fARG(UTF, w, rangebegin));
- (void)ReREFCNT_inc(RExC_rx_sv);
cp_list = add_cp_to_invlist(cp_list, '-');
cp_foldable_list = add_cp_to_invlist(cp_foldable_list,
prevvalue);
/****** !SIZE_ONLY (Pass 2) AFTER HERE *********/
- ANYOF_FLAGS(REGNODE_p(ret)) = anyof_flags;
- if (posixl) {
- ANYOF_POSIXL_SET_TO_BITMAP(REGNODE_p(ret), posixl);
- }
-
/* If folding, we calculate all characters that could fold to or from the
* ones already on the list */
if (cp_foldable_list) {
_invlist_subtract(only_non_utf8_list, cp_list,
&only_non_utf8_list);
if (_invlist_len(only_non_utf8_list) != 0) {
- ANYOF_FLAGS(REGNODE_p(ret)) |= ANYOF_SHARED_d_MATCHES_ALL_NON_UTF8_NON_ASCII_non_d_WARN_SUPER;
+ anyof_flags |= ANYOF_SHARED_d_MATCHES_ALL_NON_UTF8_NON_ASCII_non_d_WARN_SUPER;
}
SvREFCNT_dec_NN(only_non_utf8_list);
}
}
if (warn_super) {
- ANYOF_FLAGS(REGNODE_p(ret))
+ anyof_flags
|= ANYOF_SHARED_d_MATCHES_ALL_NON_UTF8_NON_ASCII_non_d_WARN_SUPER;
/* Because an ANYOF node is the only one that warns, this node
}
}
if (only_utf8_locale_list) {
- ANYOF_FLAGS(REGNODE_p(ret))
- |= ANYOFL_FOLD
- |ANYOFL_SHARED_UTF8_LOCALE_fold_HAS_MATCHES_nonfold_REQD;
+ anyof_flags
+ |= ANYOFL_FOLD
+ | ANYOFL_SHARED_UTF8_LOCALE_fold_HAS_MATCHES_nonfold_REQD;
}
else if (cp_list) { /* Look to see if a 0-255 code point is in list */
UV start, end;
invlist_iterinit(cp_list);
if (invlist_iternext(cp_list, &start, &end) && start < 256) {
- ANYOF_FLAGS(REGNODE_p(ret)) |= ANYOFL_FOLD;
+ anyof_flags |= ANYOFL_FOLD;
}
invlist_iterfinish(cp_list);
}
}
else if ( DEPENDS_SEMANTICS
&& ( has_upper_latin1_only_utf8_matches
- || (ANYOF_FLAGS(REGNODE_p(ret)) & ANYOF_SHARED_d_MATCHES_ALL_NON_UTF8_NON_ASCII_non_d_WARN_SUPER)))
+ || (anyof_flags & ANYOF_SHARED_d_MATCHES_ALL_NON_UTF8_NON_ASCII_non_d_WARN_SUPER)))
{
- OP(REGNODE_p(ret)) = ANYOFD;
+ use_anyofd = TRUE;
optimizable = FALSE;
}
* */
if ( cp_list
&& invert
- && OP(REGNODE_p(ret)) != ANYOFD
- && ! (ANYOF_FLAGS(REGNODE_p(ret)) & (ANYOF_LOCALE_FLAGS))
+ && ! use_anyofd
+ && ! (anyof_flags & (ANYOF_LOCALE_FLAGS))
&& ! HAS_NONLOCALE_RUNTIME_PROPERTY_DEFINITION)
{
_invlist_invert(cp_list);
}
}
+ /* It's going to be an ANYOF node. */
+ OP(REGNODE_p(ret)) = (use_anyofd)
+ ? ANYOFD
+ : ((posixl)
+ ? ANYOFPOSIXL
+ : ((LOC)
+ ? ANYOFL
+ : ANYOF));
+ ANYOF_FLAGS(REGNODE_p(ret)) = anyof_flags;
+
/* Here, <cp_list> contains all the code points we can determine at
* compile time that match under all conditions. Go through it, and
* for things that belong in the bitmap, put them there, and delete from
populate_ANYOF_from_invlist(REGNODE_p(ret), &cp_list);
+ if (posixl) {
+ ANYOF_POSIXL_SET_TO_BITMAP(REGNODE_p(ret), posixl);
+ }
+
if (invert) {
ANYOF_FLAGS(REGNODE_p(ret)) |= ANYOF_INVERT;
}