This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
t/TEST: $failure doesnt need to use defined
[perl5.git] / pp_ctl.c
index b25905d..e32a17e 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -793,26 +793,14 @@ PP(pp_formline)
 
        case FF_0DECIMAL: /* like FF_DECIMAL but for 0### */
            arg = *fpc++;
-#if defined(USE_LONG_DOUBLE)
            fmt = (const char *)
-               ((arg & FORM_NUM_POINT) ?
-                "%#0*.*" PERL_PRIfldbl : "%0*.*" PERL_PRIfldbl);
-#else
-           fmt = (const char *)
-               ((arg & FORM_NUM_POINT) ?
-                "%#0*.*f"              : "%0*.*f");
-#endif
+               ((arg & FORM_NUM_POINT) ? "%#0*.*" NVff : "%0*.*" NVff);
            goto ff_dec;
 
        case FF_DECIMAL: /* do @##, ^##, where <arg>=(precision|flags) */
            arg = *fpc++;
-#if defined(USE_LONG_DOUBLE)
            fmt = (const char *)
-               ((arg & FORM_NUM_POINT) ? "%#*.*" PERL_PRIfldbl : "%*.*" PERL_PRIfldbl);
-#else
-            fmt = (const char *)
-               ((arg & FORM_NUM_POINT) ? "%#*.*f"              : "%*.*f");
-#endif
+               ((arg & FORM_NUM_POINT) ? "%#*.*" NVff : "%*.*" NVff);
        ff_dec:
            /* If the field is marked with ^ and the value is undefined,
               blank it out. */
@@ -837,11 +825,25 @@ PP(pp_formline)
                 int len;
                 DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED();
                 arg &= ~(FORM_NUM_POINT|FORM_NUM_BLANK);
+#ifdef USE_QUADMATH
+                {
+                    const char* qfmt = quadmath_format_single(fmt);
+                    int len;
+                    if (!qfmt)
+                        Perl_croak_nocontext("panic: quadmath invalid format \"%s\"", fmt);
+                    len = quadmath_snprintf(t, max, qfmt, (int) fieldsize, (int) arg, value);
+                    if (len == -1)
+                        Perl_croak_nocontext("panic: quadmath_snprintf failed, format \"%s\"", qfmt);
+                    if (qfmt != fmt)
+                        Safefree(fmt);
+                }
+#else
                 /* we generate fmt ourselves so it is safe */
                 GCC_DIAG_IGNORE(-Wformat-nonliteral);
                 len = my_snprintf(t, max, fmt, (int) fieldsize, (int) arg, value);
-                PERL_MY_SNPRINTF_POST_GUARD(len, max);
                 GCC_DIAG_RESTORE;
+#endif
+                PERL_MY_SNPRINTF_POST_GUARD(len, max);
                 RESTORE_LC_NUMERIC();
            }
            t += fieldsize;
@@ -939,7 +941,6 @@ PP(pp_grepstart)
 
     src = PL_stack_base[*PL_markstack_ptr];
     if (SvPADTMP(src)) {
-        assert(!IS_PADGV(src));
        src = PL_stack_base[*PL_markstack_ptr] = sv_mortalcopy(src);
        PL_tmps_floor++;
     }
@@ -1092,7 +1093,6 @@ PP(pp_mapwhile)
        /* set $_ to the new source item */
        src = PL_stack_base[PL_markstack_ptr[-1]];
        if (SvPADTMP(src)) {
-            assert(!IS_PADGV(src));
             src = sv_mortalcopy(src);
         }
        SvTEMP_off(src);
@@ -1626,7 +1626,9 @@ Perl_die_unwind(pTHX_ SV *msv)
            SV *namesv;
            PERL_CONTEXT *cx;
            SV **newsp;
+#ifdef DEBUGGING
            COP *oldcop;
+#endif
            JMPENV *restartjmpenv;
            OP *restartop;
 
@@ -1643,7 +1645,9 @@ Perl_die_unwind(pTHX_ SV *msv)
            }
            POPEVAL(cx);
            namesv = cx->blk_eval.old_namesv;
+#ifdef DEBUGGING
            oldcop = cx->blk_oldcop;
