Commit 35bf9d5ee5 for perl

commit 35bf9d5ee5498b7385c02397f9c786579d69c526
Author: Yves Orton <demerphq@gmail.com>
Date:   Tue Oct 27 21:36:43 2026 +0100

    regcomp: name CURLY capture properties

    Use separate properties for capture numbers in CURLYM and CURLYN nodes
    and capture floors in CURLYX nodes. The names distinguish these meanings
    of FLAGS in the debugger and executor while preserving the node layout.

diff --git a/regcomp.h b/regcomp.h
index ff4315c1c7..814b27b919 100644
--- a/regcomp.h
+++ b/regcomp.h
@@ -634,6 +634,20 @@ struct regnode_ssc {
     REGNODE_NEXT_OFFSET_SET((p), (val));                                      \
 } STMT_END

+#define CURLY_CAPTURE_PARENS(p)                                               \
+    (assert(OP(p) == CURLYN || OP(p) == CURLYM), PREVENT_LVALUE(FLAGS(p)))
+#define CURLY_CAPTURE_PARENS_SET(p, val) STMT_START {                         \
+    assert(OP(p) == CURLYN || OP(p) == CURLYM);                               \
+    FLAGS(p) = (val);                                                         \
+} STMT_END
+
+#define CURLYX_CAPTURE_FLOOR(p)                                               \
+    (assert(OP(p) == CURLYX), PREVENT_LVALUE(FLAGS(p)))
+#define CURLYX_CAPTURE_FLOOR_SET(p, val) STMT_START {                         \
+    assert(OP(p) == CURLYX);                                                  \
+    FLAGS(p) = (val);                                                         \
+} STMT_END
+
 #define LOGICAL_MODE(p)                                                       \
     (assert(OP(p) == LOGICAL), PREVENT_LVALUE(FLAGS(p) & EVAL_FLAGS_MASK))
 #define LOGICAL_MODE_SET(p, val) STMT_START {                                 \
diff --git a/regcomp_debug.c b/regcomp_debug.c
index 9a36e9bcfd..43bd1a8ae0 100644
--- a/regcomp_debug.c
+++ b/regcomp_debug.c
@@ -635,8 +635,10 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o, const regmatch_
         if (CURLY_HAS_CAPTURES(o))
             sv_catpvf(sv, "<%d:%d>", CURLY_FIRST_CAPTURE(o),
                                    CURLY_LAST_CAPTURE(o));
-        if (op == CURLYM || op == CURLYN || op == CURLYX)
-            sv_catpvf(sv, "[%d]", FLAGS(o)); /* Parenth number */
+        if (op == CURLYM || op == CURLYN)
+            sv_catpvf(sv, "[%d]", CURLY_CAPTURE_PARENS(o));
+        else if (op == CURLYX)
+            sv_catpvf(sv, "[%d]", CURLYX_CAPTURE_FLOOR(o));
         sv_catpvf(sv, "{%u,", (unsigned) lo);
         if (hi == REG_INFTY)
             sv_catpvs(sv, "INFTY");
