[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