]> Savannah Git Hosting - gnulib.git/commitdiff
float, math: Fix 'int' to 'long double' conversion on Linux/SPARC64.
authorBruno Haible <bruno@clisp.org>
Fri, 30 Sep 2011 19:07:43 +0000 (21:07 +0200)
committerBruno Haible <bruno@clisp.org>
Fri, 30 Sep 2011 19:07:43 +0000 (21:07 +0200)
* m4/float_h.m4 (gl_FLOAT_H): Test conversion from 'int' to
'long double'. Set REPLACE_ITOLD.
* lib/float.in.h (_Qp_itoq, _gl_float_fix_itold): New declarations.
* lib/math.in.h (_Qp_itoq, _gl_math_fix_itold): New declarations.
* lib/itold.c: New file.
* modules/float (Files): Add lib/itold.c.
(configure.ac): When REPLACE_ITOLD is 1, arrange to compile itold.c.
(Makefile.am): Substitute REPLACE_ITOLD.
* modules/math (Depends-on): Add float.
(Makefile.am): Substitute REPLACE_ITOLD.
* doc/posix-headers/float.texi: Mention problem on Linux/SPARC64.
* doc/posix-headers/math.texi: Likewise.
* doc/posix-functions/logl.texi: Likewise.

ChangeLog
doc/posix-functions/logl.texi
doc/posix-headers/float.texi
doc/posix-headers/math.texi
lib/float.in.h
lib/math.in.h
m4/float_h.m4
modules/float
modules/math

index f4858d51364be698fce798446a2614e07e1f4d8e..2c13f787821aeb7fd5171106fb6d44e46057263c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2011-09-30  Bruno Haible  <bruno@clisp.org>
+
+       float, math: Fix 'int' to 'long double' conversion on Linux/SPARC64.
+       * m4/float_h.m4 (gl_FLOAT_H): Test conversion from 'int' to
+       'long double'. Set REPLACE_ITOLD.
+       * lib/float.in.h (_Qp_itoq, _gl_float_fix_itold): New declarations.
+       * lib/math.in.h (_Qp_itoq, _gl_math_fix_itold): New declarations.
+       * lib/itold.c: New file.
+       * modules/float (Files): Add lib/itold.c.
+       (configure.ac): When REPLACE_ITOLD is 1, arrange to compile itold.c.
+       (Makefile.am): Substitute REPLACE_ITOLD.
+       * modules/math (Depends-on): Add float.
+       (Makefile.am): Substitute REPLACE_ITOLD.
+       * doc/posix-headers/float.texi: Mention problem on Linux/SPARC64.
+       * doc/posix-headers/math.texi: Likewise.
+       * doc/posix-functions/logl.texi: Likewise.
+
 2011-09-30  Bruno Haible  <bruno@clisp.org>
 
        nonblocking tests: Fix test failure on Linux/SPARC (32-bit and 64-bit).
index bdaf6ec2834cf061e7ce536a1f1def89b881039f..93fc86115a651a20a5a1d7b3772bdceaf6facb81 100644 (file)
@@ -17,6 +17,9 @@ MSVC 9.
 @item
 This function is not declared on some platforms:
 MacOS X 10.3.
+@item
+This function returns wrong results on some platforms:
+glibc 2.7 on Linux/SPARC64.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index f2e0e9b2dbd418f002a1ed38066c72ad68458c4a..e6a78d72e44d58ef4560cb1d43a4cabd4f95bd03 100644 (file)
@@ -8,6 +8,10 @@ Gnulib module: float
 Portability problems fixed by Gnulib:
 @itemize
 @item
+The conversion from @code{int} to @code{long double} in incorrect on some
+platforms:
+glibc 2.7 on Linux/SPARC64.
+@item
 The values of @code{LDBL_*} macros are incorrect on some platforms:
 On OpenBSD 4.0, MirBSD 10, and BeOS, they are the same as the values of the
 @code{DBL_*} macros, although @samp{long double} is a larger type than
index d0de2bae43b8a4587271954969ce7a307ca5fa66..12d547ce0487ea87752912f7fc9b306bef5be48b 100644 (file)
@@ -7,6 +7,11 @@ Gnulib module: math
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+The conversion from @code{int} to @code{long double} in incorrect on some
+platforms:
+glibc 2.7 on Linux/SPARC64.
+
 @item
 The macro @code{NAN} is not defined on some platforms:
 OpenBSD 4.0, AIX 5.1, IRIX 6.5, OSF/1 5.1.
index b132035d83001c48c1cb1b352fabe3292df120b9..d5b22584f0a270d2ba2c99c94874632d7851e048 100644 (file)
@@ -173,5 +173,16 @@ extern const union gl_long_double_union gl_LDBL_MAX;
 # endif
 #endif
 
+#if @REPLACE_ITOLD@
+/* Pull in a function that fixes the 'int' to 'long double' conversion
+   of glibc 2.7.  */
+extern
+# ifdef __cplusplus
+"C"
+# endif
+void _Qp_itoq (long double *, int);
+static void (*_gl_float_fix_itold) (long double *, int) = _Qp_itoq;
+#endif
+
 #endif /* _@GUARD_PREFIX@_FLOAT_H */
 #endif /* _@GUARD_PREFIX@_FLOAT_H */
