This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Promote v5.36 usage and feature bundles doc
[perl5.git] / op.c
diff --git a/op.c b/op.c
index b78d8ce..6e19ef4 100644 (file)
--- a/op.c
+++ b/op.c
@@ -1386,7 +1386,7 @@ S_find_and_forget_pmops(pTHX_ OP *o)
         case OP_SPLIT:
         case OP_MATCH:
         case OP_QR:
-            forget_pmop((PMOP*)o);
+            forget_pmop(cPMOPo);
         }
 
         if (o->op_flags & OPf_KIDS) {
@@ -2287,17 +2287,17 @@ Perl_scalarvoid(pTHX_ OP *arg)
             if ((o->op_private & ~OPpASSIGN_BACKWARDS) != 2)
                 break;
 
-            rv2gv = ((BINOP *)o)->op_last;
+            rv2gv = cBINOPo->op_last;
             if (!rv2gv || rv2gv->op_type != OP_RV2GV)
                 break;
 
-            refgen = (UNOP *)((BINOP *)o)->op_first;
+            refgen = cUNOPx(cBINOPo->op_first);
 
             if (!refgen || (refgen->op_type != OP_REFGEN
                             && refgen->op_type != OP_SREFGEN))
                 break;
 
-            exlist = (LISTOP *)refgen->op_first;
+            exlist = cLISTOPx(refgen->op_first);
             if (!exlist || exlist->op_type != OP_NULL
                 || exlist->op_targ != OP_LIST)
                 break;
@@ -2306,7 +2306,7 @@ Perl_scalarvoid(pTHX_ OP *arg)
                 && exlist->op_first != exlist->op_last)
                 break;
 
-            rv2cv = (UNOP*)exlist->op_last;
+            rv2cv = cUNOPx(exlist->op_last);
 
             if (rv2cv->op_type != OP_RV2CV)
                 break;
