On 03/05/19 11:21 +0000, Szabolcs Nagy wrote:
On 03/05/2019 12:16, Jonathan Wakely wrote:
On 03/05/19 09:23 +0000, Szabolcs Nagy wrote:
On 01/05/2019 01:09, Jonathan Wakely wrote:
The current generic implementation of __complex_proj used when cproj is
not available calculates the wrong projection, giving a different result
than given by C99's cproj.
When C99 cproj is not available but isinf and copysign are, use those to
give correct results for float, double and long double. Otherwise, and
for other specializations of std::complex, just use a generic version
that returns its argument, and so doesn't support infinities.
We might want to consider adding additional overloads of __complex_proj
to support extended types such as _Float64x, _Float128 etc.
PR libstdc++/61761
* include/std/complex (__complex_proj): Return parameter unchanged.
[_GLIBCXX_USE_C99_COMPLEX] (__complex_proj): Change overloads for
floating-point types to take std::complex arguments.
[_GLIBCXX_USE_C99_MATH_TR1] (__complex_proj): Add overloads for
floating-point types.
* testsuite/26_numerics/complex/proj.cc: New test.
Tested powerpc64le-linux, powerpc-aix7.2.0.0, x86_64-freebsd11.2,
committed to trunk.
fails on aarch64-none-elf (newlib) with
FAIL: 26_numerics/complex/proj.cc (test for excess errors)
Excess errors:
/work/b/src/gcc/libstdc++-v3/testsuite/26_numerics/complex/proj.cc:32: error:
'copysign' is not a member of 'std'; did you mean 'copy_n'?
/work/b/src/gcc/libstdc++-v3/testsuite/26_numerics/complex/proj.cc:32: error:
'copysign' is not a member of 'std'; did you mean 'copy_n'?
/work/b/src/gcc/libstdc++-v3/testsuite/26_numerics/complex/proj.cc:34: error:
'copysign' is not a member of 'std'; did you mean 'copy_n'?
/work/b/src/gcc/libstdc++-v3/testsuite/26_numerics/complex/proj.cc:34: error:
'copysign' is not a member of 'std'; did you mean 'copy_n'?
i assume std::copysign should be visible in <complex> via <cmath>
It should, but only for C++11, and this needs to work for C++98 too. I
missed that problem.
but cmath does not have it.
Hmm, which file in the source tree does the include/cmath symlink in
the build tree point to?
/work/b/build-aarch64-none-elf/obj/gcc2/aarch64-none-elf/libstdc++-v3$ ls -l
include/cmath
lrwxrwxrwx 1 szabolcs szabolcs 51 May 1 18:06 include/cmath ->
/work/b/src/gcc/libstdc++-v3/include/c_global/cmath
Oh, I see the problem. <complex> and <cmath> both guard use of
copysign by _GLIBCXX_USE_C99_MATH_TR1 but the test just uses it
unconditionally.
Does the attached patch work?
diff --git a/libstdc++-v3/testsuite/26_numerics/complex/proj.cc b/libstdc++-v3/testsuite/26_numerics/complex/proj.cc
index b70ca4c58e9..e4e086936d1 100644
--- a/libstdc++-v3/testsuite/26_numerics/complex/proj.cc
+++ b/libstdc++-v3/testsuite/26_numerics/complex/proj.cc
@@ -21,6 +21,17 @@
#include <limits>
#include <testsuite_hooks.h>
+namespace test
+{
+#ifdef _GLIBCXX_USE_C99_MATH_TR1
+ using std::copysign;
+#else
+ bool copysign(float f) { return __builtin_copysignf(f); }
+ bool copysign(double f) { return __builtin_copysign(f); }
+ bool copysign(long double f) { return __builtin_copysignl(f); }
+#endif
+}
+
template<typename T>
bool eq(const std::complex<T>& x, const std::complex<T>& y)
{
@@ -28,9 +39,9 @@ bool eq(const std::complex<T>& x, const std::complex<T>& y)
bool nan_imags = std::isnan(x.imag()) && std::isnan(y.imag());
bool sign_reals
- = std::copysign(T(1), x.real()) == std::copysign(T(1), y.real());
+ = test::copysign(T(1), x.real()) == test::copysign(T(1), y.real());
bool sign_imags
- = std::copysign(T(1), x.imag()) == std::copysign(T(1), y.imag());
+ = test::copysign(T(1), x.imag()) == test::copysign(T(1), y.imag());
return ((x.real() == y.real() && sign_reals) || nan_reals)
&& ((x.imag() == y.imag() && sign_imags) || nan_imags);