[m-rev.] for review: Work around isinf() link error on Solaris.
Peter Wang
novalazy at gmail.com
Wed May 29 16:50:19 AEST 2013
On Wed, 29 May 2013 16:13:26 +1000 (EST), Julien Fischer <jfischer at opturion.com> wrote:
>
> Hi Peter,
>
> On Wed, 29 May 2013, Peter Wang wrote:
>
> > On Solaris, isinf() is detected by configure but we pass -fno-builtin
> > for global registers on x86/x86-64, and that causes an undefined
> > reference to `isinf' when linking.
>
> Or is it because the C compiler is not in C99 mode?
No, the compiler links fine in hlc.gc.pregen.
> (Either way, that behaviour seems pretty broken.)
I wouldn't expect anything less.
> > runtime/mercury_float.c:
> > Don't use `isinf' or `isinff' on when __sun is defined.
> >
> > Add a better `isinf' fallback using finite().
>
> IIRC, finite() is a BSD'ism. (C99 provides the equivalent isfinite.)
> You probably shouldn't be assuming that any of them are present and
> should certainly be checking that they are before attempting to use
> them.
Oh, all right.
Actually, I was hoping to get away with it, but some (older) MSVCs
might be missing both.
> > diff --git a/runtime/mercury_float.c b/runtime/mercury_float.c
> > index 2a31a2e..8088ae9 100644
> > --- a/runtime/mercury_float.c
> > +++ b/runtime/mercury_float.c
> > @@ -119,11 +119,16 @@ MR_is_nan(MR_Float Flt)
> > MR_bool
> > MR_is_inf(MR_Float Flt)
> > {
> > -#if defined(MR_USE_SINGLE_PREC_FLOAT) && defined(MR_HAVE_ISINFF)
> > + /*
> > + ** On Solaris, isinf() is detected by configure but we pass -fno-builtin
> > + ** for global registers on x86/x86-64, and that causes an undefined
> > + ** reference to `isinf' when linking.
> > + */
> > +#if defined(MR_USE_SINGLE_PREC_FLOAT) && defined(MR_HAVE_ISINFF) && !defined(__sun)
> > return isinff(Flt);
> > -#elif defined(MR_HAVE_ISINF)
> > +#elif defined(MR_HAVE_ISINF) && !defined(__sun)
> > return isinf(Flt);
> > #else
> > - return (Flt == Flt / 2.0 && Flt != 0.0);
> > + return !finite(Flt) && (Flt == Flt);
> > #endif
>
> I suggest adding
>
> #if defined(__sun)
> #define MR_SOLARIS)
> #endif
>
> in the runtime and using MR_SOLARIS instead of __sun directly.
Done.
[PATCH] Work around `isinf' link error on Solaris.
On Solaris, `isinf' is detected by configure but we pass -fno-builtin
for global registers on x86/x86-64, and that causes an undefined
reference to `isinf' when linking.
configure.ac:
runtime/mercury_conf.h.in:
Check for existence of `finite'.
runtime/mercury_conf_param.h:
Define MR_SOLARIS if appropriate.
runtime/mercury_float.c:
Don't use `isinf' or `isinff' on Solaris.
Add a better `MR_is_inf' fallback using `finite'.
diff --git a/configure.ac b/configure.ac
index 7022638..7b3a4d5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4800,6 +4800,7 @@ MERCURY_CHECK_FOR_IEEE_FUNC(isnan)
MERCURY_CHECK_FOR_IEEE_FUNC(isnanf)
MERCURY_CHECK_FOR_IEEE_FUNC(isinf)
MERCURY_CHECK_FOR_IEEE_FUNC(isinff)
+MERCURY_CHECK_FOR_IEEE_FUNC(finite)
#-----------------------------------------------------------------------------#
#
diff --git a/runtime/mercury_conf.h.in b/runtime/mercury_conf.h.in
index fbc1edc..b336dad 100644
--- a/runtime/mercury_conf.h.in
+++ b/runtime/mercury_conf.h.in
@@ -274,6 +274,7 @@
** MR_HAVE_ISNANF we have the isnanf() function.
** MR_HAVE_ISINF we have the isinf() function.
** MR_HAVE_ISINFF we have the isinff() function.
+** MR_HAVE_FINITE we have the finite() function.
** MR_HAVE_OPENDIR we have the opendir() function.
** MR_HAVE_READDIR we have the readdir() function.
** MR_HAVE_CLOSEDIR we have the closedir() function.
@@ -344,6 +345,7 @@
#undef MR_HAVE_ISNANF
#undef MR_HAVE_ISINF
#undef MR_HAVE_ISINFF
+#undef MR_HAVE_FINITE
#undef MR_HAVE_OPENDIR
#undef MR_HAVE_READDIR
#undef MR_HAVE_CLOSEDIR
diff --git a/runtime/mercury_conf_param.h b/runtime/mercury_conf_param.h
index b52c4b4..9f4c14a 100644
--- a/runtime/mercury_conf_param.h
+++ b/runtime/mercury_conf_param.h
@@ -100,6 +100,16 @@
/*---------------------------------------------------------------------------*/
/*
+** Solaris/SunOS specific.
+*/
+
+#if defined(__sun)
+ #define MR_SOLARIS
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+/*
** C compilers.
*/
diff --git a/runtime/mercury_float.c b/runtime/mercury_float.c
index 2a31a2e..798cc30 100644
--- a/runtime/mercury_float.c
+++ b/runtime/mercury_float.c
@@ -119,10 +119,17 @@ MR_is_nan(MR_Float Flt)
MR_bool
MR_is_inf(MR_Float Flt)
{
-#if defined(MR_USE_SINGLE_PREC_FLOAT) && defined(MR_HAVE_ISINFF)
+ /*
+ ** On Solaris, isinf() is detected by configure but we pass -fno-builtin
+ ** for global registers on x86/x86-64, and that causes an undefined
+ ** reference to `isinf' when linking. finite() works though.
+ */
+#if defined(MR_USE_SINGLE_PREC_FLOAT) && defined(MR_HAVE_ISINFF) && !defined(MR_SOLARIS)
return isinff(Flt);
-#elif defined(MR_HAVE_ISINF)
+#elif defined(MR_HAVE_ISINF) && !defined(MR_SOLARIS)
return isinf(Flt);
+#elif defined(MR_HAVE_FINITE)
+ return !finite(Flt) && (Flt == Flt);
#else
return (Flt == Flt / 2.0 && Flt != 0.0);
#endif
More information about the reviews
mailing list