perlio.c: (Coverity) eliminate temp ptr that confuses Coverity into thinking there...
[p5sagit/p5-mst-13.2.git] / sv.c
diff --git a/sv.c b/sv.c
index 63cef31..8e90234 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -6188,7 +6188,6 @@ Perl_sv_gets(pTHX_ register SV *sv, register PerlIO *fp, I32 append)
     register I32 cnt;
     I32 i = 0;
     I32 rspara = 0;
-    I32 recsize;
 
     if (SvTHINKFIRST(sv))
        sv_force_normal_flags(sv, append ? 0 : SV_COW_DROP_PV);
@@ -6229,9 +6228,9 @@ Perl_sv_gets(pTHX_ register SV *sv, register PerlIO *fp, I32 append)
     }
     else if (RsSNARF(PL_rs)) {
        /* If it is a regular disk file use size from stat() as estimate
-          of amount we are going to read - may result in malloc-ing
-          more memory than we realy need if layers bellow reduce
-          size we read (e.g. CRLF or a gzip layer)
+          of amount we are going to read -- may result in mallocing
+          more memory than we really need if the layers below reduce
+          the size we read (e.g. CRLF or a gzip layer).
         */
        Stat_t st;
        if (!PerlLIO_fstat(PerlIO_fileno(fp), &st) && S_ISREG(st.st_mode))  {
@@ -6246,9 +6245,10 @@ Perl_sv_gets(pTHX_ register SV *sv, register PerlIO *fp, I32 append)
     else if (RsRECORD(PL_rs)) {
       I32 bytesread;
       char *buffer;
+      U32 recsize;
 
       /* Grab the size of the record we're getting */
-      recsize = SvIV(SvRV(PL_rs));
+      recsize = SvUV(SvRV(PL_rs)); /* RsRECORD() guarantees > 0. */
       buffer = SvGROW(sv, (STRLEN)(recsize + append + 1)) + append;
       /* Go yank in */
 #ifdef VMS
@@ -6964,9 +6964,23 @@ Perl_newSVhek(pTHX_ const HEK *hek)
            return sv;
        }
        /* This will be overwhelminly the most common case.  */
-       return newSVpvn_share(HEK_KEY(hek),
-                             (HEK_UTF8(hek) ? -HEK_LEN(hek) : HEK_LEN(hek)),
-                             HEK_HASH(hek));
+       {
+           /* Inline most of newSVpvn_share(), because share_hek_hek() is far
+              more efficient than sharepvn().  */
+           SV *sv;
+
+           new_SV(sv);
+           sv_upgrade(sv, SVt_PV);
+           SvPV_set(sv, (char *)HEK_KEY(share_hek_hek(hek)));
+           SvCUR_set(sv, HEK_LEN(hek));
+           SvLEN_set(sv, 0);
+           SvREADONLY_on(sv);
+           SvFAKE_on(sv);
+           SvPOK_on(sv);
+           if (HEK_UTF8(hek))
+               SvUTF8_on(sv);
+           return sv;
+       }
     }
 }
 
@@ -6990,6 +7004,8 @@ Perl_newSVpvn_share(pTHX_ const char *src, I32 len, U32 hash)
     dVAR;
     register SV *sv;
     bool is_utf8 = FALSE;
+    const char *const orig_src = src;
+
     if (len < 0) {
        STRLEN tmplen = -len;
         is_utf8 = TRUE;
@@ -7009,6 +7025,8 @@ Perl_newSVpvn_share(pTHX_ const char *src, I32 len, U32 hash)
     SvPOK_on(sv);
     if (is_utf8)
         SvUTF8_on(sv);
+    if (src != orig_src)
+       Safefree(src);
     return sv;
 }
 
@@ -9390,6 +9408,9 @@ ptr_table_* functions.
 #endif
 
 
