In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/261d007a5e77381a4a921bbdfc9adbe51c1c2964?hp=c5e6a3c74b2fe93aae700ce59ef0ad8c70ad1bd6>
- Log ----------------------------------------------------------------- commit 261d007a5e77381a4a921bbdfc9adbe51c1c2964 Author: Jarkko Hietaniemi <[email protected]> Date: Tue Nov 11 18:36:57 2014 -0500 Special case exp(1) for ppc64-linux. M t/op/sprintf2.t commit 2804f8c19e636bbf6736960a6d921c3fc5f81063 Author: Jarkko Hietaniemi <[email protected]> Date: Tue Nov 11 18:27:51 2014 -0500 Revert "sisyphus thinks the test value is simply wrong here." This reverts commit 5399a05dbb94d8e0c2a0ea2b588ff80ad23f2093. (sisyphus thinks the bug is actually in ppc64 linux exp()) M t/op/sprintf2.t commit 2f52d58da6fe67fb710f470965ffef38c2f32d9c Author: Jarkko Hietaniemi <[email protected]> Date: Tue Nov 11 18:14:40 2014 -0500 If long double math functions do not work, drop uselongdouble. This moves a earlier version of the test from the freebsd hints to Configure, thus stopping also any other platforms that have lacking longdouble implementations. The test is not comprehensive (not all long double interfaces are tested), but it covers some of the most common ones. The earlier test was actually wrong, so no FreeBSD could ever pass. Sorry, FreeBSD. M Configure M hints/freebsd.sh ----------------------------------------------------------------------- Summary of changes: Configure | 263 +++++++++++++++++++++++++++++++------------------------ hints/freebsd.sh | 32 ------- t/op/sprintf2.t | 13 ++- 3 files changed, 159 insertions(+), 149 deletions(-) diff --git a/Configure b/Configure index 2a9e25b..d092c74 100755 --- a/Configure +++ b/Configure @@ -7029,6 +7029,153 @@ case "$longdblkind" in esac $rm_try +: Check print/scan long double stuff +echo " " + +if $test X"$d_longdbl" = X"$define"; then + +echo "Checking how to print long doubles..." >&4 + +if $test X"$sPRIfldbl" = X -a X"$doublesize" = X"$longdblsize"; then + $cat >try.c <<'EOCP' +#include <sys/types.h> +#include <stdio.h> +int main() { + double d = 123.456; + printf("%.3f\n", d); +} +EOCP + set try + if eval $compile; then + yyy=`$run ./try` + case "$yyy" in + 123.456) + sPRIfldbl='"f"'; sPRIgldbl='"g"'; sPRIeldbl='"e"'; + sPRIFUldbl='"F"'; sPRIGUldbl='"G"'; sPRIEUldbl='"E"'; + echo "We will use %f." + ;; + esac + fi +fi + +if $test X"$sPRIfldbl" = X; then + $cat >try.c <<'EOCP' +#include <sys/types.h> +#include <stdio.h> +int main() { + long double d = 123.456; + printf("%.3Lf\n", d); +} +EOCP + set try + if eval $compile; then + yyy=`$run ./try` + case "$yyy" in + 123.456) + sPRIfldbl='"Lf"'; sPRIgldbl='"Lg"'; sPRIeldbl='"Le"'; + sPRIFUldbl='"LF"'; sPRIGUldbl='"LG"'; sPRIEUldbl='"LE"'; + echo "We will use %Lf." + ;; + esac + fi +fi + +if $test X"$sPRIfldbl" = X; then + $cat >try.c <<'EOCP' +#include <sys/types.h> +#include <stdio.h> +int main() { + long double d = 123.456; + printf("%.3llf\n", d); +} +EOCP + set try + if eval $compile; then + yyy=`$run ./try` + case "$yyy" in + 123.456) + sPRIfldbl='"llf"'; sPRIgldbl='"llg"'; sPRIeldbl='"lle"'; + sPRIFUldbl='"llF"'; sPRIGUldbl='"llG"'; sPRIEUldbl='"llE"'; + echo "We will use %llf." + ;; + esac + fi +fi + +if $test X"$sPRIfldbl" = X; then + $cat >try.c <<'EOCP' +#include <sys/types.h> +#include <stdio.h> +int main() { + long double d = 123.456; + printf("%.3lf\n", d); +} +EOCP + set try + if eval $compile; then + yyy=`$run ./try` + case "$yyy" in + 123.456) + sPRIfldbl='"lf"'; sPRIgldbl='"lg"'; sPRIeldbl='"le"'; + sPRIFUldbl='"lF"'; sPRIGUldbl='"lG"'; sPRIEUldbl='"lE"'; + echo "We will use %lf." + ;; + esac + fi +fi + +if $test X"$sPRIfldbl" = X; then + echo "Cannot figure out how to print long doubles." >&4 +else + sSCNfldbl=$sPRIfldbl # expect consistency +fi + +$rm_try + +fi # d_longdbl + +case "$sPRIfldbl" in +'') d_PRIfldbl="$undef"; d_PRIgldbl="$undef"; d_PRIeldbl="$undef"; + d_PRIFUldbl="$undef"; d_PRIGUldbl="$undef"; d_PRIEUldbl="$undef"; + d_SCNfldbl="$undef"; + ;; +*) d_PRIfldbl="$define"; d_PRIgldbl="$define"; d_PRIeldbl="$define"; + d_PRIFUldbl="$define"; d_PRIGUldbl="$define"; d_PRIEUldbl="$define"; + d_SCNfldbl="$define"; + ;; +esac + +: Before committing on uselongdouble, see whether that looks sane. +if $test "$uselongdouble" = "$define"; then + message="" + echo " " + echo "Checking if your long double math functions work right..." >&4 + $cat > try.c <<EOF +#include <math.h> +#include <stdio.h> +int main() { + printf("%"$sPRIgldbl"\n", sqrtl(logl(expl(cosl(sinl(0.0L))))+powl(2.0L, 3.0L))); +} +EOF + case "$osname:$gccversion" in + aix:) saveccflags="$ccflags" + ccflags="$ccflags -qlongdouble" ;; # to avoid core dump + esac + set try + if eval $compile_ok; then + yyy=`$run ./try` + fi + case "$yyy" in + 3) echo "Your long double math functions are working correctly." >&4 ;; + *) echo "Your long double math functions are broken, not using long doubles." >&4 + uselongdouble=$undef + ;; + esac + $rm_try + case "$osname:$gccversion" in + aix:) ccflags="$saveccflags" ;; # restore + esac +fi : determine the architecture name echo " " @@ -10079,122 +10226,6 @@ esac set qgcvt d_qgcvt eval $inlibc -: Check print/scan long double stuff -echo " " - -if $test X"$d_longdbl" = X"$define"; then - -echo "Checking how to print long doubles..." >&4 - -if $test X"$sPRIfldbl" = X -a X"$doublesize" = X"$longdblsize"; then - $cat >try.c <<'EOCP' -#include <sys/types.h> -#include <stdio.h> -int main() { - double d = 123.456; - printf("%.3f\n", d); -} -EOCP - set try - if eval $compile; then - yyy=`$run ./try` - case "$yyy" in - 123.456) - sPRIfldbl='"f"'; sPRIgldbl='"g"'; sPRIeldbl='"e"'; - sPRIFUldbl='"F"'; sPRIGUldbl='"G"'; sPRIEUldbl='"E"'; - echo "We will use %f." - ;; - esac - fi -fi - -if $test X"$sPRIfldbl" = X; then - $cat >try.c <<'EOCP' -#include <sys/types.h> -#include <stdio.h> -int main() { - long double d = 123.456; - printf("%.3Lf\n", d); -} -EOCP - set try - if eval $compile; then - yyy=`$run ./try` - case "$yyy" in - 123.456) - sPRIfldbl='"Lf"'; sPRIgldbl='"Lg"'; sPRIeldbl='"Le"'; - sPRIFUldbl='"LF"'; sPRIGUldbl='"LG"'; sPRIEUldbl='"LE"'; - echo "We will use %Lf." - ;; - esac - fi -fi - -if $test X"$sPRIfldbl" = X; then - $cat >try.c <<'EOCP' -#include <sys/types.h> -#include <stdio.h> -int main() { - long double d = 123.456; - printf("%.3llf\n", d); -} -EOCP - set try - if eval $compile; then - yyy=`$run ./try` - case "$yyy" in - 123.456) - sPRIfldbl='"llf"'; sPRIgldbl='"llg"'; sPRIeldbl='"lle"'; - sPRIFUldbl='"llF"'; sPRIGUldbl='"llG"'; sPRIEUldbl='"llE"'; - echo "We will use %llf." - ;; - esac - fi -fi - -if $test X"$sPRIfldbl" = X; then - $cat >try.c <<'EOCP' -#include <sys/types.h> -#include <stdio.h> -int main() { - long double d = 123.456; - printf("%.3lf\n", d); -} -EOCP - set try - if eval $compile; then - yyy=`$run ./try` - case "$yyy" in - 123.456) - sPRIfldbl='"lf"'; sPRIgldbl='"lg"'; sPRIeldbl='"le"'; - sPRIFUldbl='"lF"'; sPRIGUldbl='"lG"'; sPRIEUldbl='"lE"'; - echo "We will use %lf." - ;; - esac - fi -fi - -if $test X"$sPRIfldbl" = X; then - echo "Cannot figure out how to print long doubles." >&4 -else - sSCNfldbl=$sPRIfldbl # expect consistency -fi - -$rm_try - -fi # d_longdbl - -case "$sPRIfldbl" in -'') d_PRIfldbl="$undef"; d_PRIgldbl="$undef"; d_PRIeldbl="$undef"; - d_PRIFUldbl="$undef"; d_PRIGUldbl="$undef"; d_PRIEUldbl="$undef"; - d_SCNfldbl="$undef"; - ;; -*) d_PRIfldbl="$define"; d_PRIgldbl="$define"; d_PRIeldbl="$define"; - d_PRIFUldbl="$define"; d_PRIGUldbl="$define"; d_PRIEUldbl="$define"; - d_SCNfldbl="$define"; - ;; -esac - : Check how to convert floats to strings. if test "X$d_Gconvert" = X; then diff --git a/hints/freebsd.sh b/hints/freebsd.sh index 673dc4b..8d436a1 100644 --- a/hints/freebsd.sh +++ b/hints/freebsd.sh @@ -310,35 +310,3 @@ esac # of FreeBSD. d_printf_format_null='undef' -$cat > UU/uselongdouble.cbu <<'EOCBU' -# This script UU/uselongdouble.cbu will get 'called-back' by Configure -# after it has prompted the user for whether to use long doubles. - -# Some FreeBSD releases apparently don't really have the C99 long double -# versions of math functions. If this seems to be the case, disable -# uselongdouble. -# -# XXX This sanity check logic could be move to Configure. -case "$uselongdouble" in -define) - echo "Checking if your long double math functions work right..." >&4 - cat > ldblm$$.c <<EOF -#include <math.h> -#include <stdio.h> -int main() { - printf("%Lg\n", sqrtl(logl(expl(1.0L))+powl(2.0L, 3.0L))+cosl(sinl(1.0L))); -} -EOF - $cc -o ldblm$$ ldblm$$.c -lm - case `test -x ldblm$$ && ./ldblm$$` in - 4) echo "Your long double math functions are working correctly." >&4 ;; - *) - echo "Your long double math functions are broken, disabling uselongdouble." >&4 - uselongdouble=$undef - ;; - esac - rm -f ldblm$$.c ldblm$$ - ;; -esac - -EOCBU diff --git a/t/op/sprintf2.t b/t/op/sprintf2.t index 8008a46..526608e 100644 --- a/t/op/sprintf2.t +++ b/t/op/sprintf2.t @@ -12,6 +12,8 @@ BEGIN { eval { my $q = pack "q", 0 }; my $Q = $@ eq ''; +my $doubledouble; + # %a and %A depend on the floating point config # This totally doesn't test non-IEEE-754 float formats. my @hexfloat; @@ -189,6 +191,7 @@ if ($Config{nvsize} == 8 && (pack("F", 0.1) =~ /^\x9A\x99{5}\x59\xBC/ || # LE pack("F", 0.1) =~ /\xBC\x59\x99{5}\x9A$/) # BE ) { + $doubledouble = 1; @hexfloat = ( [ '%a', '0', '0x0p+0' ], [ '%a', '1', '0x1p+0' ], @@ -202,7 +205,7 @@ if ($Config{nvsize} == 8 && [ '%a', '0.1', '0x1.999999999999999999999999998p-4' ], [ '%a', '1/7', '0x1.249249249249249249249249248p-3' ], [ '%a', 'sqrt(2)', '0x1.6a09e667f3bcc908b2fb1366ea8p+0' ], - [ '%a', 'exp(1)', '0x1.5bf0a8b1457695355fb8ac40520p+1' ], + [ '%a', 'exp(1)', '0x1.5bf0a8b1457695355fb8ac404e8p+1' ], [ '%a', '2**-10', '0x1p-10' ], [ '%a', '2**10', '0x1p+10' ], [ '%a', '1e-09', '0x1.12e0be826d694b2e62d01511f14p-30' ], @@ -565,11 +568,19 @@ $o::count = 0; () = sprintf "%.1s", $o; is $o::count, '1', 'sprinf %.1s overload count'; +my $ppc64_linux = $Config{archname} =~ /^ppc64-linux/; + for my $t (@hexfloat) { my ($format, $arg, $expected) = @$t; $arg = eval $arg; my $result = sprintf($format, $arg); my $ok = $result eq $expected; + if ($doubledouble && $ppc64_linux && $arg =~ /^2.71828/) { + # ppc64-linux has buggy exp(1). + local $::TODO = "$Config{archname} exp(1)"; + ok($ok, "'$format' '$arg' -> '$result' cf '$expected'"); + next; + } unless ($ok) { # It seems that there can be difference in the last bits: # [perl #122578] -- Perl5 Master Repository
