changeset 12726:d6da6e5f2f62

math: add portability warnings for classification macros For interfaces which are defined to exist only as macros, implement the proper magic needed to warn if the corresponding gnulib module was not in use. This solution avoids promoting arguments unnecessarily, to allow reuse in case gnulib ever implements fpclassify, since fpclassify(1e-40f) is different than fpclassify(1e-40). * modules/math (Depends-on): Add warn-on-use. (Makefile.am): Provide new substitutions. * m4/math_h.m4 (gl_MATH_H): Require inline. * lib/math.in.h (_GL_WARN_REAL_FLOATING_DECL) (_GL_WARN_REAL_FLOATING_IMPL): New helper macros. (isfinite, isinf, isnan, signbit) [GNULIB_POSIXCHECK]: Use them to implement warnings. Signed-off-by: Eric Blake <ebb9@byu.net>
author Eric Blake <ebb9@byu.net>
date Thu, 31 Dec 2009 13:48:15 -0700
parents b6a49a4ae7d7
children fd5b0bf2a8e9
files ChangeLog lib/math.in.h m4/math_h.m4 modules/math
diffstat 4 files changed, 67 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2010-01-11  Eric Blake  <ebb9@byu.net>
 
+	math: add portability warnings for classification macros
+	* modules/math (Depends-on): Add warn-on-use.
+	(Makefile.am): Provide new substitutions.
+	* m4/math_h.m4 (gl_MATH_H): Require inline.
+	* lib/math.in.h (_GL_WARN_REAL_FLOATING_DECL)
+	(_GL_WARN_REAL_FLOATING_IMPL): New helper macros.
+	(isfinite, isinf, isnan, signbit) [GNULIB_POSIXCHECK]: Use them to
+	implement warnings.
+
 	unistd: warn on use of environ without module
 	* modules/unistd (Depends-on): Add warn-on-use.
 	(Makefile.am): Provide new substitutions.
--- a/lib/math.in.h
+++ b/lib/math.in.h
@@ -32,6 +32,37 @@
 
 /* The definition of _GL_ARG_NONNULL is copied here.  */
 
+/* Helper macros to define a portability warning for the
+   classification macro FUNC called with VALUE.  POSIX declares the
+   classification macros with an argument of real-floating (that is,
+   one of float, double, or long double).  */
+#define _GL_WARN_REAL_FLOATING_DECL(func) \
+static inline int                                                   \
+rpl_ ## func ## f (float f)                                         \
+{                                                                   \
+  return func (f);                                                  \
+}                                                                   \
+static inline int                                                   \
+rpl_ ## func ## d (double d)                                        \
+{                                                                   \
+  return func (d);                                                  \
+}                                                                   \
+static inline int                                                   \
+rpl_ ## func ## l (long double l)                                   \
+{                                                                   \
+  return func (l);                                                  \
+}                                                                   \
+_GL_WARN_ON_USE (rpl_ ## func ## f, #func " is unportable - "       \
+                 "use gnulib module " #func " for portability");    \
+_GL_WARN_ON_USE (rpl_ ## func ## d, #func " is unportable - "       \
+                 "use gnulib module " #func " for portability");    \
+_GL_WARN_ON_USE (rpl_ ## func ## l, #func " is unportable - "       \
+                 "use gnulib module " #func " for portability")
+#define _GL_WARN_REAL_FLOATING_IMPL(func, value) \
+  (sizeof (value) == sizeof (float) ? rpl_ ## func ## f (value)     \
+   : sizeof (value) == sizeof (double) ? rpl_ ## func ## d (value)  \
+   : rpl_ ## func ## l (value))
+
 
 #ifdef __cplusplus
 extern "C" {
@@ -386,7 +417,11 @@
     gl_isfinitef (x))
 # endif
 #elif defined GNULIB_POSIXCHECK
-  /* How to override a macro?  */
+# if defined isfinite
+_GL_WARN_REAL_FLOATING_DECL (isfinite);
+#  undef isfinite
+#  define isfinite(x) _GL_WARN_REAL_FLOATING_IMPL (isfinite, x)
+# endif
 #endif
 
 
@@ -402,7 +437,11 @@
     gl_isinff (x))
 # endif
 #elif defined GNULIB_POSIXCHECK
-  /* How to override a macro?  */
+# if defined isinf
+_GL_WARN_REAL_FLOATING_DECL (isinf);
+#  undef isinf
+#  define isinf(x) _GL_WARN_REAL_FLOATING_IMPL (isinf, x)
+# endif
 #endif
 
 
@@ -501,7 +540,11 @@
     gl_isnan_f (x))
 # endif
 #elif defined GNULIB_POSIXCHECK
-  /* How to override a macro?  */
+# if defined isnan
+_GL_WARN_REAL_FLOATING_DECL (isnan);
+#  undef isnan
+#  define isnan(x) _GL_WARN_REAL_FLOATING_IMPL (isnan, x)
+# endif
 #endif
 
 
@@ -557,7 +600,11 @@
     gl_signbitf (x))
 # endif
 #elif defined GNULIB_POSIXCHECK
-  /* How to override a macro?  */
+# if defined signbit
+_GL_WARN_REAL_FLOATING_DECL (signbit);
+#  undef signbit
+#  define signbit(x) _GL_WARN_REAL_FLOATING_IMPL (signbit, x)
+# endif
 #endif
 
 
--- a/m4/math_h.m4
+++ b/m4/math_h.m4
@@ -1,4 +1,4 @@
-# math_h.m4 serial 14
+# math_h.m4 serial 15
 dnl Copyright (C) 2007-2010 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,6 +8,8 @@
 [
   AC_REQUIRE([gl_MATH_H_DEFAULTS])
   gl_CHECK_NEXT_HEADERS([math.h])
+  AC_REQUIRE([AC_C_INLINE])
+
   AC_CACHE_CHECK([whether NAN macro works], [gl_cv_header_math_nan_works],
     [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <math.h>]],
       [[/* Solaris 10 has a broken definition of NAN.  Other platforms
--- a/modules/math
+++ b/modules/math
@@ -6,9 +6,10 @@
 m4/math_h.m4
 
 Depends-on:
+arg-nonnull
 include_next
 link-warning
-arg-nonnull
+warn-on-use
 
 configure.ac:
 gl_MATH_H
@@ -18,7 +19,7 @@
 
 # We need the following in order to create <math.h> when the system
 # doesn't have one that works with the given compiler.
-math.h: math.in.h $(LINK_WARNING_H) $(ARG_NONNULL_H)
+math.h: math.in.h $(LINK_WARNING_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H)
 	$(AM_V_GEN)rm -f $@-t $@ && \
 	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
 	  sed -e 's|@''INCLUDE_NEXT_AS_FIRST_DIRECTIVE''@|$(INCLUDE_NEXT_AS_FIRST_DIRECTIVE)|g' \
@@ -81,6 +82,7 @@
 	      -e 's|@''REPLACE_TRUNCL''@|$(REPLACE_TRUNCL)|g' \
 	      -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
 	      < $(srcdir)/math.in.h; \
 	} > $@-t && \
 	mv $@-t $@