regmatch: fix a || vs | typo in CACHEsayYES and add a test from Hugo.
Dave Mitchell [Tue, 18 Apr 2006 17:03:15 +0000 (17:03 +0000)]
Also defer altering the cache bit until CACHEsayYES/NO is called

p4raw-id: //depot/perl@27893

regexec.c
t/op/re_tests

index 50f164f..53ec117 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -2242,11 +2242,17 @@ typedef union re_unwind_t {
 #define POSCACHE_SUCCESS 0     /* caching success rather than failure */
 #define POSCACHE_SEEN 1                /* we know what we're caching */
 #define POSCACHE_START 2       /* the real cache: this bit maps to pos 0 */
+
 #define CACHEsayYES STMT_START { \
     if (st->u.whilem.cache_offset | st->u.whilem.cache_bit) { \
-       if (!(PL_reg_poscache[0] & (1<<POSCACHE_SEEN))) \
-           PL_reg_poscache[0] |= (1<<POSCACHE_SUCCESS) || (1<<POSCACHE_SEEN); \
-        else if (!(PL_reg_poscache[0] & (1<<POSCACHE_SUCCESS))) { \
+       if (!(PL_reg_poscache[0] & (1<<POSCACHE_SEEN))) { \
+           PL_reg_poscache[0] |= (1<<POSCACHE_SUCCESS) | (1<<POSCACHE_SEEN); \
+           PL_reg_poscache[st->u.whilem.cache_offset] |= (1<<st->u.whilem.cache_bit); \
+       } \
+        else if (PL_reg_poscache[0] & (1<<POSCACHE_SUCCESS)) { \
+           PL_reg_poscache[st->u.whilem.cache_offset] |= (1<<st->u.whilem.cache_bit); \
+       } \
+       else { \
            /* cache records failure, but this is success */ \
            DEBUG_r( \
                PerlIO_printf(Perl_debug_log, \
@@ -2258,11 +2264,17 @@ typedef union re_unwind_t {
     } \
     sayYES; \
 } STMT_END
+
 #define CACHEsayNO STMT_START { \
     if (st->u.whilem.cache_offset | st->u.whilem.cache_bit) { \
-       if (!(PL_reg_poscache[0] & (1<<POSCACHE_SEEN))) \
+       if (!(PL_reg_poscache[0] & (1<<POSCACHE_SEEN))) { \
            PL_reg_poscache[0] |= (1<<POSCACHE_SEEN); \
-        else if ((PL_reg_poscache[0] & (1<<POSCACHE_SUCCESS))) { \
+           PL_reg_poscache[st->u.whilem.cache_offset] |= (1<<st->u.whilem.cache_bit); \
+       } \
+        else if (!(PL_reg_poscache[0] & (1<<POSCACHE_SUCCESS))) { \
+           PL_reg_poscache[st->u.whilem.cache_offset] |= (1<<st->u.whilem.cache_bit); \
+       } \
+       else { \
            /* cache records success, but this is failure */ \
            DEBUG_r( \
                PerlIO_printf(Perl_debug_log, \
@@ -3690,7 +3702,6 @@ S_regmatch(pTHX_ const regmatch_info *reginfo, regnode *prog)
                            /* cache records failure */
                            sayNO_SILENT;
                    }
-                   PL_reg_poscache[st->u.whilem.cache_offset] |= (1<<st->u.whilem.cache_bit);
                }
                }
 
index 4b9ae61..a87f81c 100644 (file)
@@ -961,3 +961,4 @@ x(?#        x       c       -       Sequence (?#... not terminated
 ^(.)\s+.$(?(1))        A B     y       $1      A       # [perl #37688]
 (?:r?)*?r|(.{2,4})     abcde   y       $1      abcd
 (?!)+?|(.{2,4})        abcde   y       $1      abcd
+^(a*?)(?!(a{6}|a{5})*$)        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa y       $+[1]   12      # super-linear cache bug may return 18