This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Integrate:
[perl5.git] / regexec.c
index 0401dd3..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) ( \
@@ -363,7 +367,7 @@ S_cache_re(pTHX_ regexp *prog)
 
 /* Assumptions: if ANCH_GPOS, then strpos is anchored. XXXX Check GPOS logic */
 
-/* If SCREAM, then SvPVX(sv) should be compatible with strpos and strend.
+/* If SCREAM, then SvPVX_const(sv) should be compatible with strpos and strend.
    Otherwise, only SvCUR(sv) is used to get strbeg. */
 
 /* XXXX We assume that strpos is strbeg unless sv. */
@@ -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);
 
@@ -474,7 +478,7 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
        if (!ml_anch) {
          if ( !(prog->reganch & (ROPT_ANCH_GPOS /* Checked by the caller */
                                  | ROPT_IMPLICIT)) /* not a real BOL */
-              /* SvCUR is not set on references: SvRV and SvPVX overlap */
+              /* SvCUR is not set on references: SvRV and SvPVX_const overlap */
               && sv && !SvROK(sv)
               && (strpos != strbeg)) {
              DEBUG_r(PerlIO_printf(Perl_debug_log, "Not at start...\n"));
@@ -496,18 +500,19 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
                }
                /* Now should match s[0..slen-2] */
                slen--;
-               if (slen && (*SvPVX(check) != *s
+               if (slen && (*SvPVX_const(check) != *s
                             || (slen > 1
-                                && memNE(SvPVX(check), s, slen)))) {
+                                && memNE(SvPVX_const(check), s, slen)))) {
                  report_neq:
                    DEBUG_r(PerlIO_printf(Perl_debug_log, "String not equal...\n"));
                    goto fail_finish;
                }
            }
-           else if (*SvPVX(check) != *s
+           else if (*SvPVX_const(check) != *s
                     || ((slen = SvCUR(check)) > 1
-                        && memNE(SvPVX(check), s, slen)))
+                        && memNE(SvPVX_const(check), s, slen)))
                goto report_neq;
+           check_at = s;
            goto success_at_start;
          }
        }
@@ -556,7 +561,7 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
            goto fail_finish;
        /* we may be pointing at the wrong string */
        if (s && RX_MATCH_COPIED(prog))
-           s = strbeg + (s - SvPVX(sv));
+           s = strbeg + (s - SvPVX_const(sv));
        if (data)
            *data->scream_olds = s;
     }
@@ -578,7 +583,7 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
                          (check == (do_utf8 ? prog->anchored_utf8 : prog->anchored_substr) ? "anchored" : "floating"),
                          PL_colors[0],
                          (int)(SvCUR(check) - (SvTAIL(check)!=0)),
-                         SvPVX(check),
+                         SvPVX_const(check),
                          PL_colors[1], (SvTAIL(check) ? "$" : ""),
                          (s ? " at offset " : "...\n") ) );
 
@@ -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;
 
@@ -645,7 +651,7 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
                        PL_colors[0],
                          (int)(SvCUR(must)
                          - (SvTAIL(must)!=0)),
-                         SvPVX(must),
+                         SvPVX_const(must),
                          PL_colors[1], (SvTAIL(must) ? "$" : "")));
                if (!s) {
                    if (last1 >= last2) {
@@ -704,7 +710,7 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
                    (s ? "Found" : "Contradicts"),
                    PL_colors[0],
                      (int)(SvCUR(must) - (SvTAIL(must)!=0)),
-                     SvPVX(must),
+                     SvPVX_const(must),
                      PL_colors[1], (SvTAIL(must) ? "$" : "")));
            if (!s) {
                if (last1 == last) {
@@ -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;
@@ -1804,7 +1810,7 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
 #endif
        if (!(do_utf8 ? prog->anchored_utf8 : prog->anchored_substr))
            do_utf8 ? to_utf8_substr(prog) : to_byte_substr(prog);
-       ch = SvPVX(do_utf8 ? prog->anchored_utf8 : prog->anchored_substr)[0];
+       ch = SvPVX_const(do_utf8 ? prog->anchored_utf8 : prog->anchored_substr)[0];
 
        if (do_utf8) {
            while (s < strend) {
@@ -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)
@@ -1887,7 +1892,7 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
                                  PL_multiline ? FBMrf_MULTILINE : 0))) ) {
            /* we may be pointing at the wrong string */
            if ((flags & REXEC_SCREAM) && RX_MATCH_COPIED(prog))
-               s = strbeg + (s - SvPVX(sv));
+               s = strbeg + (s - SvPVX_const(sv));
            DEBUG_r( did_match = 1 );
            if (HOPc(s, -back_max) > last1) {
                last1 = HOPc(s, -back_min);
@@ -1921,7 +1926,7 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
                               ? "anchored" : "floating"),
                              PL_colors[0],
                              (int)(SvCUR(must) - (SvTAIL(must)!=0)),
-                             SvPVX(must),
+                             SvPVX_const(must),
                                   PL_colors[1], (SvTAIL(must) ? "$" : ""))
                );
        goto phooey;
@@ -1935,16 +1940,16 @@ 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;
 
            regprop(prop, c);
            s0 = UTF ?
-             pv_uni_display(dsv0, (U8*)SvPVX(prop), SvCUR(prop), 60,
+             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;
@@ -1976,11 +1981,11 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
                    last = scream_olds; /* Only one occurrence. */
                /* we may be pointing at the wrong string */
                else if (RX_MATCH_COPIED(prog))
-                   s = strbeg + (s - SvPVX(sv));
+                   s = strbeg + (s - SvPVX_const(sv));
            }
            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++;
@@ -2388,7 +2394,7 @@ S_regmatch(pTHX_ regnode *prog)
                            15 - l - pref_len + 1,
                            "",
                            (IV)(scan - PL_regprogram), PL_regindent*2, "",
-                           SvPVX(prop));
+                           SvPVX_const(prop));
            }
        });
 
@@ -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];
@@ -2931,7 +2934,7 @@ S_regmatch(pTHX_ regnode *prog)
                    }
                    else {
                        STRLEN len;
-                       char *t = SvPV(ret, len);
+                       const char *t = SvPV_const(ret, len);
                        PMOP pm;
                        char * const oprecomp = PL_regprecomp;
                        const I32 osize = PL_regsize;
@@ -2939,7 +2942,7 @@ S_regmatch(pTHX_ regnode *prog)
 
                        Zero(&pm, 1, PMOP);
                         if (DO_UTF8(ret)) pm.op_pmdynflags |= PMdf_DYN_UTF8;
-                       re = CALLREGCOMP(aTHX_ t, t + len, &pm);
+                       re = CALLREGCOMP(aTHX_ (char*)t, (char*)t + len, &pm);
                        if (!(SvFLAGS(ret)
                              & (SVs_TEMP | SVs_PADTMP | SVf_READONLY
                                | SVs_GMG)))
@@ -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,10 +4266,10 @@ 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(prop),(IV)c,(IV)max);
+                             REPORT_CODE_OFF+1, "", SvPVX_const(prop),(IV)c,(IV)max);
        });
 
     return(c);
@@ -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))