+#endif
            restartjmpenv = cx->blk_eval.cur_top_env;
            restartop = cx->blk_eval.retop;
 
@@ -1653,13 +1657,8 @@ Perl_die_unwind(pTHX_ SV *msv)
 
            LEAVE;
 
-           /* LEAVE could clobber PL_curcop (see save_re_context())
-            * XXX it might be better to find a way to avoid messing with
-            * PL_curcop in save_re_context() instead, but this is a more
-            * minimal fix --GSAR */
-           PL_curcop = oldcop;
-
            if (optype == OP_REQUIRE) {
+                assert (PL_curcop == oldcop);
                 (void)hv_store(GvHVn(PL_incgv),
                                SvPVX_const(namesv),
                                SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
@@ -1819,12 +1818,9 @@ PP(pp_caller)
     if (!has_arg)
        RETURN;
     if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
-       GV * const cvgv = CvGV(dbcx->blk_sub.cv);
        /* So is ccstack[dbcxix]. */
-       if (cvgv && isGV(cvgv)) {
-           SV * const sv = newSV(0);
-           gv_efullname3(sv, cvgv, NULL);
-           mPUSHs(sv);
+       if (CvHASGV(dbcx->blk_sub.cv)) {
+           PUSHs(cv_name(dbcx->blk_sub.cv, 0, 0));
            PUSHs(boolSV(CxHASARGS(cx)));
        }
        else {
@@ -1943,7 +1939,7 @@ PP(pp_dbstate)
     PERL_ASYNC_CHECK();
 
     if (PL_op->op_flags & OPf_SPECIAL /* breakpoint */
-           || SvIV(PL_DBsingle) || SvIV(PL_DBsignal) || SvIV(PL_DBtrace))
+           || PL_DBsingle_iv || PL_DBsignal_iv || PL_DBtrace_iv)
     {
        dSP;
        PERL_CONTEXT *cx;
@@ -1996,17 +1992,24 @@ PP(pp_dbstate)
        return NORMAL;
 }
 
+/* S_leave_common: Common code that many functions in this file use on
+                  scope exit.  */
+
 /* SVs on the stack that have any of the flags passed in are left as is.
    Other SVs are protected via the mortals stack if lvalue is true, and
-   copied otherwise. */
+   copied otherwise.
+
+   Also, taintedness is cleared.
+*/
 
 STATIC SV **
-S_adjust_stack_on_leave(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme,
+S_leave_common(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme,
                              U32 flags, bool lvalue)
 {
     bool padtmp = 0;
-    PERL_ARGS_ASSERT_ADJUST_STACK_ON_LEAVE;
+    PERL_ARGS_ASSERT_LEAVE_COMMON;
 
+    TAINT_NOT;
     if (flags & SVs_PADTMP) {
        flags &= ~SVs_PADTMP;
        padtmp = 1;
@@ -2076,8 +2079,7 @@ PP(pp_leave)
 
     gimme = OP_GIMME(PL_op, (cxstack_ix >= 0) ? gimme : G_SCALAR);
 
-    TAINT_NOT;
-    SP = adjust_stack_on_leave(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP,
+    SP = leave_common(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP,
                               PL_op->op_private & OPpLVALUE);
     PL_curpm = newpm;  /* Don't pop $1 et al till now */
 
@@ -2110,12 +2112,21 @@ PP(pp_enteriter)
        itervar = &PAD_SVl(PL_op->op_targ);
 #endif
     }
-    else {                                     /* symbol table variable */
+    else if (LIKELY(isGV(TOPs))) {             /* symbol table variable */
        GV * const gv = MUTABLE_GV(POPs);
        SV** svp = &GvSV(gv);
        save_pushptrptr(gv, SvREFCNT_inc(*svp), SAVEt_GVSV);
        *svp = newSV(0);
        itervar = (void *)gv;
+       save_aliased_sv(gv);
+    }
+    else {
+       SV * const sv = POPs;
+       assert(SvTYPE(sv) == SVt_PVMG);
+       assert(SvMAGIC(sv));
+       assert(SvMAGIC(sv)->mg_type == PERL_MAGIC_lvref);
+       itervar = (void *)sv;
+       cxtype |= CXp_FOR_LVREF;
     }
 
     if (PL_op->op_private & OPpITER_DEF)
@@ -2130,32 +2141,35 @@ PP(pp_enteriter)
        if (SvTYPE(maybe_ary) != SVt_PVAV) {
            dPOPss;
            SV * const right = maybe_ary;
+           if (UNLIKELY(cxtype & CXp_FOR_LVREF))
+               DIE(aTHX_ "Assigned value is not a reference");
            SvGETMAGIC(sv);
            SvGETMAGIC(right);
            if (RANGE_IS_NUMERIC(sv,right)) {
+               NV nv;
                cx->cx_type &= ~CXTYPEMASK;
                cx->cx_type |= CXt_LOOP_LAZYIV;
                /* Make sure that no-one re-orders cop.h and breaks our
                   assumptions */
                assert(CxTYPE(cx) == CXt_LOOP_LAZYIV);
 #ifdef NV_PRESERVES_UV
-               if ((SvOK(sv) && ((SvNV_nomg(sv) < (NV)IV_MIN) ||
-                                 (SvNV_nomg(sv) > (NV)IV_MAX)))
+               if ((SvOK(sv) && (((nv = SvNV_nomg(sv)) < (NV)IV_MIN) ||
+                                 (nv > (NV)IV_MAX)))
                        ||
-                   (SvOK(right) && ((SvNV_nomg(right) > (NV)IV_MAX) ||
-                                    (SvNV_nomg(right) < (NV)IV_MIN))))
+                   (SvOK(right) && (((nv = SvNV_nomg(right)) > (NV)IV_MAX) ||
+                                    (nv < (NV)IV_MIN))))
 #else
-               if ((SvOK(sv) && ((SvNV_nomg(sv) <= (NV)IV_MIN)
+               if ((SvOK(sv) && (((nv = SvNV_nomg(sv)) <= (NV)IV_MIN)
                                  ||
-                                 ((SvNV_nomg(sv) > 0) &&
-                                       ((SvUV_nomg(sv) > (UV)IV_MAX) ||
-                                        (SvNV_nomg(sv) > (NV)UV_MAX)))))
+                                 ((nv > 0) &&
+                                       ((nv > (NV)UV_MAX) ||
+                                        (SvUV_nomg(sv) > (UV)IV_MAX)))))
                        ||
-                   (SvOK(right) && ((SvNV_nomg(right) <= (NV)IV_MIN)
+                   (SvOK(right) && (((nv = SvNV_nomg(right)) <= (NV)IV_MIN)
                                     ||
-                                    ((SvNV_nomg(right) > 0) &&
-                                       ((SvUV_nomg(right) > (UV)IV_MAX) ||
-                                        (SvNV_nomg(right) > (NV)UV_MAX))
+                                    ((nv > 0) &&
+                                       ((nv > (NV)UV_MAX) ||
+                                        (SvUV_nomg(right) > (UV)IV_MAX))
                                     ))))
 #endif
                    DIE(aTHX_ "Range iterator outside integer range");
@@ -2239,8 +2253,7 @@ PP(pp_leaveloop)
     mark = newsp;
     newsp = PL_stack_base + cx->blk_loop.resetsp;
 
-    TAINT_NOT;
-    SP = adjust_stack_on_leave(newsp, SP, MARK, gimme, 0,
+    SP = leave_common(newsp, SP, MARK, gimme, 0,
                               PL_op->op_private & OPpLVALUE);
     PUTBACK;
 
@@ -2264,10 +2277,7 @@ S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme,
            const char *what = NULL;
            if (MARK < SP) {
                assert(MARK+1 == SP);
-               if ((SvPADTMP(TOPs) ||
-                    (SvFLAGS(TOPs) & (SVf_READONLY | SVf_FAKE))
-                      == SVf_READONLY
-                   ) &&
+               if ((SvPADTMP(TOPs) || SvREADONLY(TOPs)) &&
                    !SvSMAGICAL(TOPs)) {
                    what =
                        SvREADONLY(TOPs) ? (TOPs == &PL_sv_undef) ? "undef"
@@ -2335,11 +2345,9 @@ S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme,
                           : sv_2mortal(SvREFCNT_inc_simple_NN(*MARK));
        else while (++MARK <= SP) {
            if (*MARK != &PL_sv_undef
-                   && (SvPADTMP(*MARK)
-                      || (SvFLAGS(*MARK) & (SVf_READONLY|SVf_FAKE))
-                            == SVf_READONLY
-                      )
+                   && (SvPADTMP(*MARK) || SvREADONLY(*MARK))
            ) {
+                   const bool ro = cBOOL( SvREADONLY(*MARK) );
                    SV *sv;
                    /* Might be flattened array after $#array =  */
                    PUTBACK;
@@ -2351,7 +2359,7 @@ S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme,
               /* diag_listed_as: Can't return %s from lvalue subroutine */
                    Perl_croak(aTHX_
                        "Can't return a %s from lvalue subroutine",
-                       SvREADONLY(TOPs) ? "readonly value" : "temporary");
+                        ro ? "readonly value" : "temporary");
            }
            else
                *++newsp =
@@ -2741,7 +2749,10 @@ S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstac
     return 0;
 }
 
-PP(pp_goto) /* also pp_dump */
+
+/* also used for: pp_dump() */
+
+PP(pp_goto)
 {
     dVAR; dSP;
     OP *retop = NULL;
@@ -2857,7 +2868,6 @@ PP(pp_goto) /* also pp_dump */
            SAVETMPS;
            SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
            if (CvISXSUB(cv)) {
-               OP* const retop = cx->blk_sub.retop;
                SV **newsp;
                I32 gimme;
                const SSize_t items = arg ? AvFILL(arg) + 1 : 0;
@@ -2897,6 +2907,7 @@ PP(pp_goto) /* also pp_dump */
                    SvREFCNT_dec(arg);
                }
 
+               retop = cx->blk_sub.retop;
                /* XS subs don't have a CxSUB, so pop it */
                POPBLOCK(cx, PL_curpm);
                /* Push a mark for the start of arglist */
@@ -2904,8 +2915,7 @@ PP(pp_goto) /* also pp_dump */
                PUTBACK;
                (void)(*CvXSUB(cv))(aTHX_ cv);
                LEAVE;
-               PERL_ASYNC_CHECK();
-               return retop;
+               goto _return;
            }
            else {
                PADLIST * const padlist = CvPADLIST(cv);
@@ -2958,8 +2968,8 @@ PP(pp_goto) /* also pp_dump */
                        }
                    }
                }
-               PERL_ASYNC_CHECK();
-               RETURNOP(CvSTART(cv));
+               retop = CvSTART(cv);
+               goto putback_return;
            }
        }
        else {
@@ -3035,14 +3045,17 @@ PP(pp_goto) /* also pp_dump */
                break;
            }
            if (gotoprobe) {
+                OP *sibl1, *sibl2;
+
                retop = dofindlabel(gotoprobe, label, label_len, label_flags,
                                    enterops, enterops + GOTO_DEPTH);
                if (retop)
                    break;
-               if (OP_HAS_SIBLING(gotoprobe) &&
-                       OP_SIBLING(gotoprobe)->op_type == OP_UNSTACK &&
-                       OP_HAS_SIBLING(OP_SIBLING(gotoprobe))) {
-                   retop = dofindlabel(OP_SIBLING(OP_SIBLING(gotoprobe)),
+               if ( (sibl1 = OP_SIBLING(gotoprobe)) &&
+                    sibl1->op_type == OP_UNSTACK &&
+                    (sibl2 = OP_SIBLING(sibl1)))
+                {
+                   retop = dofindlabel(sibl2,
                                        label, label_len, label_flags, enterops,
                                        enterops + GOTO_DEPTH);
                    if (retop)
@@ -3102,7 +3115,8 @@ PP(pp_goto) /* also pp_dump */
        }
     }
 
-    if (do_dump) {
+    else {
+        assert(do_dump);
 #ifdef VMS
        if (!retop) retop = PL_main_start;
 #endif
@@ -3115,8 +3129,11 @@ PP(pp_goto) /* also pp_dump */
        PL_do_undump = FALSE;
     }
 
+    putback_return:
+    PL_stack_sp = sp;
+    _return:
     PERL_ASYNC_CHECK();
-    RETURNOP(retop);
+    return retop;
 }
 
 PP(pp_exit)
@@ -3369,7 +3386,7 @@ S_doeval(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
 
     /* set up a scratch pad */
 
-    CvPADLIST(evalcv) = pad_new(padnew_SAVE);
+    CvPADLIST_set(evalcv, pad_new(padnew_SAVE));
     PL_op = NULL; /* avoid PL_op and PL_curpad referring to different CVs */
 
 
@@ -3649,6 +3666,9 @@ S_path_is_searchable(const char *name)
        return TRUE;
 }
 
+
+/* also used for: pp_dofile() */
+
 PP(pp_require)
 {
     dSP;
@@ -3677,6 +3697,7 @@ PP(pp_require)
     bool path_searchable;
 
     sv = POPs;
+    SvGETMAGIC(sv);
     if ( (SvNIOKp(sv) || SvVOK(sv)) && PL_op->op_type != OP_DOFILE) {
        sv = sv_2mortal(new_version(sv));
        if (!Perl_sv_derived_from_pvn(aTHX_ PL_patchlevel, STR_WITH_LEN("version"), 0))
@@ -3734,9 +3755,12 @@ PP(pp_require)
 
        RETPUSHYES;
     }
-    name = SvPV_const(sv, len);
+    if (!SvOK(sv))
+        DIE(aTHX_ "Missing or undefined argument to require");
+    name = SvPV_nomg_const(sv, len);
     if (!(name && len > 0 && *name))
-       DIE(aTHX_ "Null filename used");
+        DIE(aTHX_ "Missing or undefined argument to require");
+
     if (!IS_SAFE_PATHNAME(name, len, "require")) {
         DIE(aTHX_ "Can't locate %s:   %s",
             pv_escape(newSVpvs_flags("",SVs_TEMP),SvPVX(sv),SvCUR(sv),
@@ -4291,8 +4315,7 @@ PP(pp_leaveeval)
     retop = cx->blk_eval.retop;
     evalcv = cx->blk_eval.cv;
 
-    TAINT_NOT;
-    SP = adjust_stack_on_leave((gimme == G_VOID) ? SP : newsp, SP, newsp,
+    SP = leave_common((gimme == G_VOID) ? SP : newsp, SP, newsp,
                                gimme, SVs_TEMP, FALSE);
     PL_curpm = newpm;  /* Don't pop $1 et al till now */
 
@@ -4389,8 +4412,7 @@ PP(pp_leavetry)
     POPEVAL(cx);
     PERL_UNUSED_VAR(optype);
 
-    TAINT_NOT;
-    SP = adjust_stack_on_leave(newsp, SP, newsp, gimme,
+    SP = leave_common(newsp, SP, newsp, gimme,
                               SVs_PADTMP|SVs_TEMP, FALSE);
     PL_curpm = newpm;  /* Don't pop $1 et al till now */
 
@@ -4436,8 +4458,7 @@ PP(pp_leavegiven)
     POPBLOCK(cx,newpm);
     assert(CxTYPE(cx) == CXt_GIVEN);
 
-    TAINT_NOT;
-    SP = adjust_stack_on_leave(newsp, SP, newsp, gimme,
+    SP = leave_common(newsp, SP, newsp, gimme,
                               SVs_PADTMP|SVs_TEMP, FALSE);
     PL_curpm = newpm;  /* Don't pop $1 et al till now */
 
@@ -5010,8 +5031,7 @@ PP(pp_leavewhen)
     POPBLOCK(cx,newpm);
     assert(CxTYPE(cx) == CXt_WHEN);
 
-    TAINT_NOT;
-    SP = adjust_stack_on_leave(newsp, SP, newsp, gimme,
+    SP = leave_common(newsp, SP, newsp, gimme,
                               SVs_PADTMP|SVs_TEMP, FALSE);
     PL_curpm = newpm;   /* pop $1 et al */