@@ -2653,13 +2653,13 @@ Perl_check_hash_fields_and_hekify(pTHX_ UNOP *rop, SVOP *key_op, int real)
     if (rop) {
         if (rop->op_first->op_type == OP_PADSV)
             /* @$hash{qw(keys here)} */
-            rop = (UNOP*)rop->op_first;
+            rop = cUNOPx(rop->op_first);
         else {
             /* @{$hash}{qw(keys here)} */
             if (rop->op_first->op_type == OP_SCOPE
                 && cLISTOPx(rop->op_first)->op_last->op_type == OP_PADSV)
                 {
-                    rop = (UNOP*)cLISTOPx(rop->op_first)->op_last;
+                    rop = cUNOPx(cLISTOPx(rop->op_first)->op_last);
                 }
             else
                 rop = NULL;
@@ -2676,7 +2676,7 @@ Perl_check_hash_fields_and_hekify(pTHX_ UNOP *rop, SVOP *key_op, int real)
          && (fields = (GV**)hv_fetchs(PadnameTYPE(lexname), "FIELDS", FALSE))
          && isGV(*fields) && GvHV(*fields);
 
-    for (; key_op; key_op = (SVOP*)OpSIBLING(key_op)) {
+    for (; key_op; key_op = cSVOPx(OpSIBLING(key_op))) {
         SV **svp, *sv;
         if (key_op->op_type != OP_CONST)
             continue;
@@ -3035,7 +3035,7 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags)
             !(o->op_flags & OPf_STACKED)) {
             OpTYPE_set(o, OP_RV2CV);           /* entersub => rv2cv */
             assert(cUNOPo->op_first->op_type == OP_NULL);
-            op_null(((LISTOP*)cUNOPo->op_first)->op_first);/* disable pushmark */
+            op_null(cLISTOPx(cUNOPo->op_first)->op_first);/* disable pushmark */
             break;
         }
         else {                         /* lvalue subroutine call */
@@ -3627,7 +3627,7 @@ Perl_doref(pTHX_ OP *o, I32 type, bool set_op_ref)
                 OpTYPE_set(o, OP_RV2CV);             /* entersub => rv2cv */
                 assert(cUNOPo->op_first->op_type == OP_NULL);
                 /* disable pushmark */
-                op_null(((LISTOP*)cUNOPo->op_first)->op_first);
+                op_null(cLISTOPx(cUNOPo->op_first)->op_first);
                 o->op_flags |= OPf_SPECIAL;
             }
             else if (type == OP_RV2SV || type == OP_RV2AV || type == OP_RV2HV){
@@ -4110,7 +4110,7 @@ Perl_my_attrs(pTHX_ OP *o, OP *attrs)
         else {
             /* The listop in rops might have a pushmark at the beginning,
                which will mess up list assignment. */
-            LISTOP * const lrops = (LISTOP *)rops; /* for brevity */
+            LISTOP * const lrops = cLISTOPx(rops); /* for brevity */
             if (rops->op_type == OP_LIST &&
                 lrops->op_first && lrops->op_first->op_type == OP_PUSHMARK)
             {
@@ -4373,7 +4373,7 @@ Perl_op_scope(pTHX_ OP *o)
         else if (o->op_type == OP_LINESEQ) {
             OP *kid;
             OpTYPE_set(o, OP_SCOPE);
-            kid = ((LISTOP*)o)->op_first;
+            kid = cLISTOPo->op_first;
             if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) {
                 op_null(kid);
 
@@ -5062,7 +5062,7 @@ S_gen_constant_list(pTHX_ OP *o)
     av = (AV *)SvREFCNT_inc_NN(*PL_stack_sp--);
 
     /* replace subtree with an OP_CONST */
-    curop = ((UNOP*)o)->op_first;
+    curop = cUNOPo->op_first;
     op_sibling_splice(o, NULL, -1, newSVOP(OP_CONST, 0, (SV *)av));
     op_free(curop);
 
@@ -5111,7 +5111,7 @@ Perl_op_append_elem(pTHX_ I32 type, OP *first, OP *last)
         return newLISTOP(type, 0, first, last);
     }
 
-    op_sibling_splice(first, ((LISTOP*)first)->op_last, 0, last);
+    op_sibling_splice(first, cLISTOPx(first)->op_last, 0, last);
     first->op_flags |= OPf_KIDS;
     return first;
 }
@@ -5144,9 +5144,9 @@ Perl_op_append_list(pTHX_ I32 type, OP *first, OP *last)
     if (last->op_type != (unsigned)type)
         return op_append_elem(type, first, last);
 
-    OpMORESIB_set(((LISTOP*)first)->op_last, ((LISTOP*)last)->op_first);
-    ((LISTOP*)first)->op_last = ((LISTOP*)last)->op_last;
-    OpLASTSIB_set(((LISTOP*)first)->op_last, first);
+    OpMORESIB_set(cLISTOPx(first)->op_last, cLISTOPx(last)->op_first);
+    cLISTOPx(first)->op_last = cLISTOPx(last)->op_last;
+    OpLASTSIB_set(cLISTOPx(first)->op_last, first);
     first->op_flags |= (last->op_flags & OPf_KIDS);
 
     S_op_destroy(aTHX_ last);
@@ -5607,7 +5607,7 @@ Perl_newBINOP(pTHX_ I32 type, I32 flags, OP *first, OP *last)
     if (binop->op_last)
         OpLASTSIB_set(binop->op_last, (OP*)binop);
 
-    binop = (BINOP*)CHECKOP(type, binop);
+    binop = (BINOP*) CHECKOP(type, binop);
     if (binop->op_next || binop->op_type != (OPCODE)type)
         return (OP*)binop;
 
@@ -5728,8 +5728,8 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
      * The rhs of the tr/// is here referred to as the r side.
      */
 
-    SV * const tstr = ((SVOP*)expr)->op_sv;
-    SV * const rstr = ((SVOP*)repl)->op_sv;
+    SV * const tstr = cSVOPx(expr)->op_sv;
+    SV * const rstr = cSVOPx(repl)->op_sv;
     STRLEN tlen;
     STRLEN rlen;
     const U8 * t0 = (U8*)SvPV_const(tstr, tlen);
@@ -7061,7 +7061,7 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, UV flags, I32 floor)
     }
 
     PL_hints |= HINT_BLOCK_SCOPE;
-    pm = (PMOP*)o;
+    pm = cPMOPo;
     assert(floor==0 || (pm->op_pmflags & PMf_HAS_CV));
 
     if (is_compiletime) {
@@ -7147,7 +7147,7 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, UV flags, I32 floor)
                  * squirrel away expr in op_code_list without the peephole
                  * optimiser etc processing it for a second time */
                 OP *qr = newPMOP(OP_QR, 0);
-                ((PMOP*)qr)->op_code_list = expr;
+                cPMOPx(qr)->op_code_list = expr;
 
                 /* handle the implicit sub{} wrapped round the qr/(?{..})/ */
                 SvREFCNT_inc_simple_void(PL_compcv);
@@ -7249,7 +7249,7 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, UV flags, I32 floor)
         if (expr->op_type == OP_REGCRESET || expr->op_type == OP_REGCMAYBE) {
             LINKLIST(expr);
             rcop->op_next = expr;
-            ((UNOP*)expr)->op_first->op_next = (OP*)rcop;
+            cUNOPx(expr)->op_first->op_next = (OP*)rcop;
         }
         else {
             rcop->op_next = LINKLIST(expr);
@@ -7335,9 +7335,12 @@ Perl_newSVOP(pTHX_ I32 type, I32 flags, SV *sv)
 
     PERL_ARGS_ASSERT_NEWSVOP;
 
+    /* OP_RUNCV is allowed specially so rpeep has room to convert it into an
+     * OP_CONST */
     assert((PL_opargs[type] & OA_CLASS_MASK) == OA_SVOP
         || (PL_opargs[type] & OA_CLASS_MASK) == OA_PVOP_OR_SVOP
         || (PL_opargs[type] & OA_CLASS_MASK) == OA_FILESTATOP
+        || type == OP_RUNCV
         || type == OP_CUSTOM);
 
     NewOp(1101, svop, 1, SVOP);
@@ -7459,7 +7462,7 @@ Perl_newPVOP(pTHX_ I32 type, I32 flags, char *pv)
     flags &= ~SVf_UTF8;
 
     assert((PL_opargs[type] & OA_CLASS_MASK) == OA_PVOP_OR_SVOP
-        || type == OP_RUNCV || type == OP_CUSTOM
+        || type == OP_CUSTOM
         || (PL_opargs[type] & OA_CLASS_MASK) == OA_LOOPEXOP);
 
     NewOp(1101, pvop, 1, PVOP);
@@ -7553,7 +7556,7 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
     veop = NULL;
 
     if (version) {
-        SV * const vesv = ((SVOP*)version)->op_sv;
+        SV * const vesv = cSVOPx(version)->op_sv;
 
         if (!arg && !SvNIOKp(vesv)) {
             arg = version;
@@ -7566,7 +7569,7 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
                 Perl_croak(aTHX_ "Version number must be a constant number");
 
             /* Make copy of idop so we don't free it twice */
-            pack = newSVOP(OP_CONST, 0, newSVsv(((SVOP*)idop)->op_sv));
+            pack = newSVOP(OP_CONST, 0, newSVsv(cSVOPx(idop)->op_sv));
 
             /* Fake up a method call to VERSION */
             meth = newSVpvs_share("VERSION");
@@ -7581,10 +7584,10 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
     if (arg && arg->op_type == OP_STUB) {
         imop = arg;            /* no import on explicit () */
     }
-    else if (SvNIOKp(((SVOP*)idop)->op_sv)) {
+    else if (SvNIOKp(cSVOPx(idop)->op_sv)) {
         imop = NULL;           /* use 5.0; */
         if (aver)
-            use_version = ((SVOP*)idop)->op_sv;
+            use_version = cSVOPx(idop)->op_sv;
         else
             idop->op_private |= OPpCONST_NOVER;
     }
@@ -7592,7 +7595,7 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
         SV *meth;
 
         /* Make copy of idop so we don't free it twice */
-        pack = newSVOP(OP_CONST, 0, newSVsv(((SVOP*)idop)->op_sv));
+        pack = newSVOP(OP_CONST, 0, newSVsv(cSVOPx(idop)->op_sv));
 
         /* Fake up a method call to import/unimport */
         meth = aver
@@ -8004,7 +8007,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
 
         if (OP_TYPE_IS_OR_WAS(left, OP_LIST))
         {
-            OP *lop = ((LISTOP*)left)->op_first, *vop, *eop;
+            OP *lop = cLISTOPx(left)->op_first, *vop, *eop;
             if (!(left->op_flags & OPf_PARENS) &&
                     lop->op_type == OP_PUSHMARK &&
                     (vop = OpSIBLING(lop)) &&
@@ -8066,18 +8069,18 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
             OP *gvop = NULL;
 
             if (   (  left->op_type == OP_RV2AV
-                   && (gvop=((UNOP*)left)->op_first)->op_type==OP_GV)
+                   && (gvop=cUNOPx(left)->op_first)->op_type==OP_GV)
                 || left->op_type == OP_PADAV)
             {
                 /* @pkg or @lex or local @pkg' or 'my @lex' */
                 OP *tmpop;
                 if (gvop) {
 #ifdef USE_ITHREADS
-                    ((PMOP*)right)->op_pmreplrootu.op_pmtargetoff
+                    cPMOPx(right)->op_pmreplrootu.op_pmtargetoff
                         = cPADOPx(gvop)->op_padix;
                     cPADOPx(gvop)->op_padix = 0;       /* steal it */
 #else
-                    ((PMOP*)right)->op_pmreplrootu.op_pmtargetgv
+                    cPMOPx(right)->op_pmreplrootu.op_pmtargetgv
                         = MUTABLE_GV(cSVOPx(gvop)->op_sv);
                     cSVOPx(gvop)->op_sv = NULL;        /* steal it */
 #endif
@@ -8085,7 +8088,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
                         left->op_private & OPpOUR_INTRO;
                 }
                 else {
-                    ((PMOP*)right)->op_pmreplrootu.op_pmtargetoff = left->op_targ;
+                    cPMOPx(right)->op_pmreplrootu.op_pmtargetoff = left->op_targ;
                     left->op_targ = 0; /* steal it */
                     right->op_private |= OPpSPLIT_LEX;
                 }
@@ -8093,7 +8096,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
 
               detach_split:
                 tmpop = cUNOPo->op_first;      /* to list (nulled) */
-                tmpop = ((UNOP*)tmpop)->op_first; /* to pushmark */
+                tmpop = cUNOPx(tmpop)->op_first; /* to pushmark */
                 assert(OpSIBLING(tmpop) == right);
                 assert(!OpHAS_SIBLING(right));
                 /* detach the split subtreee from the o tree,
@@ -8120,11 +8123,11 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
                 goto detach_split;
             }
             else if (PL_modcount < RETURN_UNLIMITED_NUMBER &&
-                    ((LISTOP*)right)->op_last->op_type == OP_CONST)
+                    cLISTOPx(right)->op_last->op_type == OP_CONST)
             {
                 /* convert split(...,0) to split(..., PL_modcount+1) */
                 SV ** const svp =
-                    &((SVOP*)((LISTOP*)right)->op_last)->op_sv;
+                    &cSVOPx(cLISTOPx(right)->op_last)->op_sv;
                 SV * const sv = *svp;
                 if (SvIOK(sv) && SvIVX(sv) == 0)
                 {
@@ -8398,9 +8401,9 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
             no_bareword_allowed(cstop);
         else if ((cstop->op_private & OPpCONST_BARE))
                 Perl_ck_warner(aTHX_ packWARN(WARN_BAREWORD), "Bareword found in conditional");
-        if ((type == OP_AND &&  SvTRUE(((SVOP*)cstop)->op_sv)) ||
-            (type == OP_OR  && !SvTRUE(((SVOP*)cstop)->op_sv)) ||
-            (type == OP_DOR && !SvOK(((SVOP*)cstop)->op_sv))) {
+        if ((type == OP_AND &&  SvTRUE(cSVOPx(cstop)->op_sv)) ||
+            (type == OP_OR  && !SvTRUE(cSVOPx(cstop)->op_sv)) ||
+            (type == OP_DOR && !SvOK(cSVOPx(cstop)->op_sv))) {
             /* Elide the (constant) lhs, since it can't affect the outcome */
             *firstp = NULL;
             if (other->op_type == OP_CONST)
@@ -8449,7 +8452,7 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
     else if ((first->op_flags & OPf_KIDS) && type != OP_DOR
         && ckWARN(WARN_MISC)) /* [#24076] Don't warn for <FH> err FOO. */
     {
-        const OP * const k1 = ((UNOP*)first)->op_first;
+        const OP * const k1 = cUNOPx(first)->op_first;
         const OP * const k2 = OpSIBLING(k1);
         OPCODE warnop = 0;
         switch (first->op_type)
@@ -8560,7 +8563,7 @@ Perl_newCONDOP(pTHX_ I32 flags, OP *first, OP *trueop, OP *falseop)
     scalarboolean(first);
     if ((cstop = search_const(first))) {
         /* Left or right arm of the conditional?  */
-        const bool left = SvTRUE(((SVOP*)cstop)->op_sv);
+        const bool left = SvTRUE(cSVOPx(cstop)->op_sv);
         OP *live = left ? trueop : falseop;
         OP *const dead = left ? falseop : trueop;
         if (cstop->op_private & OPpCONST_BARE &&
@@ -8754,7 +8757,7 @@ Perl_newLOOPOP(pTHX_ I32 flags, I32 debuggable, OP *expr, OP *block)
 
     if (expr) {
         if (once && (
-              (expr->op_type == OP_CONST && !SvTRUE(((SVOP*)expr)->op_sv))
+              (expr->op_type == OP_CONST && !SvTRUE(cSVOPx(expr)->op_sv))
            || (  expr->op_type == OP_NOT
               && cUNOPx(expr)->op_first->op_type == OP_CONST
               && SvTRUE(cSVOPx_sv(cUNOPx(expr)->op_first))
@@ -8775,7 +8778,7 @@ Perl_newLOOPOP(pTHX_ I32 flags, I32 debuggable, OP *expr, OP *block)
             expr = newUNOP(OP_DEFINED, 0,
                 newASSIGNOP(0, newDEFSVOP(), 0, expr) );
         } else if (expr->op_flags & OPf_KIDS) {
-            const OP * const k1 = ((UNOP*)expr)->op_first;
+            const OP * const k1 = cUNOPx(expr)->op_first;
             const OP * const k2 = k1 ? OpSIBLING(k1) : NULL;
             switch (expr->op_type) {
               case OP_NULL:
@@ -8809,13 +8812,13 @@ Perl_newLOOPOP(pTHX_ I32 flags, I32 debuggable, OP *expr, OP *block)
     }
 
     if (listop)
-        ((LISTOP*)listop)->op_last->op_next = LINKLIST(o);
+        cLISTOPx(listop)->op_last->op_next = LINKLIST(o);
 
     if (once && o != listop)
     {
         assert(cUNOPo->op_first->op_type == OP_AND
             || cUNOPo->op_first->op_type == OP_OR);
-        o->op_next = ((LOGOP*)cUNOPo->op_first)->op_other;
+        o->op_next = cLOGOPx(cUNOPo->op_first)->op_other;
     }
 
     if (o == listop)
@@ -8872,7 +8875,7 @@ Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP *loop,
             expr = newUNOP(OP_DEFINED, 0,
                 newASSIGNOP(0, newDEFSVOP(), 0, expr) );
         } else if (expr->op_flags & OPf_KIDS) {
-            const OP * const k1 = ((UNOP*)expr)->op_first;
+            const OP * const k1 = cUNOPx(expr)->op_first;
             const OP * const k2 = (k1) ? OpSIBLING(k1) : NULL;
             switch (expr->op_type) {
               case OP_NULL:
@@ -8923,7 +8926,7 @@ Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP *loop,
             return expr;               /* listop already freed by new_logop */
         }
         if (listop)
-            ((LISTOP*)listop)->op_last->op_next =
+            cLISTOPx(listop)->op_last->op_next =
                 (o == listop ? redo : LINKLIST(o));
     }
     else
@@ -9019,7 +9022,7 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
         else if (sv->op_type == OP_NULL && sv->op_targ == OP_SREFGEN)
             NOOP;
         else if (sv->op_type == OP_LIST) {
-            LISTOP *list = (LISTOP *) sv;
+            LISTOP *list = cLISTOPx(sv);
             OP *pushmark = list->op_first;
             OP *first_padsv;
             UNOP *padsv;
@@ -9041,7 +9044,7 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
 
             /* There should be at least one more PADSV to find, and the ops
                should have consecutive values in targ: */
-            padsv = (UNOP *) OpSIBLING(first_padsv);
+            padsv = cUNOPx(OpSIBLING(first_padsv));
             do {
                 if (!padsv || padsv->op_type != OP_PADSV) {
                     Perl_croak(aTHX_ "panic: newFORLOOP, found %s at %zd, expecting padsv",
@@ -9054,7 +9057,7 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
                                how_many_more, padsv->op_targ, padoff + how_many_more);
                 }
 
-                padsv = (UNOP *) OpSIBLING(padsv);
+                padsv = cUNOPx(OpSIBLING(padsv));
             } while (padsv);
 
             /* OK, this optree has the shape that we expected. So now *we*
@@ -9064,13 +9067,13 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
 
             i = padoff;
 
-            padsv = (UNOP *) OpSIBLING(first_padsv);
+            padsv = cUNOPx(OpSIBLING(first_padsv));
             do {
                 ++i;
                 padsv->op_targ = 0;
                 PAD_COMPNAME_GEN_set(i, PERL_INT_MAX);
 
-                padsv = (UNOP *) OpSIBLING(padsv);
+                padsv = cUNOPx(OpSIBLING(padsv));
             } while (padsv);
 
             op_free(sv);
@@ -9097,14 +9100,14 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
     }
     else if (expr->op_type == OP_NULL &&
              (expr->op_flags & OPf_KIDS) &&
-             ((BINOP*)expr)->op_first->op_type == OP_FLOP)
+             cBINOPx(expr)->op_first->op_type == OP_FLOP)
     {
         /* Basically turn for($x..$y) into the same as for($x,$y), but we
          * set the STACKED flag to indicate that these values are to be
          * treated as min/max values by 'pp_enteriter'.
          */
-        const UNOP* const flip = (UNOP*)((UNOP*)((BINOP*)expr)->op_first)->op_first;
-        LOGOP* const range = (LOGOP*) flip->op_first;
+        const UNOP* const flip = cUNOPx(cUNOPx(cBINOPx(expr)->op_first)->op_first);
+        LOGOP* const range = cLOGOPx(flip->op_first);
         OP* const left  = range->op_first;
         OP* const right = OpSIBLING(left);
         LISTOP* listop;
@@ -9113,7 +9116,7 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
         /* detach range's children */
         op_sibling_splice((OP*)range, NULL, -1, NULL);
 
-        listop = (LISTOP*)newLISTOP(OP_LIST, 0, left, right);
+        listop = cLISTOPx(newLISTOP(OP_LIST, 0, left, right));
         listop->op_first->op_next = range->op_next;
         left->op_next = range->op_other;
         right->op_next = (OP*)listop;
@@ -9202,14 +9205,14 @@ Perl_newLOOPEX(pTHX_ I32 type, OP *label)
 
     /* Check for a constant argument */
     if (label->op_type == OP_CONST) {
-            SV * const sv = ((SVOP *)label)->op_sv;
+            SV * const sv = cSVOPx(label)->op_sv;
             STRLEN l;
             const char *s = SvPV_const(sv,l);
             if (l == strlen(s)) {
                 o = newPVOP(type,
-                            SvUTF8(((SVOP*)label)->op_sv),
+                            SvUTF8(cSVOPx(label)->op_sv),
                             savesharedpv(
-                                SvPV_nolen_const(((SVOP*)label)->op_sv)));
+                                SvPV_nolen_const(cSVOPx(label)->op_sv)));
             }
     }
 
@@ -9571,7 +9574,7 @@ Perl_cv_ckproto_len_flags(pTHX_ const CV *cv, const GV *gv, const char *p,
         else if (SvPOK(gv) && *SvPVX((SV *)gv) == '&')
             name = newSVpvn_flags(SvPVX((SV *)gv)+1, SvCUR(gv)-1, SvUTF8(gv)|SVs_TEMP);
         else if (flags & CV_CKPROTO_CURSTASH || SvROK(gv)) {
-            name = sv_2mortal(newSVhek(HvNAME_HEK(PL_curstash)));
+            name = newSVhek_mortal(HvNAME_HEK(PL_curstash));
             sv_catpvs(name, "::");
             if (SvROK(gv)) {
                 assert (SvTYPE(SvRV_const(gv)) == SVt_PVCV);
@@ -9800,8 +9803,8 @@ Perl_newMYSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
 
     if (proto) {
         assert(proto->op_type == OP_CONST);
-        ps = SvPV_const(((SVOP*)proto)->op_sv, ps_len);
-        ps_utf8 = SvUTF8(((SVOP*)proto)->op_sv);
+        ps = SvPV_const(cSVOPx(proto)->op_sv, ps_len);
+        ps_utf8 = SvUTF8(cSVOPx(proto)->op_sv);
     }
     else
         ps = NULL;
@@ -10276,8 +10279,8 @@ Perl_newATTRSUB_x(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs,
 
     if (proto) {
         assert(proto->op_type == OP_CONST);
-        ps = SvPV_const(((SVOP*)proto)->op_sv, ps_len);
-        ps_utf8 = SvUTF8(((SVOP*)proto)->op_sv);
+        ps = SvPV_const(cSVOPx(proto)->op_sv, ps_len);
+        ps_utf8 = SvUTF8(cSVOPx(proto)->op_sv);
     }
     else
         ps = NULL;
@@ -11335,7 +11338,7 @@ Perl_newGVREF(pTHX_ I32 type, OP *o)
     if (!FEATURE_BAREWORD_FILEHANDLES_IS_ENABLED &&
         ((PL_opargs[type] >> OASHIFT) & 7) == OA_FILEREF &&
         o->op_type == OP_CONST && (o->op_private & OPpCONST_BARE)) {
-        no_bareword_filehandle(SvPVX(cSVOPx_sv((SVOP*)o)));
+        no_bareword_filehandle(SvPVX(cSVOPo_sv));
     }
 
     return ref(newUNOP(OP_RV2GV, OPf_REF, o), type);
@@ -11747,7 +11750,7 @@ Perl_ck_eval(pTHX_ OP *o)
 
     PL_hints |= HINT_BLOCK_SCOPE;
     if (o->op_flags & OPf_KIDS) {
-        SVOP * const kid = (SVOP*)cUNOPo->op_first;
+        SVOP * const kid = cSVOPx(cUNOPo->op_first);
         assert(kid);
 
         if (o->op_type == OP_ENTERTRY) {
@@ -11910,7 +11913,7 @@ Perl_ck_exists(pTHX_ OP *o)
 OP *
 Perl_ck_rvconst(pTHX_ OP *o)
 {
-    SVOP * const kid = (SVOP*)cUNOPo->op_first;
+    SVOP * const kid = cSVOPx(cUNOPo->op_first);
 
     PERL_ARGS_ASSERT_CK_RVCONST;
 
@@ -12012,13 +12015,13 @@ Perl_ck_ftst(pTHX_ OP *o)
         NOOP;
     }
     else if (o->op_flags & OPf_KIDS && cUNOPo->op_first->op_type != OP_STUB) {
-        SVOP * const kid = (SVOP*)cUNOPo->op_first;
+        SVOP * const kid = cSVOPx(cUNOPo->op_first);
         const OPCODE kidtype = kid->op_type;
 
         if (kidtype == OP_CONST && (kid->op_private & OPpCONST_BARE)
          && !kid->op_folded) {
             if (!FEATURE_BAREWORD_FILEHANDLES_IS_ENABLED) {
-                no_bareword_filehandle(SvPVX(cSVOPx_sv((SVOP*)kid)));
+                no_bareword_filehandle(SvPVX(kSVOP_sv));
             }
             OP * const newop = newGVOP(type, OPf_REF,
                 gv_fetchsv(kid->op_sv, GV_ADD, SVt_PVIO));
@@ -12175,11 +12178,11 @@ Perl_ck_fun(pTHX_ OP *o)
                         (kid->op_private & OPpCONST_BARE))
                     {
                         OP * const newop = newGVOP(OP_GV, 0,
-                            gv_fetchsv(((SVOP*)kid)->op_sv, GV_ADD, SVt_PVIO));
+                            gv_fetchsv(kSVOP->op_sv, GV_ADD, SVt_PVIO));
                         /* a first argument is handled by toke.c, ideally we'd
                          just check here but several ops don't use ck_fun() */
                         if (!FEATURE_BAREWORD_FILEHANDLES_IS_ENABLED) {
-                            no_bareword_filehandle(SvPVX(cSVOPx_sv((SVOP*)kid)));
+                            no_bareword_filehandle(SvPVX(kSVOP_sv));
                         }
                         /* replace kid with newop in chain */
                         op_sibling_splice(o, prev_kid, 1, newop);
@@ -12227,7 +12230,7 @@ Perl_ck_fun(pTHX_ OP *o)
                                      || kid->op_type == OP_HELEM)
                             {
                                  OP *firstop;
-                                 OP *op = ((BINOP*)kid)->op_first;
+                                 OP *op = kBINOP->op_first;
                                  name = NULL;
                                  if (op) {
                                       SV *tmpstr = NULL;
@@ -12236,7 +12239,7 @@ Perl_ck_fun(pTHX_ OP *o)
                                            "[]" : "{}";
                                       if (((op->op_type == OP_RV2AV) ||
                                            (op->op_type == OP_RV2HV)) &&
-                                          (firstop = ((UNOP*)op)->op_first) &&
+                                          (firstop = cUNOPx(op)->op_first) &&
                                           (firstop->op_type == OP_GV)) {
                                            /* packagevar $a[] or $h{} */
                                            GV * const gv = cGVOPx_gv(firstop);
@@ -12495,7 +12498,7 @@ Perl_ck_readline(pTHX_ OP *o)
          OP *kid = cLISTOPo->op_first;
          if (!FEATURE_BAREWORD_FILEHANDLES_IS_ENABLED
              && kid->op_type == OP_CONST && (kid->op_private & OPpCONST_BARE)) {
-             no_bareword_filehandle(SvPVX(cSVOPx_sv((SVOP*)kid)));
+             no_bareword_filehandle(SvPVX(kSVOP_sv));
          }
          if (kid->op_type == OP_RV2GV) kid->op_private |= OPpALLOW_FAKE;
          scalar(kid);
@@ -12539,7 +12542,7 @@ Perl_ck_listiob(pTHX_ OP *o)
         if (kid->op_type == OP_CONST && kid->op_private & OPpCONST_BARE
          && !kid->op_folded) {
             if (!FEATURE_BAREWORD_FILEHANDLES_IS_ENABLED) {
-                no_bareword_filehandle(SvPVX(cSVOPx_sv((SVOP*)kid)));
+                no_bareword_filehandle(SvPVX(kSVOP_sv));
             }
             o->op_flags |= OPf_STACKED;        /* make it a filehandle */
             scalar(kid);
@@ -12745,8 +12748,8 @@ Perl_ck_open(pTHX_ OP *o)
              (oa = OpSIBLING(first)) &&                /* The fh. */
              (oa = OpSIBLING(oa)) &&                   /* The mode. */
              (oa->op_type == OP_CONST) &&
-             SvPOK(((SVOP*)oa)->op_sv) &&
-             (mode = SvPVX_const(((SVOP*)oa)->op_sv)) &&
+             SvPOK(cSVOPx(oa)->op_sv) &&
+             (mode = SvPVX_const(cSVOPx(oa)->op_sv)) &&
              mode[0] == '>' && mode[1] == '&' &&       /* A dup open. */
              (last == OpSIBLING(oa)))                  /* The bareword. */
               last->op_private &= ~OPpCONST_STRICT;
@@ -12826,7 +12829,7 @@ Perl_ck_refassign(pTHX_ OP *o)
                 /* a CVREF here confuses pp_refassign, so make sure
                    it gets a GV */
                 CV *const cv = (CV*)SvRV(sv);
-                SV *name_sv = sv_2mortal(newSVhek(CvNAME_HEK(cv)));
+                SV *name_sv = newSVhek_mortal(CvNAME_HEK(cv));
                 (void)gv_init_sv((GV*)sv, CvSTASH(cv), name_sv, 0);
                 assert(SvTYPE(sv) == SVt_PVGV);
             }
@@ -12897,7 +12900,7 @@ Perl_ck_require(pTHX_ OP *o)
     PERL_ARGS_ASSERT_CK_REQUIRE;
 
     if (o->op_flags & OPf_KIDS) {      /* Shall we supply missing .pm? */
-        SVOP * const kid = (SVOP*)cUNOPo->op_first;
+        SVOP * const kid = cSVOPx(cUNOPo->op_first);
         U32 hash;
         char *s;
         STRLEN len;
@@ -13261,7 +13264,7 @@ Perl_ck_split(pTHX_ OP *o)
 
     assert(kid->op_type == OP_MATCH || kid->op_type == OP_SPLIT);
 
-    if (((PMOP *)kid)->op_pmflags & PMf_GLOBAL) {
+    if (kPMOP->op_pmflags & PMf_GLOBAL) {
       Perl_ck_warner(aTHX_ packWARN(WARN_REGEXP),
                      "Use of /g modifier is meaningless in split");
     }
@@ -13926,7 +13929,7 @@ Perl_ck_entersub_args_core(pTHX_ OP *entersubop, GV *namegv, SV *protosv)
 
             }
             return opnum == OP_RUNCV
-                ? newPVOP(OP_RUNCV,0,NULL)
+                ? newSVOP(OP_RUNCV, 0, &PL_sv_undef)
                 : newOP(opnum,0);
         default:
             return op_convert_list(opnum,0,aop);
@@ -14150,7 +14153,7 @@ Perl_ck_subr(pTHX_ OP *o)
                 const_class = &cSVOPx(aop)->op_sv;
             }
             else if (aop->op_type == OP_LIST) {
-                OP * const sib = OpSIBLING(((UNOP*)aop)->op_first);
+                OP * const sib = OpSIBLING(cUNOPx(aop)->op_first);
                 if (sib && sib->op_type == OP_CONST) {
                     sib->op_private &= ~OPpCONST_STRICT;
                     const_class = &cSVOPx(sib)->op_sv;
@@ -14237,10 +14240,10 @@ Perl_ck_trunc(pTHX_ OP *o)
     PERL_ARGS_ASSERT_CK_TRUNC;
 
     if (o->op_flags & OPf_KIDS) {
-        SVOP *kid = (SVOP*)cUNOPo->op_first;
+        SVOP *kid = cSVOPx(cUNOPo->op_first);
 
         if (kid->op_type == OP_NULL)
-            kid = (SVOP*)OpSIBLING(kid);
+            kid = cSVOPx(OpSIBLING(kid));
         if (kid && kid->op_type == OP_CONST &&
             (kid->op_private & OPpCONST_BARE) &&
             !kid->op_folded)