This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add ANYOFM regnode
[perl5.git] / op.c
diff --git a/op.c b/op.c
index 4ea83d1..373822a 100644 (file)
--- a/op.c
+++ b/op.c
@@ -4081,7 +4081,10 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags)
     case OP_RV2HV:
        if (type == OP_REFGEN && o->op_flags & OPf_PARENS) {
            PL_modcount = RETURN_UNLIMITED_NUMBER;
-           return o;           /* Treat \(@foo) like ordinary list. */
+           /* Treat \(@foo) like ordinary list, but still mark it as modi-
+              fiable since some contexts need to know.  */
+           o->op_flags |= OPf_MOD;
+           return o;
        }
        /* FALLTHROUGH */
     case OP_RV2GV:
@@ -4146,7 +4149,12 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags)
     case OP_PADHV:
        PL_modcount = RETURN_UNLIMITED_NUMBER;
        if (type == OP_REFGEN && o->op_flags & OPf_PARENS)
-           return o;           /* Treat \(@foo) like ordinary list. */
+       {
+           /* Treat \(@foo) like ordinary list, but still mark it as modi-
+              fiable since some contexts need to know.  */
+           o->op_flags |= OPf_MOD;
+           return o;
+       }
        if (scalar_mod_type(o, type))
            goto nomod;
        if ((o->op_flags & OPf_WANT) != OPf_WANT_SCALAR
@@ -6340,15 +6348,14 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
     STRLEN rlen;
     const U8 *t = (U8*)SvPV_const(tstr, tlen);
     const U8 *r = (U8*)SvPV_const(rstr, rlen);
-    I32 i;
-    I32 j;
-    I32 grows = 0;
+    Size_t i, j;
+    bool grows = FALSE;
     OPtrans_map *tbl;
     SSize_t struct_size; /* malloced size of table struct */
 
     const bool complement = cBOOL(o->op_private & OPpTRANS_COMPLEMENT);
-    const I32 squash     = o->op_private & OPpTRANS_SQUASH;
-    I32 del              = o->op_private & OPpTRANS_DELETE;
+    const bool squash     = cBOOL(o->op_private & OPpTRANS_SQUASH);
+    const bool del        = cBOOL(o->op_private & OPpTRANS_DELETE);
     SV* swash;
 
     PERL_ARGS_ASSERT_PMTRANS;
@@ -6573,7 +6580,7 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
 
        none = ++max;
        if (del)
-           del = ++max;
+           ++max;
 
        if (max > 0xffff)
            bits = 32;
@@ -6641,17 +6648,17 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
     cPVOPo->op_pv = (char*)tbl;
 
     if (complement) {
-        SSize_t excess;
+        Size_t excess;
 
         /* in this branch, j is a count of 'consumed' (i.e. paired off
          * with a search char) replacement chars (so j <= rlen always)
          */
-       for (i = 0; i < (I32)tlen; i++)
+       for (i = 0; i < tlen; i++)
            tbl->map[t[i]] = -1;
 
        for (i = 0, j = 0; i < 256; i++) {
            if (!tbl->map[i]) {
-               if (j == (I32)rlen) {
+               if (j == rlen) {
                    if (del)
                        tbl->map[i] = -2;
                    else if (rlen)
@@ -6660,15 +6667,18 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
                        tbl->map[i] = (short)i;
                }
                else {
-                   if (UVCHR_IS_INVARIANT(i) && ! UVCHR_IS_INVARIANT(r[j]))
-                       grows = 1;
                    tbl->map[i] = r[j++];
                }
+                if (   tbl->map[i] >= 0
+                    &&  UVCHR_IS_INVARIANT((UV)i)
+                    && !UVCHR_IS_INVARIANT((UV)(tbl->map[i]))
+                )
+                    grows = TRUE;
            }
        }
 
-        assert(j <= (I32)rlen);
-        excess = rlen - (SSize_t)j;
+        ASSUME(j <= rlen);
+        excess = rlen - j;
 
         if (excess) {
             /* More replacement chars than search chars:
@@ -6681,7 +6691,7 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
             tbl->size += excess;
             cPVOPo->op_pv = (char*)tbl;
 
-            for (i = 0; i < (I32)excess; i++)
+            for (i = 0; i < excess; i++)
                 tbl->map[i + 256] = r[j+i];
         }
         else {
@@ -6704,8 +6714,8 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
 
        for (i = 0; i < 256; i++)
            tbl->map[i] = -1;
-       for (i = 0, j = 0; i < (I32)tlen; i++,j++) {
-           if (j >= (I32)rlen) {
+       for (i = 0, j = 0; i < tlen; i++,j++) {
+           if (j >= rlen) {
                if (del) {
                    if (tbl->map[t[i]] == -1)
                        tbl->map[t[i]] = -2;
@@ -6716,7 +6726,7 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
            if (tbl->map[t[i]] == -1) {
                 if (     UVCHR_IS_INVARIANT(t[i])
                     && ! UVCHR_IS_INVARIANT(r[j]))
-                   grows = 1;
+                   grows = TRUE;
                tbl->map[t[i]] = r[j];
            }
        }