index afbc9cbd26fa3b7dff6e8ac9449ef225ee3774f0..f82d03c2fd66b696debaf585c48c9ac997095da0 100644 (file)
@@ -67,6 +67,14 @@ _GL_WARN_ON_USE (rpl_ ## func ## l, #func " is unportable - "       \
    : rpl_ ## func ## l (value))
 
 
+#if @REPLACE_ITOLD@
+/* Pull in a function that fixes the 'int' to 'long double' conversion
+   of glibc 2.7.  */
+_GL_EXTERN_C void _Qp_itoq (long double *, int);
+static void (*_gl_math_fix_itold) (long double *, int) = _Qp_itoq;
+#endif
+
+
 /* POSIX allows platforms that don't support NAN.  But all major
    machines in the past 15 years have supported something close to
    IEEE NaN, so we define this unconditionally.  We also must define
index da11c0e2d80e2343907f848bfe6350551330587a..0420e06921acb03813d659df61952b93233fca99 100644 (file)
@@ -1,4 +1,4 @@
-# float_h.m4 serial 8
+# float_h.m4 serial 9
 dnl Copyright (C) 2007, 2009-2011 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -48,9 +48,51 @@ changequote([,])dnl
       fi
       ;;
   esac
+
+  dnl Test against glibc-2.7 Linux/SPARC64 bug.
+  REPLACE_ITOLD=0
+  AC_CACHE_CHECK([whether conversion from 'int' to 'long double' works],
+    [gl_cv_func_itold_works],
+    [
+      AC_RUN_IFELSE(
+        [AC_LANG_SOURCE([[
+int i = -1;
+volatile long double ld;
+int main ()
+{
+  ld += i * 1.0L;
+  if (ld > 0)
+    return 1;
+  return 0;
+}]])],
+        [gl_cv_func_itold_works=yes],
+        [gl_cv_func_itold_works=no],
+        [case "$host" in
+           sparc*-*-linux*)
+             AC_EGREP_CPP([yes],
+               [#if defined __LP64__ || defined __arch64__
+                yes
+                #endif],
+               [gl_cv_func_itold_works="guessing no"],
+               [gl_cv_func_itold_works="guessing yes"])
+             ;;
+           *) gl_cv_func_itold_works="guessing yes" ;;
+         esac
+        ])
+    ])
+  case "$gl_cv_func_itold_works" in
+    *no)
+      REPLACE_ITOLD=1
+      dnl We add the workaround to <float.h> but also to <math.h>,
+      dnl to increase the chances that the fix function gets pulled in.
+      FLOAT_H=float.h
+      ;;
+  esac
+
   if test -n "$FLOAT_H"; then
     gl_NEXT_HEADERS([float.h])
   fi
   AC_SUBST([FLOAT_H])
   AM_CONDITIONAL([GL_GENERATE_FLOAT_H], [test -n "$FLOAT_H"])
+  AC_SUBST([REPLACE_ITOLD])
 ])
index 2a79750037b82e0ca0cbf8a6cc712575578c0562..a24e80d05cc6e81fcd84927adab8056434048c9f 100644 (file)
@@ -4,6 +4,7 @@ A correct <float.h>.
 Files:
 lib/float.in.h
 lib/float.c
+lib/itold.c
 m4/float_h.m4
 
 Depends-on:
@@ -14,6 +15,9 @@ gl_FLOAT_H
 if test $REPLACE_FLOAT_LDBL = 1; then
   AC_LIBOBJ([float])
 fi
+if test $REPLACE_ITOLD = 1; then
+  AC_LIBOBJ([itold])
+fi
 
 Makefile.am:
 BUILT_SOURCES += $(FLOAT_H)
@@ -29,6 +33,7 @@ float.h: float.in.h $(top_builddir)/config.status
              -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
              -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
              -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \
+             -e 's|@''REPLACE_ITOLD''@|$(REPLACE_ITOLD)|g' \
              < $(srcdir)/float.in.h; \
        } > $@-t && \
        mv $@-t $@
index bc3d34c35569349774bf19edeb86871ee2658697..8062d2da527431763ab6d64c2187869775a87ecd 100644 (file)
@@ -10,6 +10,7 @@ include_next
 snippet/arg-nonnull
 snippet/c++defs
 snippet/warn-on-use
+float
 
 configure.ac:
 gl_MATH_H
@@ -107,6 +108,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
              -e 's|@''REPLACE_ISFINITE''@|$(REPLACE_ISFINITE)|g' \
              -e 's|@''REPLACE_ISINF''@|$(REPLACE_ISINF)|g' \
              -e 's|@''REPLACE_ISNAN''@|$(REPLACE_ISNAN)|g' \
+             -e 's|@''REPLACE_ITOLD''@|$(REPLACE_ITOLD)|g' \
              -e 's|@''REPLACE_LDEXPL''@|$(REPLACE_LDEXPL)|g' \
              -e 's|@''REPLACE_NAN''@|$(REPLACE_NAN)|g' \
              -e 's|@''REPLACE_ROUND''@|$(REPLACE_ROUND)|g' \