diff mbox

[v3] PR 67844

Message ID CAFk2RUYBeQW2zyvCh6W6Hp3OthA_1HHKrf-JLT27411XAaAmLQ@mail.gmail.com
State New
Headers show

Commit Message

Ville Voutilainen Oct. 5, 2015, 3:59 a.m. UTC
Tested on Linux-PPC64. The problem is a tad tricky, since
the bug triggered by the testcase is in a constructor that
will not be used, but will cause endless meta-recursion
via checking convertibility of an incomplete type that will
cause further recursion. While there might be ways to fix
that in the traits themselves, this is a straightforward fix,
for certain tuple-specific values of "straightforward". ;)

And hey, the problem and its solution were, once the bug
report came in, obvious to the resident tuple-hacker between
my chair and my keyboard. :)

2015-10-05  Ville Voutilainen  <ville.voutilainen@gmail.com>

    PR 67844.
    * include/std/tuple (_TC::_NonNestedTuple): Eagerly reject
    conversions from tuple types same as the target tuple.
    * testsuite/20_util/tuple/67844.cc: New.

Comments

Jonathan Wakely Oct. 5, 2015, 9:48 a.m. UTC | #1
On 05/10/15 06:59 +0300, Ville Voutilainen wrote:
>    PR 67844.
>    * include/std/tuple (_TC::_NonNestedTuple): Eagerly reject
>    conversions from tuple types same as the target tuple.
>    * testsuite/20_util/tuple/67844.cc: New.

OK for trunk with a copyright header on the testcase. Thanks for the
quick fix.
diff mbox

Patch

diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 751d7eb..8af01f4 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -457,6 +457,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     };
 
+  template<typename... _Elements>
+    class tuple;
 
   // Concept utility functions, reused in conditionally-explicit
   // constructors.
@@ -490,7 +492,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     template<typename _SrcTuple>
     static constexpr bool _NonNestedTuple()
     {
-      return  __and_<__not_<is_convertible<_SrcTuple, _Elements...>>,
+      return  __and_<__not_<is_same<tuple<_Elements...>,
+                                   typename remove_cv<
+                                     typename remove_reference<_SrcTuple>::type
+                                   >::type>>,
+                     __not_<is_convertible<_SrcTuple, _Elements...>>,
                      __not_<is_constructible<_Elements..., _SrcTuple>>
               >::value;
     }
diff --git a/libstdc++-v3/testsuite/20_util/tuple/67844.cc b/libstdc++-v3/testsuite/20_util/tuple/67844.cc
new file mode 100644
index 0000000..5635462
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/67844.cc
@@ -0,0 +1,24 @@ 
+// { dg-do compile }
+
+#include <tuple>
+
+struct A
+{
+  template <typename T>
+  A(T)
+  {
+  }
+
+  A(const A&) = default;
+  A(A&&) = default;
+  A& operator=(const A&) = default;
+  A& operator=(A&&) = default;
+  ~A() = default;
+};
+
+int main()
+{
+  auto x = A{7};
+  std::make_tuple(x);
+}
+