In perl.git, the branch blead has been updated

<https://perl5.git.perl.org/perl.git/commitdiff/ad9b9a4926e4b0d348c048937df69e382f7e6d27?hp=59592778585db09866cbb37a7ab04eefc07b4df4>

- Log -----------------------------------------------------------------
commit ad9b9a4926e4b0d348c048937df69e382f7e6d27
Author: Tomasz Konojacki <m...@xenu.pl>
Date:   Wed Nov 21 09:26:31 2018 +0100

    optimize IV -> UV conversions
    
    This commit replaces all instances of code that looks like this:
    
      uv = (iv == IV_MIN) ? (UV)iv : (UV)(-iv)
    
    with simpler and more optimal:
    
      uv = -(UV)iv
    
    While -iv indeed results in an undefined behaviour when iv == IV_MIN,
    -(UV)iv is perfectly well defined and does the right thing.
    
    C standard guarantees that the result of (UV)iv (for negative iv) is
    equal to iv + UV_MAX + 1 (see 6.3.1.3, paragraph 2 in C11). It also
    guarantees that the result of -uv is UV_MAX - uv + 1 (6.2.5,
    paragraph 9).
    
    That means that the result of -(UV)iv is UV_MAX - (iv + UV_MAX + 1) + 1
    which is equal to -iv for *all* possible negative values of iv.
    
    [perl #133677]

commit 9ba9a28aaea66bad2de041880a2c4210a911dda6
Author: David Mitchell <da...@iabyn.com>
Date:   Wed Nov 21 12:09:45 2018 +0000

    S_hv_delete_common(): avoid undefined behaviour
    
    ASAN -fsanitize-undefined was tripping on the second of these two lines:
    
        svp = AvARRAY(isa);
        end = svp + AvFILLp(isa)+1;
    
    In the case where svp is NULL and AvFILLp(isa) is -1, the first addition
    is undefined behaviour. Add the 1 first, so that it becomes
    svp + (-1+1), which is safe.

-----------------------------------------------------------------------

Summary of changes:
 hv.c     |  2 +-
 pp.c     | 18 +++++++++---------
 pp_hot.c |  4 ++--
 sv.c     |  4 ++--
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/hv.c b/hv.c
index d3d02d1046..fc90a5146b 100644
--- a/hv.c
+++ b/hv.c
@@ -1295,7 +1295,7 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char 
*key, STRLEN klen,
                             SV **svp, **end;
                         strip_magic:
                             svp = AvARRAY(isa);
-                            end = svp + AvFILLp(isa)+1;
+                            end = svp + (AvFILLp(isa)+1);
                             while (svp < end) {
                                 if (*svp)
                                     mg_free_type(*svp, PERL_MAGIC_isaelem);
diff --git a/pp.c b/pp.c
index 6d432acd31..880f266081 100644
--- a/pp.c
+++ b/pp.c
@@ -1319,7 +1319,7 @@ PP(pp_multiply)
                    auvok = TRUE; /* effectively it's a UV now */
                } else {
                     /* abs, auvok == false records sign */
-                   alow = (aiv == IV_MIN) ? (UV)aiv : (UV)(-aiv);
+                   alow = -(UV)aiv;
                }
            }
            if (buvok) {
@@ -1331,7 +1331,7 @@ PP(pp_multiply)
                    buvok = TRUE; /* effectively it's a UV now */
                } else {
                     /* abs, buvok == false records sign */
-                   blow = (biv == IV_MIN) ? (UV)biv : (UV)(-biv);
+                   blow = -(UV)biv;
                }
            }
 
@@ -1462,7 +1462,7 @@ PP(pp_divide)
                     right_non_neg = TRUE; /* effectively it's a UV now */
                 }
                else {
-                    right = (biv == IV_MIN) ? (UV)biv : (UV)(-biv);
+                    right = -(UV)biv;
                 }
             }
             /* historically undef()/0 gives a "Use of uninitialized value"
@@ -1483,7 +1483,7 @@ PP(pp_divide)
                     left_non_neg = TRUE; /* effectively it's a UV now */
                 }
                else {
-                    left = (aiv == IV_MIN) ? (UV)aiv : (UV)(-aiv);
+                    left = -(UV)aiv;
                 }
             }
 
@@ -1566,7 +1566,7 @@ PP(pp_modulo)
                     right = biv;
                     right_neg = FALSE; /* effectively it's a UV now */
                 } else {
-                    right = (biv == IV_MIN) ? (UV)biv : (UV)(-biv);
+                    right = -(UV)biv;
                 }
             }
         }
@@ -1596,7 +1596,7 @@ PP(pp_modulo)
                         left = aiv;
                         left_neg = FALSE; /* effectively it's a UV now */
                     } else {
-                        left = (aiv == IV_MIN) ? (UV)aiv : (UV)(-aiv);
+                        left = -(UV)aiv;
                     }
                 }
         }
@@ -1893,8 +1893,8 @@ PP(pp_subtract)
                    if (aiv >= 0) {
                        auv = aiv;
                        auvok = 1;      /* Now acting as a sign flag.  */
-                   } else { /* 2s complement assumption for IV_MIN */
-                       auv = (aiv == IV_MIN) ? (UV)aiv : (UV)-aiv;
+                   } else {
+                       auv = -(UV)aiv;
                    }
                }
                a_valid = 1;
@@ -1914,7 +1914,7 @@ PP(pp_subtract)
                    buv = biv;
                    buvok = 1;
                } else
-                    buv = (biv == IV_MIN) ? (UV)biv : (UV)-biv;
+                    buv = -(UV)biv;
            }
            /* ?uvok if value is >= 0. basically, flagged as UV if it's +ve,
               else "IV" now, independent of how it came in.
diff --git a/pp_hot.c b/pp_hot.c
index dc02612042..ace5f0208b 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1521,7 +1521,7 @@ PP(pp_add)
                        auv = aiv;
                        auvok = 1;      /* Now acting as a sign flag.  */
                    } else {
-                       auv = (aiv == IV_MIN) ? (UV)aiv : (UV)(-aiv);
+                       auv = -(UV)aiv;
                    }
                }
                a_valid = 1;
@@ -1541,7 +1541,7 @@ PP(pp_add)
                    buv = biv;
                    buvok = 1;
                } else
-                    buv = (biv == IV_MIN) ? (UV)biv : (UV)(-biv);
+                    buv = -(UV)biv;
            }
            /* ?uvok if value is >= 0. basically, flagged as UV if it's +ve,
               else "IV" now, independent of how it came in.
diff --git a/sv.c b/sv.c
index 983646f335..b10f205033 100644
--- a/sv.c
+++ b/sv.c
@@ -2868,7 +2868,7 @@ S_uiv_2buf(char *const buf, const IV iv, UV uv, const int 
is_uv, char **const pe
        uv = iv;
        sign = 0;
     } else {
-        uv = (iv == IV_MIN) ? (UV)iv : (UV)(-iv);
+        uv = -(UV)iv;
        sign = 1;
     }
     do {
@@ -12596,7 +12596,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char 
*const pat, const STRLEN p
                             esignbuf[esignlen++] = plus;
                     }
                     else {
-                        uv = (iv == IV_MIN) ? (UV)iv : (UV)(-iv);
+                        uv = -(UV)iv;
                         esignbuf[esignlen++] = '-';
                     }
                 }

-- 
Perl5 Master Repository

Reply via email to