diff --git a/regcomp_study.c b/regcomp_study.c
index 35e501c71b..d644bb9146 100644
--- a/regcomp_study.c
+++ b/regcomp_study.c
@@ -2549,7 +2549,7 @@ Perl_study_chunk(pTHX_
                 goto optimize_curly_tail;
             case CURLY:
                 if (stopparen > 0 && (OP(scan) == CURLYN || OP(scan) == CURLYM)
-                    && (FLAGS(scan) == stopparen))
+                    && (CURLY_CAPTURE_PARENS(scan) == stopparen))
                 {
                     mincount = 1;
                     maxcount = 1;
@@ -2560,7 +2560,7 @@ Perl_study_chunk(pTHX_
                 next = regnext(scan);
                 if (OP(scan) == CURLYX) {
                     I32 lp = (data ? *(data->last_closep) : 0);
-                    FLAGS(scan) = ((lp <= (I32)U8_MAX) ? (U8)lp : U8_MAX);
+                    CURLYX_CAPTURE_FLOOR_SET(scan, ((lp <= (I32)U8_MAX) ? (U8)lp : U8_MAX));
                 }
                 scan = REGNODE_AFTER(scan);
                 next_is_eval = (OP(scan) == EVAL);
@@ -2725,8 +2725,8 @@ Perl_study_chunk(pTHX_
                         RExC_close_parens[PARNO(nxt1)] = REGNODE_OFFSET(nxt) + 2;
                     }
                     /* Now we know that nxt2 is the only contents: */
-                    FLAGS(oscan) = (U8)PARNO(nxt);
                     OP(oscan) = CURLYN;
+                    CURLY_CAPTURE_PARENS_SET(oscan, (U8)PARNO(nxt));
                     OP(nxt1) = NOTHING; /* was OPEN. */

 #ifdef DEBUGGING
@@ -2783,7 +2783,7 @@ Perl_study_chunk(pTHX_
                         /* note that we have changed the type of oscan to CURLYM here */
                         regnode *nxt1 = REGNODE_AFTER_type(oscan, tregnode_CURLYM); /* OPEN*/

-                        FLAGS(oscan) = (U8)PARNO(nxt);
+                        CURLY_CAPTURE_PARENS_SET(oscan, (U8)PARNO(nxt));
                         if (RExC_open_parens) {
                              /*open->CURLYM*/
                             RExC_open_parens[PARNO(nxt1)] = REGNODE_OFFSET(oscan);
@@ -2822,7 +2822,7 @@ Perl_study_chunk(pTHX_
                                     depth+1, mutate_ok);
                     }
                     else
-                        FLAGS(oscan) = 0;
+                        CURLY_CAPTURE_PARENS_SET(oscan, 0);
                 }
                 else if ((OP(oscan) == CURLYX)
                         /* Possibly mark the corresponding WHILEM node as
diff --git a/regexec.c b/regexec.c
index cd352ba52e..6fd07baee4 100644
--- a/regexec.c
+++ b/regexec.c
@@ -9585,7 +9585,7 @@ NULL
         case CURLYX:    /* start of /A*B/  (for complex A) */
         {
             /* No need to save/restore up to this paren */
-            I32 parenfloor = FLAGS(scan);
+            I32 parenfloor = CURLYX_CAPTURE_FLOOR(scan);

             assert(next); /* keep Coverity happy */
             if (OP(REGNODE_BEFORE(next)) == NOTHING) /* LONGJMP */
@@ -10015,8 +10015,8 @@ NULL
             ST.lastcloseparen = RXp_LASTCLOSEPAREN(rex);

             /* if paren positive, emulate an OPEN/CLOSE around A */
-            if (FLAGS(ST.me)) {
-                U32 paren = FLAGS(ST.me);
+            if (CURLY_CAPTURE_PARENS(ST.me)) {
+                U32 paren = CURLY_CAPTURE_PARENS(ST.me);
                 lastopen = paren;
                 if (paren > maxopenparen)
                     maxopenparen = paren;
@@ -10063,15 +10063,15 @@ NULL
                           depth, (IV) ST.count, (IV)ST.alen)
             );

-            if (FLAGS(ST.me)) {
+            if (CURLY_CAPTURE_PARENS(ST.me)) {
                 /* emulate CLOSE: mark current A as captured */
-                U32 paren = (U32)FLAGS(ST.me);
+                U32 paren = (U32)CURLY_CAPTURE_PARENS(ST.me);
                 CLOSE_CAPTURE(rex, paren,
                     HOPc(locinput, -ST.alen) - reginfo->strbeg,
                     locinput - reginfo->strbeg);
             }

-            if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)FLAGS(ST.me)))
+            if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)CURLY_CAPTURE_PARENS(ST.me)))
                 goto fake_end;


@@ -10088,7 +10088,7 @@ NULL


             if (ST.minmod || ST.count < CURLY_MIN_REPEAT(ST.me)
-                || EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)FLAGS(ST.me)))
+                || EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)CURLY_CAPTURE_PARENS(ST.me)))
                 sayNO;

           curlym_do_B: /* execute the B in /A{m,n}B/  */
@@ -10137,9 +10137,9 @@ NULL
             }

           curlym_close_B:
-            if (FLAGS(ST.me)) {
+            if (CURLY_CAPTURE_PARENS(ST.me)) {
                 /* emulate CLOSE: mark current A as captured */
-                U32 paren = (U32)FLAGS(ST.me);
+                U32 paren = (U32)CURLY_CAPTURE_PARENS(ST.me);
                 if (ST.count || is_accepted) {
                     CLOSE_CAPTURE(rex, paren,
                         HOPc(locinput, -ST.alen) - reginfo->strbeg,
@@ -10148,7 +10148,7 @@ NULL
                 else
                     RXp_OFFSp(rex)[paren].end = -1;

-                if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)FLAGS(ST.me)))
+                if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)CURLY_CAPTURE_PARENS(ST.me)))
                 {
                     if (ST.count || is_accepted)
                         goto fake_end;
@@ -10211,7 +10211,7 @@ NULL
             goto repeat;

         case CURLYN:		/*  /(A){m,n}B/ where A is width 1 char */
-            ST.paren = FLAGS(scan);     /* Which paren to set */
+            ST.paren = CURLY_CAPTURE_PARENS(scan);     /* Which paren to set */
             ST.lastparen      = RXp_LASTPAREN(rex);
             ST.lastcloseparen = RXp_LASTCLOSEPAREN(rex);
             if (ST.paren > maxopenparen)