Package: perl
Version: 5.24.1~rc3-3
Severity: normal
Tags: patch upstream
User: reproducible-bui...@lists.alioth.debian.org
Usertags: randomness
X-Debbugs-Cc: reproducible-b...@lists.alioth.debian.org

The Configure test for long double implementation details probes the
contents of "long double inf", and they get stored in the Config module:

 % perl -V:longdblinfbytes
 longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 
0x40, 0x00, 0x00, 0x00, 0x00, 0x00';

Some of these bytes are currently essentially random and vary between
builds on at least amd64 and i386, because their long doubles are only
80-bit and the remaining six bytes stay uninitialized.

The relevant Configure probe tries to initialize these bytes, but has
several bugs that defeat the purpose. Patch attached.

The randomness seems to only have started to show with GCC-6 for
one reason or another; the bytes are zeroed out on at least GCC-5.
-- 
Niko Tyni   nt...@debian.org
>From 97eaa8936166129d88f778562e587a9151ce15b7 Mon Sep 17 00:00:00 2001
From: Niko Tyni <nt...@debian.org>
Date: Fri, 18 Nov 2016 18:36:34 +0200
Subject: [PATCH] Configure: fix garbage filtering with 80-bit long doubles

The test had several problems that resulted in the excess
bytes not getting zeroed out. This caused random contents in
$Config{longdblinfbytes}, observed on Debian with GCC 6.2.0 (but not
5.4.1).
---
 Configure | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/Configure b/Configure
index 6a3d617..f561a87 100755
--- a/Configure
+++ b/Configure
@@ -20661,8 +20661,8 @@ $cat >try.c <<EOP
 #define DOUBLESIZE $doublesize
 #$d_longdbl HAS_LONG_DOUBLE
 #ifdef HAS_LONG_DOUBLE
-#define LONGDBLSIZE $longdblsize
-#define LONGDBLKIND $longdblkind
+#define LONG_DOUBLESIZE $longdblsize
+#define LONG_DOUBLEKIND $longdblkind
 #endif
 #$i_math I_MATH
 #ifdef I_MATH
@@ -20699,16 +20699,14 @@ int main(int argc, char *argv[]) {
 #ifdef HAS_LONG_DOUBLE
    long double ldinf = (long double)exp(1e9);
    long double ldnan = (long double)sqrt(-1.0);
-#endif
-  if (argc == 2) {
-    switch (argv[1][0]) {
-    case '1': bytes(&dinf, sizeof(dinf)); break;
-    case '2': bytes(&dnan, sizeof(dnan)); break;
-#ifdef HAS_LONG_DOUBLE
 # if LONG_DOUBLEKIND == 3 || LONG_DOUBLEKIND == 4
 /* the 80-bit long doubles might have garbage in their excess bytes */
     memset((char *)&ldinf + 10, '\0', LONG_DOUBLESIZE - 10);
 # endif
+  if (argc == 2) {
+    switch (argv[1][0]) {
+    case '1': bytes(&dinf, sizeof(dinf)); break;
+    case '2': bytes(&dnan, sizeof(dnan)); break;
     case '3': bytes(&ldinf, sizeof(ldinf)); break;
     case '4': bytes(&ldnan, sizeof(ldnan)); break;
 #endif
-- 
2.10.2

Reply via email to