After running into this issue with another module, I did a grep.cpan.me and found that you too are still accessing the struct field op_sibling by name. This means that this module will not build against any perl built with -DPERL_OP_PARENT, which is currently the default in blead, and will likely be the default for 5.26.0.
The attached patches use the new macro, OpSIBLING, wherever necessary, and uses the new setter macro - Op_MORESIB_set - whereever OpSIBLING would have been used as an lvalue. The patches also provide those macros when needed, which they are in older perls. Your alternative is to use ppport.h from a recent (>3.33) version of Devel::PPPort.
These patches allow Data::Alias to build on my machine, which is an improvement, but all tests still fail due to [cpan #112289].
From 5d2c175e9ca83ec184f26ea60a00164cbbd3a4fc Mon Sep 17 00:00:00 2001
From: Dan Collins <dcollinsn@gmail.com>
Date: Tue, 7 Jun 2016 13:54:07 -0400
Subject: [PATCH 4/6] [cpan #114544] Conditionally provide OpMORESIB_set
Because the OpMORESIB_set macro may not be available in old perls,
we should also define it ourselves, using the non-PERL_OP_PARENT
version of the macro (as the macro will always be provided under
PERL_OP_PARENT).
---
Alias.xs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Alias.xs b/Alias.xs
index f5bdb5e..24dcc0e 100644
--- a/Alias.xs
+++ b/Alias.xs
@@ -251,6 +251,12 @@ STATIC OP *(*da_old_ck_helem)(pTHX_ OP *op);
#ifndef OpSIBLING
#define OpSIBLING(o) (0 + (o)->op_sibling)
#endif
+/* Likewise, while old perls allow using OpSIBLING(o) as an lvalue, new
+ perls need a setter macro. If we're going to use a setter for new perls,
+ we need to provide it in case old perls don't have it. */
+#ifndef OpMORESIB_set
+#define OpMORESIB_set(o, sib) ((o)->op_moresib = 1, (o)->op_sibling = (sib))
+#endif
#ifdef USE_ITHREADS
--
2.8.1
From 4112d5043d79450abdd51547a2b2245227b6be13 Mon Sep 17 00:00:00 2001
From: Dan Collins <dcollinsn@gmail.com>
Date: Tue, 7 Jun 2016 15:33:43 -0400
Subject: [PATCH 2/6] [cpan #114544] Replace lvalue OpSIBLING() with
OpMORESIB_set
Because the new OpSIBLING macro cannot be used as an lvalue, we need
to use the setter macro from op.h.
---
Alias.xs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Alias.xs b/Alias.xs
index 383767e..6fa8aa5 100644
--- a/Alias.xs
+++ b/Alias.xs
@@ -1831,7 +1831,7 @@ STATIC void da_peep2(pTHX_ OP *o) {
if (!(sib = cUNOPx(fk)->op_first) || sib->op_ppaddr != da_tag_rv2cv) {
Perl_warn(aTHX_ "da peep weirdness 1");
} else {
- OpSIBLING(k) = sib;
+ OpMORESIB_set(k, sib);
cLISTOPo->op_last = sib;
if (!(k = sib->op_next) || k->op_ppaddr != da_tag_entersub) {
Perl_warn(aTHX_ "da peep weirdness 2");
@@ -2050,7 +2050,7 @@ STATIC OP *da_ck_entersub(pTHX_ OP *o) {
kUNOP->op_first = last;
while (OpSIBLING(kid) != last)
kid = OpSIBLING(kid);
- OpSIBLING(kid) = Nullop;
+ OpMORESIB_set(kid, Nullop);
cLISTOPx(cUNOPo->op_first)->op_last = kid;
if (kid->op_type == OP_NULL && inside)
kid->op_flags &= ~OPf_SPECIAL;
--
2.8.1
From be57b2ca162cfbd60148bee2cf277c3749de1a46 Mon Sep 17 00:00:00 2001
From: Dan Collins <dcollinsn@gmail.com>
Date: Tue, 7 Jun 2016 13:44:43 -0400
Subject: [PATCH 3/6] [cpan #114544] Conditionally provide OpSIBLING
We also need to provide OpSIBLING, since it is not available on older
perls. This is either an integral part of the patch, if you intend
to push it immediately to begin passing on blead, or a temporary fix,
if you intend to use ppport.h from Devel::PPPort 3.33 or later,
which provides exactly this.
---
Alias.xs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Alias.xs b/Alias.xs
index 6fa8aa5..f5bdb5e 100644
--- a/Alias.xs
+++ b/Alias.xs
@@ -244,6 +244,14 @@ STATIC OP *(*da_old_ck_aelem)(pTHX_ OP *op);
STATIC OP *(*da_old_ck_helem)(pTHX_ OP *op);
#endif
+/* op->op_sibling is deprecated on new perls, but the OpSIBLING macro doesn't
+ exist on older perls. We don't need to check for PERL_OP_PARENT here
+ because if PERL_OP_PARENT was set, and we needed to check op_moresib,
+ we would already have this macro. */
+#ifndef OpSIBLING
+#define OpSIBLING(o) (0 + (o)->op_sibling)
+#endif
+
#ifdef USE_ITHREADS
#define DA_GLOBAL_KEY "Data::Alias::_global"
--
2.8.1
From f63cca29f525f90002fa3a54e69b26a10879d3bb Mon Sep 17 00:00:00 2001
From: Dan Collins <dcollinsn@gmail.com>
Date: Tue, 7 Jun 2016 13:44:20 -0400
Subject: [PATCH 1/6] [cpan #114544] Replace usage of op_sibling with
OpSIBLING()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The Perl core, since 586d4abb8, has had a build mode called
PERL_OP_PARENT, which causes the last sibling in a sibling chain to use
op_sibling to point to the parent, rather than being null. Under this
build mode, op_sibling is now called op_sibparent. This causes errors
of the type:
error: âOP {aka const struct op}â has no member named âop_siblingâ; did
you mean âop_sibparentâ?
The name of the field was changed to force programs using op_sibling to
revisit their code in light of this change - now, the last sibling in
a chain will have a non-NULL op_sibparent, and the caller must use
op_moresib to know whether the pointer is to another sibling or to
the parent.
This breakage is now visible in bleadperl, since PERL_OP_PARENT was
made default, and will be default in 5.26.0.
op.h provides a macro, OpSIBLING(o), which behaves correctly, checking
op->moresib under PERL_OP_PARENT, and returning either op_sibparent or
NULL. This patch replaces op_sibling with use that macro.
---
Alias.xs | 58 +++++++++++++++++++++++++++++-----------------------------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/Alias.xs b/Alias.xs
index a1f7868..383767e 100644
--- a/Alias.xs
+++ b/Alias.xs
@@ -1548,20 +1548,20 @@ STATIC void da_lvalue(pTHX_ OP *op, int list) {
op = (op->op_flags & OPf_KIDS) ? cUNOPx(op)->op_first : NULL;
while (op) {
da_lvalue(aTHX_ op, list);
- op = op->op_sibling;
+ op = OpSIBLING(op);
}
break;
case OP_COND_EXPR:
op = cUNOPx(op)->op_first;
- while ((op = op->op_sibling))
+ while ((op = OpSIBLING(op)))
da_lvalue(aTHX_ op, list);
break;
case OP_SCOPE:
case OP_LEAVE:
case OP_LINESEQ:
op = (op->op_flags & OPf_KIDS) ? cUNOPx(op)->op_first : NULL;
- while (op->op_sibling)
- op = op->op_sibling;
+ while (OpSIBLING(op))
+ op = OpSIBLING(op);
da_lvalue(aTHX_ op, list);
break;
case OP_PUSHMARK:
@@ -1602,13 +1602,13 @@ STATIC void da_aassign(OP *op, OP *right) {
int hash = FALSE, pad;
/* make sure it fits the model exactly */
- if (!right || !(left = right->op_sibling) || left->op_sibling)
+ if (!right || !(left = OpSIBLING(right)) || OpSIBLING(left))
return;
if (left->op_type || !(left->op_flags & OPf_KIDS))
return;
if (!(left = cUNOPx(left)->op_first) || !IS_PUSHMARK_OR_PADRANGE(left))
return;
- if (!(la = left->op_sibling) || la->op_sibling)
+ if (!(la = OpSIBLING(left)) || OpSIBLING(la))
return;
if (la->op_flags & OPf_PARENS)
return;
@@ -1634,7 +1634,7 @@ STATIC void da_aassign(OP *op, OP *right) {
right->op_ppaddr = DataAlias_pp_padrange_single;
#endif
}
- if (!(ra = right->op_sibling) || ra->op_sibling)
+ if (!(ra = OpSIBLING(right)) || OpSIBLING(ra))
return;
if (ra->op_flags & OPf_PARENS)
return;
@@ -1741,7 +1741,7 @@ STATIC int da_transform(pTHX_ OP *op, int sib) {
da_lvalue(aTHX_ tmp, TRUE);
else
#endif
- da_lvalue(aTHX_ kid->op_sibling, TRUE);
+ da_lvalue(aTHX_ OpSIBLING(kid), TRUE);
break;
case OP_SASSIGN:
@@ -1749,7 +1749,7 @@ STATIC int da_transform(pTHX_ OP *op, int sib) {
MOD(kid);
ksib = FALSE;
if (!(op->op_private & OPpASSIGN_BACKWARDS))
- da_lvalue(aTHX_ kid->op_sibling, FALSE);
+ da_lvalue(aTHX_ OpSIBLING(kid), FALSE);
break;
case OP_ANDASSIGN:
op->op_ppaddr = DataAlias_pp_andassign;
@@ -1762,39 +1762,39 @@ STATIC int da_transform(pTHX_ OP *op, int sib) {
op->op_ppaddr = DataAlias_pp_dorassign;
#endif
da_lvalue(aTHX_ kid, FALSE);
- kid = kid->op_sibling;
+ kid = OpSIBLING(kid);
break;
case OP_UNSHIFT:
- if (!(tmp = kid->op_sibling)) break; /* array */
- if (!(tmp = tmp->op_sibling)) break; /* first elem */
+ if (!(tmp = OpSIBLING(kid))) break; /* array */
+ if (!(tmp = OpSIBLING(tmp))) break; /* first elem */
op->op_ppaddr = DataAlias_pp_unshift;
goto mod;
case OP_PUSH:
- if (!(tmp = kid->op_sibling)) break; /* array */
- if (!(tmp = tmp->op_sibling)) break; /* first elem */
+ if (!(tmp = OpSIBLING(kid))) break; /* array */
+ if (!(tmp = OpSIBLING(tmp))) break; /* first elem */
op->op_ppaddr = DataAlias_pp_push;
goto mod;
case OP_SPLICE:
- if (!(tmp = kid->op_sibling)) break; /* array */
- if (!(tmp = tmp->op_sibling)) break; /* offset */
- if (!(tmp = tmp->op_sibling)) break; /* length */
- if (!(tmp = tmp->op_sibling)) break; /* first elem */
+ if (!(tmp = OpSIBLING(kid))) break; /* array */
+ if (!(tmp = OpSIBLING(tmp))) break; /* offset */
+ if (!(tmp = OpSIBLING(tmp))) break; /* length */
+ if (!(tmp = OpSIBLING(tmp))) break; /* first elem */
op->op_ppaddr = DataAlias_pp_splice;
goto mod;
case OP_ANONLIST:
- if (!(tmp = kid->op_sibling)) break; /* first elem */
+ if (!(tmp = OpSIBLING(kid))) break; /* first elem */
op->op_ppaddr = DataAlias_pp_anonlist;
goto mod;
case OP_ANONHASH:
- if (!(tmp = kid->op_sibling)) break; /* first elem */
+ if (!(tmp = OpSIBLING(kid))) break; /* first elem */
op->op_ppaddr = DataAlias_pp_anonhash;
- mod: do MOD(tmp); while ((tmp = tmp->op_sibling));
+ mod: do MOD(tmp); while ((tmp = OpSIBLING(tmp)));
}
- if (sib && op->op_sibling) {
+ if (sib && OpSIBLING(op)) {
if (kid)
hits += da_transform(aTHX_ kid, ksib);
- op = op->op_sibling;
+ op = OpSIBLING(op);
} else {
op = kid;
sib = ksib;
@@ -1808,7 +1808,7 @@ STATIC void da_peep2(pTHX_ OP *o) {
OP *sib, *k, *fk;
int useful;
while (o->op_ppaddr != da_tag_list) {
- while ((sib = o->op_sibling)) {
+ while ((sib = OpSIBLING(o))) {
if ((o->op_flags & OPf_KIDS) && (k = cUNOPo->op_first)){
da_peep2(aTHX_ k);
} else switch (o->op_type ? o->op_type : o->op_targ) {
@@ -1826,12 +1826,12 @@ STATIC void da_peep2(pTHX_ OP *o) {
op_null(o);
o->op_ppaddr = PL_ppaddr[OP_NULL];
k = fk = cLISTOPo->op_first;
- while ((sib = k->op_sibling))
+ while ((sib = OpSIBLING(k)))
k = sib;
if (!(sib = cUNOPx(fk)->op_first) || sib->op_ppaddr != da_tag_rv2cv) {
Perl_warn(aTHX_ "da peep weirdness 1");
} else {
- k->op_sibling = sib;
+ OpSIBLING(k) = sib;
cLISTOPo->op_last = sib;
if (!(k = sib->op_next) || k->op_ppaddr != da_tag_entersub) {
Perl_warn(aTHX_ "da peep weirdness 2");
@@ -2048,9 +2048,9 @@ STATIC OP *da_ck_entersub(pTHX_ OP *o) {
kLISTOP->op_first = tmp;
kid = tmp;
kUNOP->op_first = last;
- while (kid->op_sibling != last)
- kid = kid->op_sibling;
- kid->op_sibling = Nullop;
+ while (OpSIBLING(kid) != last)
+ kid = OpSIBLING(kid);
+ OpSIBLING(kid) = Nullop;
cLISTOPx(cUNOPo->op_first)->op_last = kid;
if (kid->op_type == OP_NULL && inside)
kid->op_flags &= ~OPf_SPECIAL;
--
2.8.1