+/* Certain cases in Perl_ss_dup have been merged, by relying on the fact
+   that currently av_dup and hv_dup are the same as sv_dup. If this changes,
+   please unmerge ss_dup.  */
 #define sv_dup_inc(s,t)        SvREFCNT_inc(sv_dup(s,t))
 #define sv_dup_inc_NN(s,t)     SvREFCNT_inc_NN(sv_dup(s,t))
 #define av_dup(s,t)    (AV*)sv_dup((SV*)s,t)
@@ -10371,17 +10392,12 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
        TOPINT(nss,ix) = i;
        switch (i) {
        case SAVEt_ITEM:                        /* normal string */
+        case SAVEt_SV:                         /* scalar reference */
            sv = (SV*)POPPTR(ss,ix);
            TOPPTR(nss,ix) = sv_dup_inc(sv, param);
            sv = (SV*)POPPTR(ss,ix);
            TOPPTR(nss,ix) = sv_dup_inc(sv, param);
            break;
-        case SAVEt_SV:                         /* scalar reference */
-           sv = (SV*)POPPTR(ss,ix);
-           TOPPTR(nss,ix) = sv_dup_inc(sv, param);
-           gv = (GV*)POPPTR(ss,ix);
-           TOPPTR(nss,ix) = gv_dup_inc(gv, param);
-           break;
        case SAVEt_SHARED_PVREF:                /* char* in shared space */
            c = (char*)POPPTR(ss,ix);
            TOPPTR(nss,ix) = savesharedpv(c);
@@ -10395,15 +10411,10 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = svp_dup_inc((SV**)ptr, proto_perl);/* XXXXX */
            break;
-        case SAVEt_AV:                         /* array reference */
-           av = (AV*)POPPTR(ss,ix);
-           TOPPTR(nss,ix) = av_dup_inc(av, param);
-           gv = (GV*)POPPTR(ss,ix);
-           TOPPTR(nss,ix) = gv_dup(gv, param);
-           break;
         case SAVEt_HV:                         /* hash reference */
-           hv = (HV*)POPPTR(ss,ix);
-           TOPPTR(nss,ix) = hv_dup_inc(hv, param);
+        case SAVEt_AV:                         /* array reference */
+           sv = POPPTR(ss,ix);
+           TOPPTR(nss,ix) = sv_dup_inc(sv, param);
            gv = (GV*)POPPTR(ss,ix);
            TOPPTR(nss,ix) = gv_dup(gv, param);
            break;
@@ -10434,6 +10445,8 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            iv = POPIV(ss,ix);
            TOPIV(nss,ix) = iv;
            break;
+       case SAVEt_HPTR:                        /* HV* reference */
+       case SAVEt_APTR:                        /* AV* reference */
        case SAVEt_SPTR:                        /* SV* reference */
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
@@ -10453,18 +10466,6 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            c = (char*)POPPTR(ss,ix);
            TOPPTR(nss,ix) = pv_dup(c);
            break;
-       case SAVEt_HPTR:                        /* HV* reference */
-           ptr = POPPTR(ss,ix);
-           TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
-           hv = (HV*)POPPTR(ss,ix);
-           TOPPTR(nss,ix) = hv_dup(hv, param);
-           break;
-       case SAVEt_APTR:                        /* AV* reference */
-           ptr = POPPTR(ss,ix);
-           TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
-           av = (AV*)POPPTR(ss,ix);
-           TOPPTR(nss,ix) = av_dup(av, param);
-           break;
        case SAVEt_NSTAB:
            gv = (GV*)POPPTR(ss,ix);
            TOPPTR(nss,ix) = gv_dup(gv, param);
@@ -10577,7 +10578,12 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            i = POPINT(ss,ix);
            TOPINT(nss,ix) = i;
            ptr = POPPTR(ss,ix);
-           TOPPTR(nss,ix) = Perl_refcounted_he_dup(aTHX_ ptr, param);
+           if (ptr) {
+               HINTS_REFCNT_LOCK;
+               ((struct refcounted_he *)ptr)->refcounted_he_refcnt++;
+               HINTS_REFCNT_UNLOCK;
+           }
+           TOPPTR(nss,ix) = ptr;
            if (i & HINT_LOCALIZE_HH) {
                hv = (HV*)POPPTR(ss,ix);
                TOPPTR(nss,ix) = hv_dup_inc(hv, param);
@@ -10625,8 +10631,6 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
                    = pv_dup(old_state->re_state_bostr);
                new_state->re_state_reginput
                    = pv_dup(old_state->re_state_reginput);
-               new_state->re_state_regbol
-                   = pv_dup(old_state->re_state_regbol);
                new_state->re_state_regeol
                    = pv_dup(old_state->re_state_regeol);
                new_state->re_state_regstartp
@@ -10638,8 +10642,6 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
                new_state->re_state_reglastcloseparen
                    = any_dup(old_state->re_state_reglastcloseparen,
                              proto_perl);
-               new_state->re_state_regtill
-                   = pv_dup(old_state->re_state_regtill);
                /* XXX This just has to be broken. The old save_re_context
                   code did SAVEGENERICPV(PL_reg_start_tmp);
                   PL_reg_start_tmp is char **.
@@ -10653,14 +10655,6 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
                /* I assume that it only ever "worked" because no-one called
                   (pseudo)fork while the regexp engine had re-entered itself.
                */
-               new_state->re_state_reg_call_cc
-                   = any_dup(old_state->re_state_reg_call_cc, proto_perl);
-               new_state->re_state_reg_re
-                   = any_dup(old_state->re_state_reg_re, proto_perl);
-               new_state->re_state_reg_ganch
-                   = pv_dup(old_state->re_state_reg_ganch);
-               new_state->re_state_reg_sv
-                   = sv_dup(old_state->re_state_reg_sv, param);
 #ifdef PERL_OLD_COPY_ON_WRITE
                new_state->re_state_nrs
                    = sv_dup(old_state->re_state_nrs, param);
@@ -10681,6 +10675,22 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
 #endif
                break;
            }
+       case SAVEt_COP_WARNINGS:
+           {
+               void *optr = POPPTR(ss,ix);
+               TOPPTR(nss,ix) = ptr = any_dup(optr, proto_perl);
+               if (ptr != optr) {
+                   /* We duped something in the interpreter structure.  */
+                   ptr = POPPTR(ss,ix);
+                   TOPPTR(nss,ix) = DUP_WARNINGS((STRLEN*)ptr);
+               } else {
+                   /* I don't think that this happens, but it would mean that
+                      we (didn't) dup something shared.  */
+                   ptr = POPPTR(ss,ix);
+                   TOPPTR(nss,ix) = ptr;
+               }
+           }
+           break;
        default:
            Perl_croak(aTHX_ "panic: ss_dup inconsistency (%"IVdf")", (IV) i);
        }
@@ -10934,12 +10944,14 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_file, PL_compiling.cop_file);
 
     ptr_table_store(PL_ptr_table, &proto_perl->Icompiling, &PL_compiling);
-    if (!specialWARN(PL_compiling.cop_warnings))
-       PL_compiling.cop_warnings = sv_dup_inc(PL_compiling.cop_warnings, param);
+    PL_compiling.cop_warnings = DUP_WARNINGS(PL_compiling.cop_warnings);
     if (!specialCopIO(PL_compiling.cop_io))
        PL_compiling.cop_io = sv_dup_inc(PL_compiling.cop_io, param);
-    PL_compiling.cop_hints
-       = Perl_refcounted_he_dup(aTHX_ PL_compiling.cop_hints, param);
+    if (PL_compiling.cop_hints) {
+       HINTS_REFCNT_LOCK;
+       PL_compiling.cop_hints->refcounted_he_refcnt++;
+       HINTS_REFCNT_UNLOCK;
+    }
     PL_curcop          = (COP*)any_dup(proto_perl->Tcurcop, proto_perl);
 
     /* pseudo environmental stuff */