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