On 03/11/16 15:11 +0100, Rainer Orth wrote:
Fortunately, this is all easily fixed by wrapping the affected templates
in a new macro. That's what this patch does. The new libstdc++
acinclude.m4 test may well need wording changes in comments etc. and can
perhaps be shortened a bit, bit it worked for me.
See below.
The fixincludes part passes make check.
The patch has been regtested (C++ only) on
* Solaris 11.2 SRU 13.6 (i.e. without both overloads and templates in
<iso/math_c99.h>),
* Solaris 11.3 SRU 3.6 (i.e. with overloads only), and
* Solaris 12 Build 110 (i.e. with both overloads and templates, and the
_GLIBCXX_USE_C99_MATH #undef's)
* Linux/x86_64
I've checked that __CORRECT_ISO_CPP11_MATH_H_PROTO[12] were defined in
config.h as expected, and there were no testsuite regressions. On the
contrary, a couple of tests that before showed up as UNSUPPORTED due to
the _GLIBCXX_USE_C99_MATH* #undef's now PASS as they should.
Ok for mainline now, and for backports to the gcc-6 and gcc-5 branches
after some soak time?
The change is OK in principle, but I'd prefer more meaningful names
for the macros ...
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2181,7 +2181,8 @@ AC_DEFUN([GLIBCXX_CHECK_STDIO_PROTO], [
])
dnl
-dnl Check whether required C++11 overloads are present in <math.h>.
+dnl Check whether required C++11 overloads and templates are present
+dnl in <math.h>.
The standard doesn't actually require templates to be used here, it
only requires "sufficient additional overloads" so that integral
arguments work. We happen to do that with templates, and apparently so
do the Solaris headers, but other implementations are possible. So a
more accurate description would be:
dnl Check whether required C++11 overloads for FP and integral types
dnl are present in <math.h>.
And rather than PROTO1 and PROTO2 the macros could be called PROTO_FP
for the overloads for FP types, and PROTO_INT (or just PROTO_I) for
the overloads for integral types (which happen to be templates in our
header).
+ # Solaris 12 Build 90, Solaris 11.3 SRU 5.6, and Solaris 10 Patch
+ # 11996[67]-02 introduced the C++11 <math.h> templates.
+ AC_MSG_CHECKING([for C++11 <math.h> templates])
+ AC_CACHE_VAL(glibcxx_cv_math11_template, [
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [#include <math.h>
+ namespace std {
+ struct __true_type { };
+ struct __false_type { };
We don't need these structs.
+ template<typename _Tp>
+ struct __is_integer
+ {
+ enum { __value = 0 };
+ typedef __false_type __type;
+ };
We don't need a definition for the primary template, this will work:
template<typename _Tp>
struct __is_integer;
+ template<>
+ struct __is_integer<int>
+ {
+ enum { __value = 1 };
+ typedef __true_type __type;
The __type typedef is not needed here, just __value.
+ };
+ }
+ namespace __gnu_cxx {
+ template<bool, typename>
+ struct __enable_if
+ { };
Again, no need to define the primary template:
template<bool, typename>
struct __enable_if;
+ template<typename _Tp>
+ struct __enable_if<true, _Tp>
+ { typedef _Tp __type; };
+ }
The suggestions above would make it shorter, while still remaining
accurate to what the real code in the header does. It could be reduced
even further without altering the meaning for the purposes of this
test:
+ namespace std {
+ template<typename _Tp>
+ constexpr typename __gnu_cxx::__enable_if
+ <__is_integer<_Tp>::__value, double>::__type
+ log2(_Tp __x)
+ { return __builtin_log2(__x); }
template<typename _Tp>
struct __enable_if_int;
template<>
struct __enable_if_int<int>
{ typedef double __type; };
template<typename _Tp>
constexpr typename __enable_if_int<_Tp>::__type
log2(_Tp __x)
{ return __builtin_log2(__x); }
I don't mind whether you go with this or just remove the unnecessary
structs, typedef and primary template bodies. Either is OK.
+ }
+ int
+ main (void)
+ {
+ int i = 1000;
+ return std::log2(i);
+ }