This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Only test SvTAIL when SvVALID
authorDavid Mitchell <davem@iabyn.com>
Sat, 12 Nov 2016 11:21:43 +0000 (11:21 +0000)
committerDavid Mitchell <davem@iabyn.com>
Sat, 12 Nov 2016 16:15:09 +0000 (16:15 +0000)
Only use the SvTAIL() macro when we've already confirmed that
the SV is SvVALID() - this is in preparation for removing the
SVpbm_TAIL flag in the next commit

dump.c
sv.h
util.c

diff --git a/dump.c b/dump.c
index 5b59500..49a03a5 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -1513,8 +1513,11 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
        if (SvIsUV(sv) && !(flags & SVf_ROK))   sv_catpv(d, "IsUV,");
        break;
     case SVt_PVMG:
-       if (SvTAIL(sv))         sv_catpv(d, "TAIL,");
-       if (SvVALID(sv))        sv_catpv(d, "VALID,");
+       if (SvVALID(sv)) {
+            sv_catpv(d, "VALID,");
+            if (SvTAIL(sv))
+                sv_catpv(d, "TAIL,");
+            }
        goto do_uv;
     case SVt_PVAV:
        break;
diff --git a/sv.h b/sv.h
index c33a9a4..e2cf10e 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -1140,6 +1140,7 @@ object type. Exposed to perl code via Internals::SvREADONLY().
                            assert(SvTYPE(_svtail) != SVt_PVAV);        \
                            assert(SvTYPE(_svtail) != SVt_PVHV);        \
                            assert(!SvSCREAM(_svtail));                 \
+                           assert((SvFLAGS(sv) & SVpbm_VALID));        \
                            (SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID))    \
                                == (SVpbm_TAIL|SVpbm_VALID);            \
                        })
diff --git a/util.c b/util.c
index a69ddad..409d3ec 100644 (file)
--- a/util.c
+++ b/util.c
@@ -825,11 +825,12 @@ Perl_fbm_instr(pTHX_ unsigned char *big, unsigned char *bigend, SV *littlestr, U
     const unsigned char *little = (const unsigned char *)SvPV_const(littlestr,l);
     STRLEN littlelen = l;
     const I32 multiline = flags & FBMrf_MULTILINE;
+    bool tail = SvVALID(littlestr) ? cBOOL(SvTAIL(littlestr)) : FALSE;
 
     PERL_ARGS_ASSERT_FBM_INSTR;
 
     if ((STRLEN)(bigend - big) < littlelen) {
-       if ( SvTAIL(littlestr)
+       if (     tail
             && ((STRLEN)(bigend - big) == littlelen - 1)
             && (littlelen == 1
                 || (*big == *little &&
@@ -843,19 +844,19 @@ Perl_fbm_instr(pTHX_ unsigned char *big, unsigned char *bigend, SV *littlestr, U
        return (char*)big;              /* Cannot be SvTAIL! */
 
     case 1:
-           if (SvTAIL(littlestr) && !multiline) /* Anchor only! */
+           if (tail && !multiline) /* Anchor only! */
                /* [-1] is safe because we know that bigend != big.  */
                return (char *) (bigend - (bigend[-1] == '\n'));
 
            s = (unsigned char *)memchr((void*)big, *little, bigend-big);
             if (s)
                 return (char *)s;
-           if (SvTAIL(littlestr))
+           if (tail)
                return (char *) bigend;
            return NULL;
 
     case 2:
-       if (SvTAIL(littlestr) && !multiline) {
+       if (tail && !multiline) {
             /* a littlestr with SvTAIL must be of the form "X\n" (where X
              * is a single char). It is anchored, and can only match
              * "....X\n"  or  "....X" */
@@ -933,7 +934,7 @@ Perl_fbm_instr(pTHX_ unsigned char *big, unsigned char *bigend, SV *littlestr, U
 
             /* failed to find 2 chars; try anchored match at end without
              * the \n */
-            if (SvTAIL(littlestr) && bigend[0] == little[0])
+            if (tail && bigend[0] == little[0])
                 return (char *)bigend;
             return NULL;
         }
@@ -942,7 +943,7 @@ Perl_fbm_instr(pTHX_ unsigned char *big, unsigned char *bigend, SV *littlestr, U
        break; /* Only lengths 0 1 and 2 have special-case code.  */
     }
 
-    if (SvTAIL(littlestr) && !multiline) {     /* tail anchored? */
+    if (tail && !multiline) {  /* tail anchored? */
        s = bigend - littlelen;
        if (s >= big && bigend[-1] == '\n' && *s == *little
            /* Automatically of length > 2 */
@@ -963,7 +964,7 @@ Perl_fbm_instr(pTHX_ unsigned char *big, unsigned char *bigend, SV *littlestr, U
        char * const b = ninstr((char*)big,(char*)bigend,
                         (char*)little, (char*)little + littlelen);
 
-       if (!b && SvTAIL(littlestr)) {  /* Automatically multiline!  */
+       if (!b && tail) {       /* Automatically multiline!  */
            /* Chop \n from littlestr: */
            s = bigend - littlelen + 1;
            if (*s == *little
@@ -1035,7 +1036,7 @@ Perl_fbm_instr(pTHX_ unsigned char *big, unsigned char *bigend, SV *littlestr, U
        }
       check_end:
        if ( s == bigend
-            && SvTAIL(littlestr)
+            && tail
             && memEQ((char *)(bigend - littlelen),
                      (char *)(oldlittle - littlelen), littlelen) )
            return (char*)bigend - littlelen;