diff mbox

[libstdc++,testsuite] XFAIL tests relying on long double-to-string conversions on broken newlib

Message ID 584EAC3A.3070408@foss.arm.com
State New
Headers show

Commit Message

Kyrill Tkachov Dec. 12, 2016, 1:55 p.m. UTC
Hi all,

I've been investigating the execution failures of:
21_strings/basic_string/numeric_conversions/char/stod.cc
21_strings/basic_string/numeric_conversions/wchar_t/stod.cc
21_strings/basic_string/numeric_conversions/wchar_t/stold.cc
27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc

on aarch64-none-elf, a newlib target.
The reason they are failing is because they are converting a long double to a string using to_string
before trying to convert it back into a number.
to_string ends up calling a vsnprintf from the C library (newlib in this case) with the %Lf format
to convert from long double.
Unfortunately the %Lf format is broken in newlib for platforms where long double is not the same as double.
It gives bogus results because newlib doesn't implement the long double variant of frexp (frexpl) which is needed
to implement printf properly. So it ends up using frexp even on long doubles. This gives wrong results which causes
these tests to fail.

So this patch marks them as XFAIL and adds an effective target check for broken newlib versions.

With this patch these tests appear as XFAIL on aarch64-none-elf.

Ok for trunk?

Thanks,
Kyrill

2016-12-12  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * lib/target-supports.exp
     (check_effective_target_newlib_broken_long_double_io): New check.
     (check_effective_target_frexpl): Likewise.

2016-12-12  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * testsuite/21_strings/basic_string/numeric_conversions/char/stod.cc:
     XFAIL run if newlib_broken_long_double_io.
     * testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc:
     Likewise.
     * testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stold.cc:
     Likewise.
     * testsuite/27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc:
     Likewise.

Comments

Jonathan Wakely Dec. 12, 2016, 3:39 p.m. UTC | #1
On 12/12/16 13:55 +0000, Kyrill Tkachov wrote:
>Hi all,
>
>I've been investigating the execution failures of:
>21_strings/basic_string/numeric_conversions/char/stod.cc
>21_strings/basic_string/numeric_conversions/wchar_t/stod.cc
>21_strings/basic_string/numeric_conversions/wchar_t/stold.cc
>27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc
>
>on aarch64-none-elf, a newlib target.
>The reason they are failing is because they are converting a long double to a string using to_string
>before trying to convert it back into a number.
>to_string ends up calling a vsnprintf from the C library (newlib in this case) with the %Lf format
>to convert from long double.
>Unfortunately the %Lf format is broken in newlib for platforms where long double is not the same as double.
>It gives bogus results because newlib doesn't implement the long double variant of frexp (frexpl) which is needed
>to implement printf properly. So it ends up using frexp even on long doubles. This gives wrong results which causes
>these tests to fail.
>
>So this patch marks them as XFAIL and adds an effective target check for broken newlib versions.
>
>With this patch these tests appear as XFAIL on aarch64-none-elf.
>
>Ok for trunk?

Yes OK, thanks.
diff mbox

Patch

diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index bce181fd87b32d51edb9b62fef81ad4314f0d222..d6229392b1414a26fe000dd61cc75ec112453b5f 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -6765,6 +6765,17 @@  proc check_effective_target_newlib {} {
     }]
 }
 
+# Some newlib versions don't provide a frexpl and instead depend
+# on frexp to implement long double conversions in their printf-like
+# functions.  This leads to broken results.  Detect such versions here.
+
+proc check_effective_target_newlib_broken_long_double_io {} {
+  if { [is-effective-target newlib] && ![is-effective-target frexpl] } {
+	return 1
+  }
+  return 0
+}
+
 # Return true if this is NOT a Bionic target.
 
 proc check_effective_target_non_bionic {} {
@@ -7380,6 +7391,21 @@  proc check_effective_target_pow10 { } {
     } "-lm" ]
 }
 
+# Return 1 if frexpl function exists.
+
+proc check_effective_target_frexpl { } {
+    return [check_runtime frexpl {
+	#include <math.h>
+	int main () {
+	long double x;
+	int y;
+	x = frexpl (5.0, &y);
+	return 0;
+	}
+    } "-lm" ]
+}
+
+
 # Return 1 if issignaling function exists.
 proc check_effective_target_issignaling {} {
     return [check_runtime issignaling {
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stod.cc b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stod.cc
index 7e7c1347eab51abef73865073dbb4129db71af48..088641130075add8346948f286cfc63de6637721 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stod.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stod.cc
@@ -1,5 +1,6 @@ 
 // { dg-do run { target c++11 } }
 // { dg-require-string-conversions "" }
+// { dg-xfail-run-if "broken long double IO" { newlib_broken_long_double_io  }  "*" "" }
 
 // 2008-06-15  Paolo Carlini  <paolo.carlini@oracle.com>
 
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stold.cc b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stold.cc
index 15a4dcaddb46dc62df9f7c51c3c07c73823fccff..df39a50b9c8964f70db17a07caaf0f8a48eddbcf 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stold.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stold.cc
@@ -1,5 +1,6 @@ 
 // { dg-do run { target c++11 } }
 // { dg-require-string-conversions "" }
+// { dg-xfail-run-if "broken long double IO" { newlib_broken_long_double_io  }  "*" "" }
 
 // 2008-06-15  Paolo Carlini  <paolo.carlini@oracle.com>
 
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc
index 81735dd186617c0fe96c2334e5fab2cef6a07d4e..259dc65024833af576b5cba44942e996c41c1b0d 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc
@@ -1,5 +1,7 @@ 
 // { dg-do run { target c++11 } }
 // { dg-require-string-conversions "" }
+// { dg-xfail-run-if "broken long double IO" { newlib_broken_long_double_io  }  "*" "" }
+
 // 2008-06-15  Paolo Carlini  <paolo.carlini@oracle.com>
 
 // Copyright (C) 2008-2016 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stold.cc b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stold.cc
index 82b8c8bb84658d5b30b69fffbf7066940e44a460..3a95010945b25317619f34458905d540076a407a 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stold.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stold.cc
@@ -1,5 +1,7 @@ 
 // { dg-do run { target c++11 } }
 // { dg-require-string-conversions "" }
+// { dg-xfail-run-if "broken long double IO" { newlib_broken_long_double_io  }  "*" "" }
+
 // 2008-06-15  Paolo Carlini  <paolo.carlini@oracle.com>
 
 // Copyright (C) 2008-2016 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc
index 364bc56d2faac10c19c673d1adcd0e7e986a777f..839037917c959905a11774854bb1ceb88c5559a4 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc
@@ -1,6 +1,7 @@ 
 // { dg-do run { target c++11 } }
 // { dg-require-string-conversions "" }
 // { dg-xfail-run-if "PR libstdc++/64054" { *-*-solaris* } }
+// { dg-xfail-run-if "broken long double IO" { newlib_broken_long_double_io  }  "*" "" }
 
 // 2014-03-27 RĂ¼diger Sonderfeld
 // test the hexadecimal floating point inserters (facet num_put)