This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Integrate:
[perl5.git] / regexec.c
index 854fe40..b9ebb9f 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -55,7 +55,6 @@
 #  define PERL_NO_GET_CONTEXT
 #endif
 
-/*SUPPRESS 112*/
 /*
  * pregcomp and pregexec -- regsub and regerror are not used in perl
  *
@@ -79,7 +78,7 @@
  ****    Alterations to Henry's code are...
  ****
  ****    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- ****    2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others
+ ****    2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
  ****
  ****    You may distribute under the terms of either the GNU General Public
  ****    License or the Artistic License, as specified in the README file.
 #define HOP3c(pos,off,lim) ((char*)HOP3(pos,off,lim))
 #define HOPMAYBE3c(pos,off,lim) ((char*)HOPMAYBE3(pos,off,lim))
 
-#define LOAD_UTF8_CHARCLASS(a,b) STMT_START { if (!CAT2(PL_utf8_,a)) { ENTER; save_re_context(); (void)CAT2(is_utf8_, a)((const U8*)b); LEAVE; } } STMT_END
+#define LOAD_UTF8_CHARCLASS(class,str) STMT_START { \
+    if (!CAT2(PL_utf8_,class)) { bool ok; ENTER; save_re_context(); ok=CAT2(is_utf8_,class)((U8*)str); assert(ok); LEAVE; } } STMT_END
+#define LOAD_UTF8_CHARCLASS_ALNUM() LOAD_UTF8_CHARCLASS(alnum,"a")
+#define LOAD_UTF8_CHARCLASS_DIGIT() LOAD_UTF8_CHARCLASS(digit,"0")
+#define LOAD_UTF8_CHARCLASS_SPACE() LOAD_UTF8_CHARCLASS(space," ")
+#define LOAD_UTF8_CHARCLASS_MARK()  LOAD_UTF8_CHARCLASS(mark, "\xcd\x86")
 
 /* for use after a quantifier and before an EXACT-like node -- japhy */
 #define JUMPABLE(rn) ( \
@@ -409,8 +413,8 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
     register char *other_last = Nullch;        /* other substr checked before this */
     char *check_at = Nullch;           /* check substr found at this pos */
 #ifdef DEBUGGING
-    char *i_strpos = strpos;
-    SV *dsv = PERL_DEBUG_PAD_ZERO(0);
+    const char * const i_strpos = strpos;
+    SV * const dsv = PERL_DEBUG_PAD_ZERO(0);
 #endif
     RX_MATCH_UTF8_set(prog,do_utf8);
 
@@ -508,6 +512,7 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
                     || ((slen = SvCUR(check)) > 1
                         && memNE(SvPVX_const(check), s, slen)))
                goto report_neq;
+           check_at = s;
            goto success_at_start;
          }
        }
