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.voutilai...@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.
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);
+}
+

Reply via email to