Message ID | or7e2k3o1z.fsf@livre.home |
---|---|
State | New |
Headers | show |
Series | Define HAVE_ for math long double functions declared in vxworks headers | expand |
On 25/12/19 03:40 -0300, Alexandre Oliva wrote: > >When cross-building for vxworks, test for declarations of long double >functions in math.h. We don't normally test for these functions when >cross compiling, because link tests don't work, or ever really, but >not defining them as available causes replacements to be defined in >ways that may cause duplicate definition linker errors if the units >defining both the replacement and the actual implementation are >brought in because of other symbols. > >Tested on trunk by checking configure results of libstdc++-v3 for an >affected target, and also building natively on x86_64-linux-gnu. Also >tested for various cross configurations far more thoroughly on trees not >matching trunk so closely. I'm checking this in. > > >libstdc++-v3/ > * crossconfig.m4 (GLIBCXX_CROSSCONFIG) [*-vxworks*]: Define > long double functions as available if declared by math.h. > (GLIBCXX_CHECK_MATH_DECL, GLIBCXX_CHECK_MATH_DECLS): New. > * configure: Rebuild. >--- > libstdc++-v3/configure | 1104 +++++++++++++++++++++++++++++++++++++++++++ > libstdc++-v3/crossconfig.m4 | 62 ++ > 2 files changed, 1166 insertions(+) > >diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure >[omitted] >diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4 >index 5e24889..2a0cb04 100644 >--- a/libstdc++-v3/crossconfig.m4 >+++ b/libstdc++-v3/crossconfig.m4 >@@ -291,9 +291,71 @@ case "${host}" in > AC_DEFINE(HAVE_SQRTF) > AC_DEFINE(HAVE_TANF) > AC_DEFINE(HAVE_TANHF) >+ >+dnl # Different versions and execution modes implement different >+dnl # subsets of these functions. Instead of hard-coding, test for C >+dnl # declarations in headers. The C primitives could be defined as >+dnl # macros, in which case the tests might fail, and we might have to >+dnl # switch to more elaborate tests. >+ GLIBCXX_CHECK_MATH_DECLS([ >+ acosl asinl atan2l atanl ceill cosl coshl expl fabsl floorl fmodl >+ frexpl ldexpl log10l logl modfl powl sinl sinhl sqrtl tanl tanhl]) >+dnl # sincosl is the only one missing here, compared with the *l >+dnl # functions in the list guarded by >+dnl # long_double_math_on_this_cpu in configure.ac, right after >+dnl # the expansion of the present macro. > ;; > *) > AC_MSG_ERROR([No support for this host/target combination.]) > ;; > esac > ]) >+ >+ >+dnl >+dnl Check to see if the (math function) argument passed is >+dnl declared when using the c compiler >+dnl >+dnl Define HAVE_CARGF etc if "cargf" is declared >+dnl >+dnl argument 1 is name of function to check >+dnl >+dnl ASSUMES argument is a math function >+dnl >+dnl GLIBCXX_CHECK_MATH_DECL >+AC_DEFUN([GLIBCXX_CHECK_MATH_DECL], [ >+ AC_CACHE_CHECK([for $1 declaration], >+ [glibcxx_cv_func_$1_use], [ >+ AC_LANG_SAVE >+ AC_LANG_C >+ AC_TRY_COMPILE([ >+#include <math.h> >+#ifdef HAVE_IEEEFP_H >+# include <ieeefp.h> >+#endif >+], [ >+ void (*f)(void) = (void (*)(void))$1; I wondered whether using ($1) here instead of just $1 would give any benefit. It would mean that function-like macros are ignored. Maybe it would be better to just do #undef $1 before the test, so that all macros are ignored. That would match the actual usage, as <cmath> does a #undef for each function.
On Jan 3, 2020, Jonathan Wakely <jwakely@redhat.com> wrote: >> +#include <math.h> >> +#ifdef HAVE_IEEEFP_H >> +# include <ieeefp.h> >> +#endif >> +], [ >> + void (*f)(void) = (void (*)(void))$1; > I wondered whether using ($1) here instead of just $1 would give any > benefit. It would mean that function-like macros are ignored. The lack of parentheses after a functional macro name is enough to avoid its use as a macro. However, the test I used wouldn't avoid aliasing macros, such as #define foo bar, and it would pass even if the name was defined as an object rather than as a function. I've also come up with a way to test, during C compilation, that $1 is a function rather than anything else. If the test was in C++, we could presumably use template type resolution and static asserts to recognize function-typed expressions, though a possibility of overloading could make it fall apart. In theory the closer we are to the environment in which the test result will be used, the more likely we are to get the desired result, but I'm a little concerned about switching to a C++ test, precisely because of the math.h header that we might or might not override, and of unexpected overloading that system math headers might offer if they are C++-ready, which could then get us wrong test results. Any thoughts on this possibility? Meanwhile, here's what I'm testing now... It's supposed to be a strict incremental improvement, unless $1-&$1 unexpectedly compiles for some case I couldn't think of. Ok to install? reject macros in math decl check From: Alexandre Oliva <oliva@adacore.com> The C++ headers #undef the functions we are testing for, just in case they're implemented as macros. Do that as well, so as to reject macros of the form #define foo bar, where bar is the actual implementation, since those wouldn't work in C++ after the #undef. While at that, tighten the test so that it doesn't take objects of pointer types as if they were functions. for libstdc++-v3/ChangeLog * crossconfig.m4 (GLIBCXX_CHECK_MATH_DECL): Reject macros and data objects. * configure: Rebuild. --- configure | 66 +++++++++++++++++++++++++++++++++++++------------------- crossconfig.m4 | 11 ++++++++- 2 files changed, 54 insertions(+), 23 deletions(-) diff --git libstdc++-v3/crossconfig.m4 libstdc++-v3/crossconfig.m4 index 2a0cb04..221b59d 100644 --- libstdc++-v3/crossconfig.m4 +++ libstdc++-v3/crossconfig.m4 @@ -322,6 +322,14 @@ dnl argument 1 is name of function to check dnl dnl ASSUMES argument is a math function dnl +dnl Test for $1 - &$1: it's well-formed iff $1 names a function, +dnl because $1's type decays to that of &$1. +dnl For any object type, even arrays and void*, types won't match. +dnl +dnl Undefine $1, so that we don't accept an alias macro, e.g. +dnl say define foo bar, when bar is the function. Our C++ headers +dnl undefine math function names, so such a macro wouldn't do. +dnl dnl GLIBCXX_CHECK_MATH_DECL AC_DEFUN([GLIBCXX_CHECK_MATH_DECL], [ AC_CACHE_CHECK([for $1 declaration], @@ -333,8 +341,9 @@ AC_DEFUN([GLIBCXX_CHECK_MATH_DECL], [ #ifdef HAVE_IEEEFP_H # include <ieeefp.h> #endif +#undef $1 ], [ - void (*f)(void) = (void (*)(void))$1; + (void)($1 - &$1); ], [glibcxx_cv_func_$1_use=yes ], [glibcxx_cv_func_$1_use=no])]) if test "x$glibcxx_cv_func_$1_use" = xyes; then
On 21/01/20 21:50 -0300, Alexandre Oliva wrote: >On Jan 3, 2020, Jonathan Wakely <jwakely@redhat.com> wrote: > >>> +#include <math.h> >>> +#ifdef HAVE_IEEEFP_H >>> +# include <ieeefp.h> >>> +#endif >>> +], [ >>> + void (*f)(void) = (void (*)(void))$1; > >> I wondered whether using ($1) here instead of just $1 would give any >> benefit. It would mean that function-like macros are ignored. > >The lack of parentheses after a functional macro name is enough to avoid >its use as a macro. However, the test I used wouldn't avoid aliasing >macros, such as #define foo bar, and it would pass even if the name was >defined as an object rather than as a function. > >I've also come up with a way to test, during C compilation, that $1 is a >function rather than anything else. > >If the test was in C++, we could presumably use template type resolution >and static asserts to recognize function-typed expressions, though a >possibility of overloading could make it fall apart. > >In theory the closer we are to the environment in which the test result >will be used, the more likely we are to get the desired result, but I'm >a little concerned about switching to a C++ test, precisely because of >the math.h header that we might or might not override, and of unexpected >overloading that system math headers might offer if they are C++-ready, >which could then get us wrong test results. Any thoughts on this >possibility? > > >Meanwhile, here's what I'm testing now... >It's supposed to be a strict incremental improvement, unless $1-&$1 >unexpectedly compiles for some case I couldn't think of. Isn't allowing arithmetic on function pointers a GNU extension? It gets diagnosed with -pedantic. I think just adding the #undef to what you had originally is the best version.
On Dez 25 2019, Alexandre Oliva wrote: > +dnl # Different versions and execution modes implement different > +dnl # subsets of these functions. Instead of hard-coding, test for C > +dnl # declarations in headers. The C primitives could be defined as > +dnl # macros, in which case the tests might fail, and we might have to > +dnl # switch to more elaborate tests. > + GLIBCXX_CHECK_MATH_DECLS([ > + acosl asinl atan2l atanl ceill cosl coshl expl fabsl floorl fmodl > + frexpl ldexpl log10l logl modfl powl sinl sinhl sqrtl tanl tanhl]) Why can't you use AC_CHECK_DECLS? Andreas.
On Jan 22, 2020, Jonathan Wakely <jwakely@redhat.com> wrote: > Isn't allowing arithmetic on function pointers a GNU extension? Does that matter? This test is only supposed to be compiled by GCC. > I think just adding the #undef to what you had originally is the best > version. 'k, thanks, will adjust, test, post and install.
On Jan 22, 2020, Andreas Schwab <schwab@suse.de> wrote: > On Dez 25 2019, Alexandre Oliva wrote: >> +dnl # Different versions and execution modes implement different >> +dnl # subsets of these functions. Instead of hard-coding, test for C >> +dnl # declarations in headers. The C primitives could be defined as >> +dnl # macros, in which case the tests might fail, and we might have to >> +dnl # switch to more elaborate tests. >> + GLIBCXX_CHECK_MATH_DECLS([ >> + acosl asinl atan2l atanl ceill cosl coshl expl fabsl floorl fmodl >> + frexpl ldexpl log10l logl modfl powl sinl sinhl sqrtl tanl tanhl]) > Why can't you use AC_CHECK_DECLS? IIRC it doesn't #undef, for one, but that's only relevant now. I can't really recall whether using it even occurred to me, but a good reason not to use it is that it defines HAVE_FUNCTION_DECL rather than setting glibcxx_cv_func_$1_use={yes,no} and (through AC_CHECK_FUNCS) HAVE_$1, like the preexisting macros in linkage.m4 we're substituting for did before. We could probably use AC_CHECK_DECL underneath, placing the #undef in the INCLUDES argument. Indeed, it looks like the GLIBCXX_CHECK_*_DECL_? macros in linkage.m4 could use AC_CHECK_DECL as well. Does anyone know of any reason for them not to use AC_CHECK_DECL instead of open-coding the tests? And then, shouldn't they also #undef the functions they're testing for? Or should neither? It doesn't feel right to add the #undef to the new but otherwise identical compile test, just because it skips the link test.
On 23/01/20 00:20 -0300, Alexandre Oliva wrote: >On Jan 22, 2020, Jonathan Wakely <jwakely@redhat.com> wrote: > >> Isn't allowing arithmetic on function pointers a GNU extension? > >Does that matter? This test is only supposed to be compiled by GCC. Maybe if somebody was crazy enough to build GCC with -pedantic-errors? >> I think just adding the #undef to what you had originally is the best >> version. > >'k, thanks, will adjust, test, post and install. Thanks.
On Jan 23, 2020, Jonathan Wakely <jwakely@redhat.com> wrote: > On 23/01/20 00:20 -0300, Alexandre Oliva wrote: >> On Jan 22, 2020, Jonathan Wakely <jwakely@redhat.com> wrote: >> >>> Isn't allowing arithmetic on function pointers a GNU extension? >> >> Does that matter? This test is only supposed to be compiled by GCC. > Maybe if somebody was crazy enough to build GCC with -pedantic-errors? In TFLAGS while configuring libstdc++... Yeah, that would fail. >>> I think just adding the #undef to what you had originally is the best >>> version. >> >> 'k, thanks, will adjust, test, post and install. > Thanks. Here's the revised version I'm about to install... Regstrapped on x86_64-linux-gnu along with other patches, also retested on an affected target. reject macros in math decl check From: Alexandre Oliva <oliva@adacore.com> The C++ headers #undef the functions we are testing for, just in case they're implemented as macros, so do that in the cross math decl tests as well. for libstdc++-v3/ChangeLog * crossconfig.m4 (GLIBCXX_CHECK_MATH_DECL): Reject macros. * configure: Rebuild. --- libstdc++-v3/configure | 22 ++++++++++++++++++++++ libstdc++-v3/crossconfig.m4 | 1 + 2 files changed, 23 insertions(+) diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4 index 2a0cb04..fe18288 100644 --- a/libstdc++-v3/crossconfig.m4 +++ b/libstdc++-v3/crossconfig.m4 @@ -333,6 +333,7 @@ AC_DEFUN([GLIBCXX_CHECK_MATH_DECL], [ #ifdef HAVE_IEEEFP_H # include <ieeefp.h> #endif +#undef $1 ], [ void (*f)(void) = (void (*)(void))$1; ], [glibcxx_cv_func_$1_use=yes
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure [omitted] diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4 index 5e24889..2a0cb04 100644 --- a/libstdc++-v3/crossconfig.m4 +++ b/libstdc++-v3/crossconfig.m4 @@ -291,9 +291,71 @@ case "${host}" in AC_DEFINE(HAVE_SQRTF) AC_DEFINE(HAVE_TANF) AC_DEFINE(HAVE_TANHF) + +dnl # Different versions and execution modes implement different +dnl # subsets of these functions. Instead of hard-coding, test for C +dnl # declarations in headers. The C primitives could be defined as +dnl # macros, in which case the tests might fail, and we might have to +dnl # switch to more elaborate tests. + GLIBCXX_CHECK_MATH_DECLS([ + acosl asinl atan2l atanl ceill cosl coshl expl fabsl floorl fmodl + frexpl ldexpl log10l logl modfl powl sinl sinhl sqrtl tanl tanhl]) +dnl # sincosl is the only one missing here, compared with the *l +dnl # functions in the list guarded by +dnl # long_double_math_on_this_cpu in configure.ac, right after +dnl # the expansion of the present macro. ;; *) AC_MSG_ERROR([No support for this host/target combination.]) ;; esac ]) + + +dnl +dnl Check to see if the (math function) argument passed is +dnl declared when using the c compiler +dnl +dnl Define HAVE_CARGF etc if "cargf" is declared +dnl +dnl argument 1 is name of function to check +dnl +dnl ASSUMES argument is a math function +dnl +dnl GLIBCXX_CHECK_MATH_DECL +AC_DEFUN([GLIBCXX_CHECK_MATH_DECL], [ + AC_CACHE_CHECK([for $1 declaration], + [glibcxx_cv_func_$1_use], [ + AC_LANG_SAVE + AC_LANG_C + AC_TRY_COMPILE([ +#include <math.h> +#ifdef HAVE_IEEEFP_H +# include <ieeefp.h> +#endif +], [ + void (*f)(void) = (void (*)(void))$1; +], [glibcxx_cv_func_$1_use=yes +], [glibcxx_cv_func_$1_use=no])]) + if test "x$glibcxx_cv_func_$1_use" = xyes; then + AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1])) + fi +]) + +dnl +dnl Check to see whether multiple math functions are +dnl declared when using the c compiler +dnl +dnl Define HAVE_CARGF HAVE_POWL etc if "cargf" and "powl" +dnl are declared +dnl +dnl argument 1 is a word list naming function to check +dnl +dnl ASSUMES arguments are math functions +dnl +dnl GLIBCXX_CHECK_MATH_DECLS +AC_DEFUN([GLIBCXX_CHECK_MATH_DECLS], [ + m4_foreach_w([glibcxx_func], [$1], [ + GLIBCXX_CHECK_MATH_DECL(glibcxx_func) + ]) +])