@@ -606,7 +611,8 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
        if (check == (do_utf8 ? prog->float_utf8 : prog->float_substr)) {
          do_other_anchored:
            {
-               char *last = HOP3c(s, -start_shift, strbeg), *last1, *last2;
+               char * const last = HOP3c(s, -start_shift, strbeg);
+               char *last1, *last2;
                char *s1 = s;
                SV* must;
 
@@ -853,9 +859,10 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
           regstclass does not come from lookahead...  */
        /* If regstclass takes bytelength more than 1: If charlength==1, OK.
           This leaves EXACTF only, which is dealt with in find_byclass().  */
-        const U8* str = (U8*)STRING(prog->regstclass);
+        const U8* const str = (U8*)STRING(prog->regstclass);
         const int cl_l = (PL_regkind[(U8)OP(prog->regstclass)] == EXACT
-                   ? CHR_DIST(str+STR_LEN(prog->regstclass), str)
+                         ? CHR_DIST((U8 *)str+STR_LEN(prog->regstclass),
+                                    (U8 *)str)
                    : 1);
        const char * const endpos = (prog->anchored_substr || prog->anchored_utf8 || ml_anch)
                ? HOP3c(s, (prog->minlen ? cl_l : 0), strend)
@@ -1029,14 +1036,15 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, const char *strend, I32
                U8 *sm = (U8 *) m;
                U8 tmpbuf1[UTF8_MAXBYTES_CASE+1];
                U8 tmpbuf2[UTF8_MAXBYTES_CASE+1];
+               const U32 uniflags = ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY;
 
                to_utf8_lower((U8*)m, tmpbuf1, &ulen1);
                to_utf8_upper((U8*)m, tmpbuf2, &ulen2);
 
                c1 = utf8n_to_uvchr(tmpbuf1, UTF8_MAXBYTES_CASE, 
-                                   0, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
+                                   0, uniflags);
                c2 = utf8n_to_uvchr(tmpbuf2, UTF8_MAXBYTES_CASE,
-                                   0, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
+                                   0, uniflags);
                lnc = 0;
                while (sm < ((U8 *) m + ln)) {
                    lnc++;
@@ -1075,14 +1083,13 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, const char *strend, I32
                UV c, f;
                U8 tmpbuf [UTF8_MAXBYTES+1];
                STRLEN len, foldlen;
-               
+               const U32 uniflags = ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY;
                if (c1 == c2) {
                    /* Upper and lower of 1st char are equal -
                     * probably not a "letter". */
                    while (s <= e) {
                        c = utf8n_to_uvchr((U8*)s, UTF8_MAXBYTES, &len,
-                                          ckWARN(WARN_UTF8) ?
-                                          0 : UTF8_ALLOW_ANY);
+                                          uniflags);
                        if ( c == c1
                             && (ln == len ||
                                 ibcmp_utf8(s, (char **)0, 0,  do_utf8,
@@ -1109,8 +1116,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, const char *strend, I32
                else {
                    while (s <= e) {
                      c = utf8n_to_uvchr((U8*)s, UTF8_MAXBYTES, &len,
-                                          ckWARN(WARN_UTF8) ?
-                                          0 : UTF8_ALLOW_ANY);
+                                          uniflags);
 
                        /* Handle some of the three Greek sigmas cases.
                         * Note that not all the possible combinations
@@ -1184,7 +1190,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, const char *strend, I32
                }
                tmp = ((OP(c) == BOUND ?
                        isALNUM_uni(tmp) : isALNUM_LC_uvchr(UNI_TO_NATIVE(tmp))) != 0);
-               LOAD_UTF8_CHARCLASS(alnum,"a");
+               LOAD_UTF8_CHARCLASS_ALNUM();
                while (s + (uskip = UTF8SKIP(s)) <= strend) {
                    if (tmp == !(OP(c) == BOUND ?
                                 swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8) :
@@ -1227,7 +1233,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, const char *strend, I32
                }
                tmp = ((OP(c) == NBOUND ?
                        isALNUM_uni(tmp) : isALNUM_LC_uvchr(UNI_TO_NATIVE(tmp))) != 0);
-               LOAD_UTF8_CHARCLASS(alnum,"a");
+               LOAD_UTF8_CHARCLASS_ALNUM();
                while (s + (uskip = UTF8SKIP(s)) <= strend) {
                    if (tmp == !(OP(c) == NBOUND ?
                                 swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8) :
@@ -1256,7 +1262,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, const char *strend, I32
            break;
        case ALNUM:
            if (do_utf8) {
-               LOAD_UTF8_CHARCLASS(alnum,"a");
+               LOAD_UTF8_CHARCLASS_ALNUM();
                while (s + (uskip = UTF8SKIP(s)) <= strend) {
                    if (swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8)) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1314,7 +1320,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, const char *strend, I32
            break;
        case NALNUM:
            if (do_utf8) {
-               LOAD_UTF8_CHARCLASS(alnum,"a");
+               LOAD_UTF8_CHARCLASS_ALNUM();
                while (s + (uskip = UTF8SKIP(s)) <= strend) {
                    if (!swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8)) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1372,7 +1378,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, const char *strend, I32
            break;
        case SPACE:
            if (do_utf8) {
-               LOAD_UTF8_CHARCLASS(space," ");
+               LOAD_UTF8_CHARCLASS_SPACE();
                while (s + (uskip = UTF8SKIP(s)) <= strend) {
                    if (*s == ' ' || swash_fetch(PL_utf8_space,(U8*)s, do_utf8)) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1430,7 +1436,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, const char *strend, I32
            break;
        case NSPACE:
            if (do_utf8) {
-               LOAD_UTF8_CHARCLASS(space," ");
+               LOAD_UTF8_CHARCLASS_SPACE();
                while (s + (uskip = UTF8SKIP(s)) <= strend) {
                    if (!(*s == ' ' || swash_fetch(PL_utf8_space,(U8*)s, do_utf8))) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1488,7 +1494,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, const char *strend, I32
            break;
        case DIGIT:
            if (do_utf8) {
-               LOAD_UTF8_CHARCLASS(digit,"0");
+               LOAD_UTF8_CHARCLASS_DIGIT();
                while (s + (uskip = UTF8SKIP(s)) <= strend) {
                    if (swash_fetch(PL_utf8_digit,(U8*)s, do_utf8)) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1546,7 +1552,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, const char *strend, I32
            break;
        case NDIGIT:
            if (do_utf8) {
-               LOAD_UTF8_CHARCLASS(digit,"0");
+               LOAD_UTF8_CHARCLASS_DIGIT();
                while (s + (uskip = UTF8SKIP(s)) <= strend) {
                    if (!swash_fetch(PL_utf8_digit,(U8*)s, do_utf8)) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1637,7 +1643,7 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
     SV *dsv0 = PERL_DEBUG_PAD_ZERO(0);
     SV *dsv1 = PERL_DEBUG_PAD_ZERO(1);
 #endif
-    (void)data; /* Currently unused */
+    PERL_UNUSED_ARG(data);
     RX_MATCH_UTF8_set(prog,do_utf8);
 
     PL_regcc = 0;
@@ -1835,7 +1841,6 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
                                   "Did not find anchored character...\n")
                );
     }
-    /*SUPPRESS 560*/
     else if (prog->anchored_substr != Nullsv
              || prog->anchored_utf8 != Nullsv
              || ((prog->float_substr != Nullsv || prog->float_utf8 != Nullsv)
@@ -1935,8 +1940,8 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
        }
        DEBUG_r({
            SV *prop = sv_newmortal();
-           char *s0;
-           char *s1;
+           const char *s0;
+           const char *s1;
            int len0;
            int len1;
 
@@ -1944,7 +1949,7 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
            s0 = UTF ?
              pv_uni_display(dsv0, (U8*)SvPVX_const(prop), SvCUR(prop), 60,
                             UNI_DISPLAY_REGEX) :
-             SvPVX(prop);
+             SvPVX_const(prop);
            len0 = UTF ? SvCUR(dsv0) : SvCUR(prop);
            s1 = UTF ?
              sv_uni_display(dsv1, sv, 60, UNI_DISPLAY_REGEX) : s;
@@ -1980,7 +1985,7 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
            }
            else {
                STRLEN len;
-                const char * const little = SvPV(float_real, len);
+                const char * const little = SvPV_const(float_real, len);
 
                if (SvTAIL(float_real)) {
                    if (memEQ(strend - len + 1, little, len - 1))
@@ -2123,7 +2128,7 @@ S_regtry(pTHX_ regexp *prog, char *startpos)
            SAVEDESTRUCTOR_X(restore_pos, 0);
         }
         if (!PL_reg_curpm) {
-           Newz(22,PL_reg_curpm, 1, PMOP);
+           Newxz(PL_reg_curpm, 1, PMOP);
 #ifdef USE_ITHREADS
             {
                 SV* repointer = newSViv(0);
@@ -2166,7 +2171,7 @@ S_regtry(pTHX_ regexp *prog, char *startpos)
         if(PL_reg_start_tmp)
             Renew(PL_reg_start_tmp, PL_reg_start_tmpl, char*);
         else
-            New(22,PL_reg_start_tmp, PL_reg_start_tmpl, char*);
+            Newx(PL_reg_start_tmp, PL_reg_start_tmpl, char*);
     }
 
     /* XXXX What this code is doing here?!!!  There should be no need
@@ -2311,12 +2316,13 @@ S_regmatch(pTHX_ regnode *prog)
 #if 0
     I32 firstcp = PL_savestack_ix;
 #endif
-    const register bool do_utf8 = PL_reg_match_utf8;
+    register const bool do_utf8 = PL_reg_match_utf8;
 #ifdef DEBUGGING
     SV *dsv0 = PERL_DEBUG_PAD_ZERO(0);
     SV *dsv1 = PERL_DEBUG_PAD_ZERO(1);
     SV *dsv2 = PERL_DEBUG_PAD_ZERO(2);
 #endif
+    U32 uniflags = ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY;
 
 #ifdef DEBUGGING
     PL_regindent++;
@@ -2470,7 +2476,6 @@ S_regmatch(pTHX_ regnode *prog)
            else
                nextchr = UCHARAT(++locinput);
            break;
-
        case EXACT:
            s = STRING(scan);
            ln = STR_LEN(scan);
@@ -2487,8 +2492,7 @@ S_regmatch(pTHX_ regnode *prog)
                             sayNO;
                        if (NATIVE_TO_UNI(*(U8*)s) !=
                            utf8n_to_uvuni((U8*)l, UTF8_MAXBYTES, &ulen,
-                                          ckWARN(WARN_UTF8) ?
-                                          0 : UTF8_ALLOW_ANY))
+                                           uniflags))
                             sayNO;
                        l += ulen;
                        s ++;
@@ -2502,8 +2506,7 @@ S_regmatch(pTHX_ regnode *prog)
                            sayNO;
                        if (NATIVE_TO_UNI(*((U8*)l)) !=
                            utf8n_to_uvuni((U8*)s, UTF8_MAXBYTES, &ulen,
-                                          ckWARN(WARN_UTF8) ?
-                                          0 : UTF8_ALLOW_ANY))
+                                          uniflags))
                            sayNO;
                        s += ulen;
                        l ++;
@@ -2612,7 +2615,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (!nextchr)
                sayNO;
            if (do_utf8) {
-               LOAD_UTF8_CHARCLASS(alnum,"a");
+               LOAD_UTF8_CHARCLASS_ALNUM();
                if (!(OP(scan) == ALNUM
                      ? swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8)
                      : isALNUM_LC_utf8((U8*)locinput)))
@@ -2635,7 +2638,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (!nextchr && locinput >= PL_regeol)
                sayNO;
            if (do_utf8) {
-               LOAD_UTF8_CHARCLASS(alnum,"a");
+               LOAD_UTF8_CHARCLASS_ALNUM();
                if (OP(scan) == NALNUM
                    ? swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8)
                    : isALNUM_LC_utf8((U8*)locinput))
@@ -2664,11 +2667,11 @@ S_regmatch(pTHX_ regnode *prog)
                else {
                    const U8 * const r = reghop3((U8*)locinput, -1, (U8*)PL_bostr);
                
-                   ln = utf8n_to_uvchr(r, UTF8SKIP(r), 0, 0);
+                   ln = utf8n_to_uvchr((U8 *)r, UTF8SKIP(r), 0, 0);
                }
                if (OP(scan) == BOUND || OP(scan) == NBOUND) {
                    ln = isALNUM_uni(ln);
-                   LOAD_UTF8_CHARCLASS(alnum,"a");
+                   LOAD_UTF8_CHARCLASS_ALNUM();
                    n = swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8);
                }
                else {
@@ -2700,7 +2703,7 @@ S_regmatch(pTHX_ regnode *prog)
                sayNO;
            if (do_utf8) {
                if (UTF8_IS_CONTINUED(nextchr)) {
-                   LOAD_UTF8_CHARCLASS(space," ");
+                   LOAD_UTF8_CHARCLASS_SPACE();
                    if (!(OP(scan) == SPACE
                          ? swash_fetch(PL_utf8_space, (U8*)locinput, do_utf8)
                          : isSPACE_LC_utf8((U8*)locinput)))
@@ -2730,7 +2733,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (!nextchr && locinput >= PL_regeol)
                sayNO;
            if (do_utf8) {
-               LOAD_UTF8_CHARCLASS(space," ");
+               LOAD_UTF8_CHARCLASS_SPACE();
                if (OP(scan) == NSPACE
                    ? swash_fetch(PL_utf8_space, (U8*)locinput, do_utf8)
                    : isSPACE_LC_utf8((U8*)locinput))
@@ -2753,7 +2756,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (!nextchr)
                sayNO;
            if (do_utf8) {
-               LOAD_UTF8_CHARCLASS(digit,"0");
+               LOAD_UTF8_CHARCLASS_DIGIT();
                if (!(OP(scan) == DIGIT
                      ? swash_fetch(PL_utf8_digit, (U8*)locinput, do_utf8)
                      : isDIGIT_LC_utf8((U8*)locinput)))
@@ -2776,7 +2779,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (!nextchr && locinput >= PL_regeol)
                sayNO;
            if (do_utf8) {
-               LOAD_UTF8_CHARCLASS(digit,"0");
+               LOAD_UTF8_CHARCLASS_DIGIT();
                if (OP(scan) == NDIGIT
                    ? swash_fetch(PL_utf8_digit, (U8*)locinput, do_utf8)
                    : isDIGIT_LC_utf8((U8*)locinput))
@@ -2796,7 +2799,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (locinput >= PL_regeol)
                sayNO;
            if  (do_utf8) {
-               LOAD_UTF8_CHARCLASS(mark,"~");
+               LOAD_UTF8_CHARCLASS_MARK();
                if (swash_fetch(PL_utf8_mark,(U8*)locinput, do_utf8))
                    sayNO;
                locinput += PL_utf8skip[nextchr];
@@ -3234,7 +3237,7 @@ S_regmatch(pTHX_ regnode *prog)
                    }
                    else {
                        PL_reg_poscache_size = size;
-                       Newz(29, PL_reg_poscache, size, char);
+                       Newxz(PL_reg_poscache, size, char);
                    }
                    DEBUG_r(
                        PerlIO_printf(Perl_debug_log,
@@ -3620,16 +3623,13 @@ S_regmatch(pTHX_ regnode *prog)
                             to_utf8_upper((U8*)s, tmpbuf2, &ulen2);
 
                             c1 = utf8n_to_uvuni(tmpbuf1, UTF8_MAXBYTES, 0,
-                                                ckWARN(WARN_UTF8) ?
-                                                0 : UTF8_ALLOW_ANY);
+                                                uniflags);
                             c2 = utf8n_to_uvuni(tmpbuf2, UTF8_MAXBYTES, 0,
-                                                ckWARN(WARN_UTF8) ?
-                                                0 : UTF8_ALLOW_ANY);
+                                                uniflags);
                        }
                        else {
                            c2 = c1 = utf8n_to_uvchr(s, UTF8_MAXBYTES, 0,
-                                                    ckWARN(WARN_UTF8) ?
-                                                    0 : UTF8_ALLOW_ANY);
+                                                    uniflags);
                        }
                    }
                }
@@ -3690,8 +3690,7 @@ S_regmatch(pTHX_ regnode *prog)
                                while (locinput <= e &&
                                       utf8n_to_uvchr((U8*)locinput,
                                                      UTF8_MAXBYTES, &len,
-                                                     ckWARN(WARN_UTF8) ?
-                                                     0 : UTF8_ALLOW_ANY) != (UV)c1) {
+                                                     uniflags) != (UV)c1) {
                                    locinput += len;
                                    count++;
                                }
@@ -3702,8 +3701,7 @@ S_regmatch(pTHX_ regnode *prog)
                                while (locinput <= e) {
                                    UV c = utf8n_to_uvchr((U8*)locinput,
                                                          UTF8_MAXBYTES, &len,
-                                                         ckWARN(WARN_UTF8) ?
-                                                         0 : UTF8_ALLOW_ANY);
+                                                         uniflags);
                                    if (c == (UV)c1 || c == (UV)c2)
                                        break;
                                    locinput += len;
@@ -3739,8 +3737,7 @@ S_regmatch(pTHX_ regnode *prog)
                        if (do_utf8)
                            c = utf8n_to_uvchr((U8*)PL_reginput,
                                               UTF8_MAXBYTES, 0,
-                                              ckWARN(WARN_UTF8) ?
-                                              0 : UTF8_ALLOW_ANY);
+                                              uniflags);
                        else
                            c = UCHARAT(PL_reginput);
                        /* If it could work, try it. */
@@ -3789,8 +3786,7 @@ S_regmatch(pTHX_ regnode *prog)
                            if (do_utf8)
                                c = utf8n_to_uvchr((U8*)PL_reginput,
                                                   UTF8_MAXBYTES, 0,
-                                                  ckWARN(WARN_UTF8) ?
-                                                  0 : UTF8_ALLOW_ANY);
+                                                  uniflags);
                            else
                                c = UCHARAT(PL_reginput);
                        }
@@ -3812,8 +3808,7 @@ S_regmatch(pTHX_ regnode *prog)
                            if (do_utf8)
                                c = utf8n_to_uvchr((U8*)PL_reginput,
                                                   UTF8_MAXBYTES, 0,
-                                                  ckWARN(WARN_UTF8) ?
-                                                  0 : UTF8_ALLOW_ANY);
+                                                  uniflags);
                            else
                                c = UCHARAT(PL_reginput);
                        }
@@ -4006,7 +4001,6 @@ do_no:
                goto do_no;
            }
            /* Have more choice yet.  Reuse the same uwb.  */
-           /*SUPPRESS 560*/
            if ((n = (uwb->type == RE_UNWIND_BRANCH
                      ? NEXT_OFF(next) : ARG(next))))
                next += n;
@@ -4119,7 +4113,7 @@ S_regrepeat(pTHX_ const regnode *p, I32 max)
     case ALNUM:
        if (do_utf8) {
            loceol = PL_regeol;
-           LOAD_UTF8_CHARCLASS(alnum,"a");
+           LOAD_UTF8_CHARCLASS_ALNUM();
            while (hardcount < max && scan < loceol &&
                   swash_fetch(PL_utf8_alnum, (U8*)scan, do_utf8)) {
                scan += UTF8SKIP(scan);
@@ -4147,7 +4141,7 @@ S_regrepeat(pTHX_ const regnode *p, I32 max)
     case NALNUM:
        if (do_utf8) {
            loceol = PL_regeol;
-           LOAD_UTF8_CHARCLASS(alnum,"a");
+           LOAD_UTF8_CHARCLASS_ALNUM();
            while (hardcount < max && scan < loceol &&
                   !swash_fetch(PL_utf8_alnum, (U8*)scan, do_utf8)) {
                scan += UTF8SKIP(scan);
@@ -4175,7 +4169,7 @@ S_regrepeat(pTHX_ const regnode *p, I32 max)
     case SPACE:
        if (do_utf8) {
            loceol = PL_regeol;
-           LOAD_UTF8_CHARCLASS(space," ");
+           LOAD_UTF8_CHARCLASS_SPACE();
            while (hardcount < max && scan < loceol &&
                   (*scan == ' ' ||
                    swash_fetch(PL_utf8_space,(U8*)scan, do_utf8))) {
@@ -4204,7 +4198,7 @@ S_regrepeat(pTHX_ const regnode *p, I32 max)
     case NSPACE:
        if (do_utf8) {
            loceol = PL_regeol;
-           LOAD_UTF8_CHARCLASS(space," ");
+           LOAD_UTF8_CHARCLASS_SPACE();
            while (hardcount < max && scan < loceol &&
                   !(*scan == ' ' ||
                     swash_fetch(PL_utf8_space,(U8*)scan, do_utf8))) {
@@ -4233,7 +4227,7 @@ S_regrepeat(pTHX_ const regnode *p, I32 max)
     case DIGIT:
        if (do_utf8) {
            loceol = PL_regeol;
-           LOAD_UTF8_CHARCLASS(digit,"0");
+           LOAD_UTF8_CHARCLASS_DIGIT();
            while (hardcount < max && scan < loceol &&
                   swash_fetch(PL_utf8_digit, (U8*)scan, do_utf8)) {
                scan += UTF8SKIP(scan);
@@ -4247,7 +4241,7 @@ S_regrepeat(pTHX_ const regnode *p, I32 max)
     case NDIGIT:
        if (do_utf8) {
            loceol = PL_regeol;
-           LOAD_UTF8_CHARCLASS(digit,"0");
+           LOAD_UTF8_CHARCLASS_DIGIT();
            while (hardcount < max && scan < loceol &&
                   !swash_fetch(PL_utf8_digit, (U8*)scan, do_utf8)) {
                scan += UTF8SKIP(scan);
@@ -4272,7 +4266,7 @@ S_regrepeat(pTHX_ const regnode *p, I32 max)
        {
                SV *prop = sv_newmortal();
 
-               regprop(prop, p);
+               regprop(prop, (regnode *)p);
                PerlIO_printf(Perl_debug_log,
                              "%*s  %s can match %"IVdf" times out of %"IVdf"...\n",
                              REPORT_CODE_OFF+1, "", SvPVX_const(prop),(IV)c,(IV)max);
@@ -4348,16 +4342,16 @@ Perl_regclass_swash(pTHX_ register regnode* node, bool doinit, SV** listsvp, SV
        const U32 n = ARG(node);
 
        if (PL_regdata->what[n] == 's') {
-           SV *rv = (SV*)PL_regdata->data[n];
-           AV *av = (AV*)SvRV((SV*)rv);
-           SV **ary = AvARRAY(av);
+           SV * const rv = (SV*)PL_regdata->data[n];
+           AV * const av = (AV*)SvRV((SV*)rv);
+           SV **const ary = AvARRAY(av);
            SV **a, **b;
        
            /* See the end of regcomp.c:S_reglass() for
             * documentation of these array elements. */
 
            si = *ary;
-           a  = SvTYPE(ary[1]) == SVt_RV   ? &ary[1] : 0;
+           a  = SvROK(ary[1]) ? &ary[1] : 0;
            b  = SvTYPE(ary[2]) == SVt_PVAV ? &ary[2] : 0;
 
            if (a)
@@ -4398,9 +4392,13 @@ S_reginclass(pTHX_ register const regnode *n, register const U8* p, STRLEN* lenp
     STRLEN len = 0;
     STRLEN plen;
 
-    if (do_utf8 && !UTF8_IS_INVARIANT(c))
-        c = utf8n_to_uvchr(p, UTF8_MAXBYTES, &len,
-                           ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
+    if (do_utf8 && !UTF8_IS_INVARIANT(c)) {
+       c = utf8n_to_uvchr((U8 *)p, UTF8_MAXBYTES, &len,
+                           ckWARN(WARN_UTF8) ? UTF8_CHECK_ONLY :
+                                       UTF8_ALLOW_ANYUV|UTF8_CHECK_ONLY);
+       if (len == (STRLEN)-1)
+           Perl_croak(aTHX_ "Malformed UTF-8 character (fatal)");
+    }
 
     plen = lenp ? *lenp : UNISKIP(NATIVE_TO_UNI(c));
     if (do_utf8 || (flags & ANYOF_UNICODE)) {
@@ -4414,19 +4412,18 @@ S_reginclass(pTHX_ register const regnode *n, register const U8* p, STRLEN* lenp
            match = TRUE;
        if (!match) {
            AV *av;
-           SV *sw = regclass_swash(n, TRUE, 0, (SV**)&av);
+           SV * const sw = regclass_swash((regnode *)n, TRUE, 0, (SV**)&av);
        
            if (sw) {
-               if (swash_fetch(sw, p, do_utf8))
+               if (swash_fetch(sw, (U8 *)p, do_utf8))
                    match = TRUE;
                else if (flags & ANYOF_FOLD) {
                    if (!match && lenp && av) {
                        I32 i;
-                     
                        for (i = 0; i <= av_len(av); i++) {
-                           SV* sv = *av_fetch(av, i, FALSE);
+                           SV* const sv = *av_fetch(av, i, FALSE);
                            STRLEN len;
-                           const char *s = SvPV(sv, len);
+                           const char * const s = SvPV_const(sv, len);
                        
                            if (len <= plen && memEQ(s, (char*)p, len)) {
                                *lenp = len;
@@ -4439,7 +4436,7 @@ S_reginclass(pTHX_ register const regnode *n, register const U8* p, STRLEN* lenp
                        U8 tmpbuf[UTF8_MAXBYTES_CASE+1];
                        STRLEN tmplen;
 
-                       to_utf8_fold(p, tmpbuf, &tmplen);
+                       to_utf8_fold((U8 *)p, tmpbuf, &tmplen);
                        if (swash_fetch(sw, tmpbuf, do_utf8))
                            match = TRUE;
                    }
@@ -4577,7 +4574,7 @@ S_reghopmaybe3(pTHX_ U8* s, I32 off, U8* lim)
 static void
 restore_pos(pTHX_ void *arg)
 {
-    (void)arg; /* unused */
+    PERL_UNUSED_ARG(arg);
     if (PL_reg_eval_set) {
        if (PL_reg_oldsaved) {
            PL_reg_re->subbeg = PL_reg_oldsaved;
@@ -4593,8 +4590,8 @@ restore_pos(pTHX_ void *arg)
 STATIC void
 S_to_utf8_substr(pTHX_ register regexp *prog)
 {
-    SV* sv;
     if (prog->float_substr && !prog->float_utf8) {
+       SV* sv;
        prog->float_utf8 = sv = newSVsv(prog->float_substr);
        sv_utf8_upgrade(sv);
        if (SvTAIL(prog->float_substr))
@@ -4603,6 +4600,7 @@ S_to_utf8_substr(pTHX_ register regexp *prog)
            prog->check_utf8 = sv;
     }
     if (prog->anchored_substr && !prog->anchored_utf8) {
+       SV* sv;
        prog->anchored_utf8 = sv = newSVsv(prog->anchored_substr);
        sv_utf8_upgrade(sv);
        if (SvTAIL(prog->anchored_substr))
@@ -4615,8 +4613,8 @@ S_to_utf8_substr(pTHX_ register regexp *prog)
 STATIC void
 S_to_byte_substr(pTHX_ register regexp *prog)
 {
-    SV* sv;
     if (prog->float_utf8 && !prog->float_substr) {
+       SV* sv;
        prog->float_substr = sv = newSVsv(prog->float_utf8);
        if (sv_utf8_downgrade(sv, TRUE)) {
            if (SvTAIL(prog->float_utf8))
@@ -4629,6 +4627,7 @@ S_to_byte_substr(pTHX_ register regexp *prog)
            prog->check_substr = sv;
     }
     if (prog->anchored_utf8 && !prog->anchored_substr) {
+       SV* sv;
        prog->anchored_substr = sv = newSVsv(prog->anchored_utf8);
        if (sv_utf8_downgrade(sv, TRUE)) {
            if (SvTAIL(prog->anchored_utf8))