[libcxx] r219243 - Fix for PR 19616: 'tuple_cat of nested tuples fails in noexcept specification'. Thanks to Louis Dionne for the fix.

Marshall Clow mclow.lists at gmail.com
Tue Oct 7 14:42:13 PDT 2014


Author: marshall
Date: Tue Oct  7 16:42:12 2014
New Revision: 219243

URL: http://llvm.org/viewvc/llvm-project?rev=219243&view=rev
Log:
Fix for PR 19616: 'tuple_cat of nested tuples fails in noexcept specification'. Thanks to Louis Dionne for the fix.

Modified:
    libcxx/trunk/include/type_traits
    libcxx/trunk/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp
    libcxx/trunk/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp

Modified: libcxx/trunk/include/type_traits
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=219243&r1=219242&r2=219243&view=diff
==============================================================================
--- libcxx/trunk/include/type_traits (original)
+++ libcxx/trunk/include/type_traits Tue Oct  7 16:42:12 2014
@@ -2888,29 +2888,38 @@ struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_
 
 #if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)
 
-template <bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible;
+template <bool, bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible;
 
 template <class _Tp, class... _Args>
-struct __libcpp_is_nothrow_constructible<true, _Tp, _Args...>
+struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/false, _Tp, _Args...>
     : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))>
 {
 };
 
-template <class _Tp, class... _Args>
-struct __libcpp_is_nothrow_constructible<false, _Tp, _Args...>
+template <class _Tp>
+void __implicit_conversion_to(_Tp) noexcept { }
+
+template <class _Tp, class _Arg>
+struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/true, _Tp, _Arg>
+    : public integral_constant<bool, noexcept(__implicit_conversion_to<_Tp>(declval<_Arg>()))>
+{
+};
+
+template <class _Tp, bool _IsReference, class... _Args>
+struct __libcpp_is_nothrow_constructible</*is constructible*/false, _IsReference, _Tp, _Args...>
     : public false_type
 {
 };
 
 template <class _Tp, class... _Args>
 struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible
-    : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, _Tp, _Args...>
+    : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, is_reference<_Tp>::value, _Tp, _Args...>
 {
 };
 
 template <class _Tp, size_t _Ns>
 struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp[_Ns]>
-    : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, _Tp>
+    : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp>
 {
 };
 

Modified: libcxx/trunk/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp?rev=219243&r1=219242&r2=219243&view=diff
==============================================================================
--- libcxx/trunk/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp (original)
+++ libcxx/trunk/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp Tue Oct  7 16:42:12 2014
@@ -76,15 +76,28 @@ struct C
     void operator=(C&);  // not const
 };
 
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+struct Tuple {
+    Tuple(Empty&&) noexcept {}
+};
+#endif
+
 int main()
 {
     test_is_nothrow_constructible<int> ();
     test_is_nothrow_constructible<int, const int&> ();
     test_is_nothrow_constructible<Empty> ();
     test_is_nothrow_constructible<Empty, const Empty&> ();
-
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    test_is_nothrow_constructible<Tuple &&, Empty> (); // See bug #19616.
+#endif
+    
     test_is_not_nothrow_constructible<A, int> ();
     test_is_not_nothrow_constructible<A, int, double> ();
     test_is_not_nothrow_constructible<A> ();
     test_is_not_nothrow_constructible<C> ();
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    static_assert(!std::is_constructible<Tuple&, Empty>::value, "");
+    test_is_not_nothrow_constructible<Tuple &, Empty> (); // See bug #19616.
+#endif
 }

Modified: libcxx/trunk/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp?rev=219243&r1=219242&r2=219243&view=diff
==============================================================================
--- libcxx/trunk/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp (original)
+++ libcxx/trunk/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp Tue Oct  7 16:42:12 2014
@@ -213,4 +213,18 @@ int main()
         assert(std::get<3>(t3) == 4);
         assert(std::get<4>(t3) == 5);
     }
+    {
+        // See bug #19616.
+        auto t1 = std::tuple_cat(
+            std::make_tuple(std::make_tuple(1)),
+            std::make_tuple()
+        );
+        assert(t1 == std::make_tuple(std::make_tuple(1)));
+
+        auto t2 = std::tuple_cat(
+            std::make_tuple(std::make_tuple(1)),
+            std::make_tuple(std::make_tuple(2))
+        );
+        assert(t2 == std::make_tuple(std::make_tuple(1), std::make_tuple(2)));
+    }
 }





More information about the cfe-commits mailing list