summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Ozdemir <aozdemir@hmc.edu>2018-08-02 00:25:07 -0700
committerWilliam Langford <wlangfor@gmail.com>2018-10-12 16:23:09 -0400
commit0c845aa291230cace495d06ac5465bd3ccb99319 (patch)
tree4ec04c81bca4d7f58016f2518d038e16f06c3d78
parent341a5fcab34a19e155810e281e550f17d17b809f (diff)
Bugfix: Math function checking
We had config machinery that determined which math functions are available in libc. If a c math function was missing on the host system, then the corresponding jq function would be removed from the source, enabling the build to proceed anyway. The detection machinery was broken in a subtle way, as was shown after glibc updated to 2.27, dropping the `pow10` function. This caused compilation to fail. The essential problem was that we detected whether a math function was available by compiling and linking a small program evaluating that function on constants. However, since gcc's optimization machinery has special knowledge of some math functions (e.g. `pow10`), it can optimize them away, even if they don't exist in the library and are not linkable. That is, the following example compiles and links against glibc 2.27, even though `pow10` has been removed: ``` int main () { printf("%f", pow10(0.5)); return 0; } ``` What?! On the other hand, this program does not link: ``` int main () { double f; printf("%f", &f); printf("%f", pow10(f)); return 0; } ``` In the first program the call to `pow10` can be optimized away as a constant expression. This requires GCC to know about `pow10` (which it does!), but it does not require `pow10` to be in the library (and actually linkable). The solution is to use autoconf's machinery for detecting function presence, instead of our own (buggy) machinery. This has the added benefit of simplifying the code. The bug was reported in issue #1659
-rw-r--r--config/m4/check-math-func.m49
-rw-r--r--configure.ac124
2 files changed, 69 insertions, 64 deletions
diff --git a/config/m4/check-math-func.m4 b/config/m4/check-math-func.m4
index ce632726..5677cede 100644
--- a/config/m4/check-math-func.m4
+++ b/config/m4/check-math-func.m4
@@ -1,4 +1,9 @@
-dnl AC_FIND_FUNC(func, arguments)
+dnl AC_CHECK_MATH_FUNC(func)
AC_DEFUN([AC_CHECK_MATH_FUNC], [
- AC_FIND_FUNC_NO_LIBS([$1], [m], [#include <math.h>], [$2])
+ AC_LANG(C)
+ AC_CHECK_LIB([m],[$1],[
+ eval "ac_tr_func=HAVE_[]upcase($1)"
+ AC_DEFINE_UNQUOTED($ac_tr_func)
+ ],[
+ ])
])
diff --git a/configure.ac b/configure.ac
index 9186d00d..280694ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -148,68 +148,68 @@ if test $enable_pthread_tls = yes; then
fi
dnl libm math.h functions
-AC_CHECK_MATH_FUNC(acos, [.5])
-AC_CHECK_MATH_FUNC(acosh, [.5])
-AC_CHECK_MATH_FUNC(asin, [.5])
-AC_CHECK_MATH_FUNC(asinh, [.5])
-AC_CHECK_MATH_FUNC(atan2, [.5,.5])
-AC_CHECK_MATH_FUNC(atan, [.5])
-AC_CHECK_MATH_FUNC(atanh, [.5])
-AC_CHECK_MATH_FUNC(cbrt, [.5])
-AC_CHECK_MATH_FUNC(ceil,[.5])
-AC_CHECK_MATH_FUNC(copysign,[.5,1.0])
-AC_CHECK_MATH_FUNC(cos, [.5])
-AC_CHECK_MATH_FUNC(cosh, [.5])
-AC_CHECK_MATH_FUNC(drem,[.5,1.0])
-AC_CHECK_MATH_FUNC(erf,[.5])
-AC_CHECK_MATH_FUNC(erfc,[.5])
-AC_CHECK_MATH_FUNC(exp10,[.5])
-AC_CHECK_MATH_FUNC(exp2, [.5])
-AC_CHECK_MATH_FUNC(exp, [.5])
-AC_CHECK_MATH_FUNC(expm1,[.5])
-AC_CHECK_MATH_FUNC(fabs,[.5])
-AC_CHECK_MATH_FUNC(fdim,[.5,1.0])
-AC_CHECK_MATH_FUNC(floor, [.5])
-AC_CHECK_MATH_FUNC(fma,[.5,1.0,1.5])
-AC_CHECK_MATH_FUNC(fmax,[.5,1.0])
-AC_CHECK_MATH_FUNC(fmin,[.5,1.0])
-AC_CHECK_MATH_FUNC(fmod,[.5,1.0])
-AC_FIND_FUNC([frexp], [m c], [#include <math.h>], [0, 0])
-AC_CHECK_MATH_FUNC(gamma,[.5])
-AC_CHECK_MATH_FUNC(hypot, [.5,.5])
-AC_CHECK_MATH_FUNC(j0, [.5])
-AC_CHECK_MATH_FUNC(j1, [.5])
-AC_CHECK_MATH_FUNC(jn, [1,.5])
-AC_CHECK_MATH_FUNC(ldexp,[.5,2])
-AC_CHECK_MATH_FUNC(lgamma,[.5])
-AC_CHECK_MATH_FUNC(log10, [.5])
-AC_CHECK_MATH_FUNC(log1p,[.5])
-AC_CHECK_MATH_FUNC(log2, [.5])
-AC_CHECK_MATH_FUNC(log, [.5])
-AC_CHECK_MATH_FUNC(logb,[.5])
-AC_CHECK_MATH_FUNC([modf], [m c], [#include <math.h>], [0, 0])
-AC_CHECK_MATH_FUNC([lgamma_r], [m c], [#include <math.h>], [0, 0])
-AC_CHECK_MATH_FUNC(nearbyint,[.5])
-AC_CHECK_MATH_FUNC(nextafter,[.5,1.0])
-AC_CHECK_MATH_FUNC(nexttoward,[.5,1.0])
-AC_CHECK_MATH_FUNC(pow10,[.5])
-AC_CHECK_MATH_FUNC(pow, [2,2])
-AC_CHECK_MATH_FUNC(remainder, [3,2])
-AC_CHECK_MATH_FUNC(rint,[.5])
-AC_CHECK_MATH_FUNC(round,[.5])
-AC_CHECK_MATH_FUNC(scalb,[.5,1.0])
-AC_CHECK_MATH_FUNC(scalbln,[.5,2])
-AC_CHECK_MATH_FUNC(significand,[.5])
-AC_CHECK_MATH_FUNC(sin, [.5])
-AC_CHECK_MATH_FUNC(sinh, [.5])
-AC_CHECK_MATH_FUNC(sqrt, [.5])
-AC_CHECK_MATH_FUNC(tan, [.5])
-AC_CHECK_MATH_FUNC(tanh, [.5])
-AC_CHECK_MATH_FUNC(tgamma, [.5])
-AC_CHECK_MATH_FUNC(trunc,[.5])
-AC_CHECK_MATH_FUNC(y0, [.5])
-AC_CHECK_MATH_FUNC(y1, [.5])
-AC_CHECK_MATH_FUNC(yn, [1,.5])
+AC_CHECK_MATH_FUNC(acos)
+AC_CHECK_MATH_FUNC(acosh)
+AC_CHECK_MATH_FUNC(asin)
+AC_CHECK_MATH_FUNC(asinh)
+AC_CHECK_MATH_FUNC(atan2)
+AC_CHECK_MATH_FUNC(atan)
+AC_CHECK_MATH_FUNC(atanh)
+AC_CHECK_MATH_FUNC(cbrt)
+AC_CHECK_MATH_FUNC(ceil)
+AC_CHECK_MATH_FUNC(copysign)
+AC_CHECK_MATH_FUNC(cos)
+AC_CHECK_MATH_FUNC(cosh)
+AC_CHECK_MATH_FUNC(drem)
+AC_CHECK_MATH_FUNC(erf)
+AC_CHECK_MATH_FUNC(erfc)
+AC_CHECK_MATH_FUNC(exp10)
+AC_CHECK_MATH_FUNC(exp2)
+AC_CHECK_MATH_FUNC(exp)
+AC_CHECK_MATH_FUNC(expm1)
+AC_CHECK_MATH_FUNC(fabs)
+AC_CHECK_MATH_FUNC(fdim)
+AC_CHECK_MATH_FUNC(floor)
+AC_CHECK_MATH_FUNC(fma)
+AC_CHECK_MATH_FUNC(fmax)
+AC_CHECK_MATH_FUNC(fmin)
+AC_CHECK_MATH_FUNC(fmod)
+AC_CHECK_MATH_FUNC(frexp)
+AC_CHECK_MATH_FUNC(gamma)
+AC_CHECK_MATH_FUNC(hypot)
+AC_CHECK_MATH_FUNC(j0)
+AC_CHECK_MATH_FUNC(j1)
+AC_CHECK_MATH_FUNC(jn)
+AC_CHECK_MATH_FUNC(ldexp)
+AC_CHECK_MATH_FUNC(lgamma)
+AC_CHECK_MATH_FUNC(log10)
+AC_CHECK_MATH_FUNC(log1p)
+AC_CHECK_MATH_FUNC(log2)
+AC_CHECK_MATH_FUNC(log)
+AC_CHECK_MATH_FUNC(logb)
+AC_CHECK_MATH_FUNC(modf)
+AC_CHECK_MATH_FUNC(lgamma_r)
+AC_CHECK_MATH_FUNC(nearbyint)
+AC_CHECK_MATH_FUNC(nextafter)
+AC_CHECK_MATH_FUNC(nexttoward)
+AC_CHECK_MATH_FUNC(pow10) # Not available with glibc version >= 2.27
+AC_CHECK_MATH_FUNC(pow)
+AC_CHECK_MATH_FUNC(remainder)
+AC_CHECK_MATH_FUNC(rint)
+AC_CHECK_MATH_FUNC(round)
+AC_CHECK_MATH_FUNC(scalb)
+AC_CHECK_MATH_FUNC(scalbln)
+AC_CHECK_MATH_FUNC(significand)
+AC_CHECK_MATH_FUNC(sin)
+AC_CHECK_MATH_FUNC(sinh)
+AC_CHECK_MATH_FUNC(sqrt)
+AC_CHECK_MATH_FUNC(tan)
+AC_CHECK_MATH_FUNC(tanh)
+AC_CHECK_MATH_FUNC(tgamma)
+AC_CHECK_MATH_FUNC(trunc)
+AC_CHECK_MATH_FUNC(y0)
+AC_CHECK_MATH_FUNC(y1)
+AC_CHECK_MATH_FUNC(yn)
dnl Thread local storage
have___thread=no