This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Peek.t: Test that DeadCode doesn’t crash
[perl5.git] / regcomp.c
index c5964a0..b5ed584 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -3663,7 +3663,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
                uc = utf8_to_uvchr_buf(s, s + l, NULL);
                l = utf8_length(s, s + l);
            }
-           else if (has_exactf_sharp_s) {
+           if (has_exactf_sharp_s) {
                RExC_seen |= REG_SEEN_EXACTF_SHARP_S;
            }
            min += l - min_subtract;
@@ -3960,6 +3960,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
                      && !(data->flags & SF_HAS_EVAL)
                      && !deltanext     /* atom is fixed width */
                      && minnext != 0   /* CURLYM can't handle zero width */
+                      && ! (RExC_seen & REG_SEEN_EXACTF_SHARP_S) /* Nor \xDF */
                ) {
                    /* XXXX How to optimize if data == 0? */
                    /* Optimize to a simpler form.  */
@@ -5206,6 +5207,50 @@ S_compile_runtime_code(pTHX_ RExC_state_t * const pRExC_state,
 }
 
 
+STATIC bool
+S_setup_longest(pTHX_ RExC_state_t *pRExC_state, SV* sv_longest, SV** rx_utf8, SV** rx_substr, I32* rx_end_shift, I32 lookbehind, I32 offset, I32 *minlen, STRLEN longest_length, bool eol, bool meol)
+{
+    /* This is the common code for setting up the floating and fixed length
+     * string data extracted from Perlre_op_compile() below.  Returns a boolean
+     * as to whether succeeded or not */
+
+    I32 t,ml;
+
+    if (! (longest_length
+           || (eol /* Can't have SEOL and MULTI */
+               && (! meol || (RExC_flags & RXf_PMf_MULTILINE)))
+          )
+            /* See comments for join_exact for why REG_SEEN_EXACTF_SHARP_S */
+        || (RExC_seen & REG_SEEN_EXACTF_SHARP_S))
+    {
+        return FALSE;
+    }
+
+    /* copy the information about the longest from the reg_scan_data
+        over to the program. */
+    if (SvUTF8(sv_longest)) {
+        *rx_utf8 = sv_longest;
+        *rx_substr = NULL;
+    } else {
+        *rx_substr = sv_longest;
+        *rx_utf8 = NULL;
+    }
+    /* end_shift is how many chars that must be matched that
+        follow this item. We calculate it ahead of time as once the
+        lookbehind offset is added in we lose the ability to correctly
+        calculate it.*/
+    ml = minlen ? *(minlen) : (I32)longest_length;
+    *rx_end_shift = ml - offset
+        - longest_length + (SvTAIL(sv_longest) != 0)
+        + lookbehind;
+
+    t = (eol/* Can't have SEOL and MULTI */
+         && (! meol || (RExC_flags & RXf_PMf_MULTILINE)));
+    fbm_compile(sv_longest, t ? FBMcf_TAIL : 0);
+
+    return TRUE;
+}
+
 /*
  * Perl_re_op_compile - the perl internal RE engine's function to compile a
  * regular expression into internal code.
@@ -5258,7 +5303,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
     dVAR;
     REGEXP *rx;
     struct regexp *r;
-    register regexp_internal *ri;
+    regexp_internal *ri;
     STRLEN plen;
     char  * VOL exp;
     char* xend;
@@ -6173,105 +6218,56 @@ reStudy:
        scan_commit(pRExC_state, &data,&minlen,0);
        SvREFCNT_dec(data.last_found);
 
-        /* Note that code very similar to this but for anchored string 
-           follows immediately below, changes may need to be made to both. 
-           Be careful. 
-         */
        longest_float_length = CHR_SVLEN(data.longest_float);
-       if (longest_float_length
-           || (data.flags & SF_FL_BEFORE_EOL
-               && (!(data.flags & SF_FL_BEFORE_MEOL)
-                   || (RExC_flags & RXf_PMf_MULTILINE)))) 
-        {
-            I32 t,ml;
 
-            /* See comments for join_exact for why REG_SEEN_EXACTF_SHARP_S */
-           if ((RExC_seen & REG_SEEN_EXACTF_SHARP_S)
-               || (SvCUR(data.longest_fixed)  /* ok to leave SvCUR */
-                   && data.offset_fixed == data.offset_float_min
-                   && SvCUR(data.longest_fixed) == SvCUR(data.longest_float)))
-                   goto remove_float;          /* As in (a)+. */
-
-            /* copy the information about the longest float from the reg_scan_data
-               over to the program. */
-           if (SvUTF8(data.longest_float)) {
-               r->float_utf8 = data.longest_float;
-               r->float_substr = NULL;
-           } else {
-               r->float_substr = data.longest_float;
-               r->float_utf8 = NULL;
-           }
-           /* float_end_shift is how many chars that must be matched that 
-              follow this item. We calculate it ahead of time as once the
-              lookbehind offset is added in we lose the ability to correctly
-              calculate it.*/
-           ml = data.minlen_float ? *(data.minlen_float) 
-                                  : (I32)longest_float_length;
-           r->float_end_shift = ml - data.offset_float_min
-               - longest_float_length + (SvTAIL(data.longest_float) != 0)
-               + data.lookbehind_float;
+        if (! ((SvCUR(data.longest_fixed)  /* ok to leave SvCUR */
+                   && data.offset_fixed == data.offset_float_min
+                   && SvCUR(data.longest_fixed) == SvCUR(data.longest_float)))
+            && S_setup_longest (aTHX_ pRExC_state,
+                                    data.longest_float,
+                                    &(r->float_utf8),
+                                    &(r->float_substr),
+                                    &(r->float_end_shift),
+                                    data.lookbehind_float,
+                                    data.offset_float_min,
+                                    data.minlen_float,
+                                    longest_float_length,
+                                    data.flags & SF_FL_BEFORE_EOL,
+                                    data.flags & SF_FL_BEFORE_MEOL))
+        {
            r->float_min_offset = data.offset_float_min - data.lookbehind_float;
            r->float_max_offset = data.offset_float_max;
            if (data.offset_float_max < I32_MAX) /* Don't offset infinity */
                r->float_max_offset -= data.lookbehind_float;
-           
-           t = (data.flags & SF_FL_BEFORE_EOL /* Can't have SEOL and MULTI */
-                      && (!(data.flags & SF_FL_BEFORE_MEOL)
-                          || (RExC_flags & RXf_PMf_MULTILINE)));
-           fbm_compile(data.longest_float, t ? FBMcf_TAIL : 0);
        }
        else {
-         remove_float:
            r->float_substr = r->float_utf8 = NULL;
            SvREFCNT_dec(data.longest_float);
            longest_float_length = 0;
        }
 
-        /* Note that code very similar to this but for floating string 
-           is immediately above, changes may need to be made to both. 
-           Be careful. 
-         */
        longest_fixed_length = CHR_SVLEN(data.longest_fixed);
 
-        /* See comments for join_exact for why REG_SEEN_EXACTF_SHARP_S */
-       if (! (RExC_seen & REG_SEEN_EXACTF_SHARP_S)
-           && (longest_fixed_length
-               || (data.flags & SF_FIX_BEFORE_EOL /* Cannot have SEOL and MULTI */
-                   && (!(data.flags & SF_FIX_BEFORE_MEOL)
-                       || (RExC_flags & RXf_PMf_MULTILINE)))) )
+        if (S_setup_longest (aTHX_ pRExC_state,
+                                data.longest_fixed,
+                                &(r->anchored_utf8),
+                                &(r->anchored_substr),
+                                &(r->anchored_end_shift),
+                                data.lookbehind_fixed,
+                                data.offset_fixed,
+                                data.minlen_fixed,
+                                longest_fixed_length,
+                                data.flags & SF_FIX_BEFORE_EOL,
+                                data.flags & SF_FIX_BEFORE_MEOL))
         {
-            I32 t,ml;
-
-            /* copy the information about the longest fixed 
-               from the reg_scan_data over to the program. */
-           if (SvUTF8(data.longest_fixed)) {
-               r->anchored_utf8 = data.longest_fixed;
-               r->anchored_substr = NULL;
-           } else {
-               r->anchored_substr = data.longest_fixed;
-               r->anchored_utf8 = NULL;
-           }
-           /* fixed_end_shift is how many chars that must be matched that 
-              follow this item. We calculate it ahead of time as once the
-              lookbehind offset is added in we lose the ability to correctly
-              calculate it.*/
-            ml = data.minlen_fixed ? *(data.minlen_fixed) 
-                                   : (I32)longest_fixed_length;
-            r->anchored_end_shift = ml - data.offset_fixed
-               - longest_fixed_length + (SvTAIL(data.longest_fixed) != 0)
-               + data.lookbehind_fixed;
            r->anchored_offset = data.offset_fixed - data.lookbehind_fixed;
-
-           t = (data.flags & SF_FIX_BEFORE_EOL /* Can't have SEOL and MULTI */
-                && (!(data.flags & SF_FIX_BEFORE_MEOL)
-                    || (RExC_flags & RXf_PMf_MULTILINE)));
-           fbm_compile(data.longest_fixed, t ? FBMcf_TAIL : 0);
        }
        else {
            r->anchored_substr = r->anchored_utf8 = NULL;
            SvREFCNT_dec(data.longest_fixed);
            longest_fixed_length = 0;
        }
+
        if (ri->regstclass
            && (OP(ri->regstclass) == REG_ANY || OP(ri->regstclass) == SANY))
            ri->regstclass = NULL;
@@ -8303,11 +8299,11 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
     /* paren: Parenthesized? 0=top, 1=(, inside: changed to letter. */
 {
     dVAR;
-    register regnode *ret;             /* Will be the head of the group. */
-    register regnode *br;
-    register regnode *lastbr;
-    register regnode *ender = NULL;
-    register I32 parno = 0;
+    regnode *ret;              /* Will be the head of the group. */
+    regnode *br;
+    regnode *lastbr;
+    regnode *ender = NULL;
+    I32 parno = 0;
     I32 flags;
     U32 oregflags = RExC_flags;
     bool have_branch = 0;
@@ -9313,9 +9309,9 @@ STATIC regnode *
 S_regbranch(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, I32 first, U32 depth)
 {
     dVAR;
-    register regnode *ret;
-    register regnode *chain = NULL;
-    register regnode *latest;
+    regnode *ret;
+    regnode *chain = NULL;
+    regnode *latest;
     I32 flags = 0, c = 0;
     GET_RE_DEBUG_FLAGS_DECL;
 
@@ -9386,9 +9382,9 @@ STATIC regnode *
 S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
 {
     dVAR;
-    register regnode *ret;
-    register char op;
-    register char *next;
+    regnode *ret;
+    char op;
+    char *next;
     I32 flags;
     const char * const origparse = RExC_parse;
     I32 min;
@@ -10432,9 +10428,9 @@ tryagain:
            RExC_parse++;
 
        defchar: {
-           register STRLEN len = 0;
+           STRLEN len = 0;
            UV ender;
-           register char *p;
+           char *p;
            char *s;
 #define MAX_NODE_STRING_SIZE 127
            char foldbuf[MAX_NODE_STRING_SIZE+UTF8_MAXBYTES_CASE];
@@ -11336,11 +11332,11 @@ STATIC regnode *
 S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
 {
     dVAR;
-    register UV nextvalue;
-    register UV prevvalue = OOB_UNICODE;
-    register IV range = 0;
+    UV nextvalue;
+    UV prevvalue = OOB_UNICODE;
+    IV range = 0;
     UV value = 0;
-    register regnode *ret;
+    regnode *ret;
     STRLEN numlen;
     IV namedclass = OOB_NAMEDCLASS;
     char *rangebegin = NULL;
@@ -13026,7 +13022,7 @@ STATIC regnode *                        /* Location. */
 S_reg_node(pTHX_ RExC_state_t *pRExC_state, U8 op)
 {
     dVAR;
-    register regnode *ptr;
+    regnode *ptr;
     regnode * const ret = RExC_emit;
     GET_RE_DEBUG_FLAGS_DECL;
 
@@ -13068,7 +13064,7 @@ STATIC regnode *                        /* Location. */
 S_reganode(pTHX_ RExC_state_t *pRExC_state, U8 op, U32 arg)
 {
     dVAR;
-    register regnode *ptr;
+    regnode *ptr;
     regnode * const ret = RExC_emit;
     GET_RE_DEBUG_FLAGS_DECL;
 
@@ -13140,9 +13136,9 @@ STATIC void
 S_reginsert(pTHX_ RExC_state_t *pRExC_state, U8 op, regnode *opnd, U32 depth)
 {
     dVAR;
-    register regnode *src;
-    register regnode *dst;
-    register regnode *place;
+    regnode *src;
+    regnode *dst;
+    regnode *place;
     const int offset = regarglen[(U8)op];
     const int size = NODE_STEP_REGNODE + offset;
     GET_RE_DEBUG_FLAGS_DECL;
@@ -13228,7 +13224,7 @@ STATIC void
 S_regtail(pTHX_ RExC_state_t *pRExC_state, regnode *p, const regnode *val,U32 depth)
 {
     dVAR;
-    register regnode *scan;
+    regnode *scan;
     GET_RE_DEBUG_FLAGS_DECL;
 
     PERL_ARGS_ASSERT_REGTAIL;
@@ -13287,7 +13283,7 @@ STATIC U8
 S_regtail_study(pTHX_ RExC_state_t *pRExC_state, regnode *p, const regnode *val,U32 depth)
 {
     dVAR;
-    register regnode *scan;
+    regnode *scan;
     U8 exact = PSEUDO;
 #ifdef EXPERIMENTAL_INPLACESCAN
     I32 min = 0;
@@ -13528,7 +13524,7 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o)
 {
 #ifdef DEBUGGING
     dVAR;
-    register int k;
+    int k;
 
     /* Should be synchronized with * ANYOF_ #xdefines in regcomp.h */
     static const char * const anyofs[] = {
@@ -14332,7 +14328,7 @@ regnode *
 Perl_regnext(pTHX_ register regnode *p)
 {
     dVAR;
-    register I32 offset;
+    I32 offset;
 
     if (!p)
        return(NULL);
@@ -14491,8 +14487,8 @@ S_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
            SV* sv, I32 indent, U32 depth)
 {
     dVAR;
-    register U8 op = PSEUDO;   /* Arbitrary non-END op. */
-    register const regnode *next;
+    U8 op = PSEUDO;    /* Arbitrary non-END op. */
+    const regnode *next;
     const regnode *optstart= NULL;
     
     RXi_GET_DECL(r,ri);
@@ -14543,9 +14539,9 @@ S_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
        if (PL_regkind[(U8)op] == BRANCHJ) {
            assert(next);
            {
-                register const regnode *nnode = (OP(next) == LONGJMP
-                                            ? regnext((regnode *)next)
-                                            : next);
+                const regnode *nnode = (OP(next) == LONGJMP
+                                       ? regnext((regnode *)next)
+                                       : next);
                 if (last && nnode > last)
                     nnode = last;
                 DUMPUNTIL(NEXTOPER(NEXTOPER(node)), nnode);