]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR libstdc++/55043 (again)
authorJonathan Wakely <jwakely.gcc@gmail.com>
Wed, 16 Jan 2013 23:56:00 +0000 (23:56 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 16 Jan 2013 23:56:00 +0000 (23:56 +0000)
PR libstdc++/55043 (again)
* include/bits/alloc_traits.h (allocator_traits::construct): Disable
unless construction would be well-formed.
(__allow_copy_cons, __check_copy_constructible): Define.
* include/bits/unordered_map.h (__check_copy_constructible): Use as
base class so copy constructor will be deleted if appropriate.
(is_copy_constructible): Remove specialization.
* include/bits/unordered_set.h: Likewise.
* include/debug/unordered_map.h: Undo previous commit. Default copy
and move constructors.
* include/debug/unordered_set.h: Likewise.
* include/profile/unordered_map.h: Undo previous commit.
* include/profile/unordered_set.h: Likewise.
* testsuite/23_containers/unordered_map/55043.cc: Fix test.
* testsuite/23_containers/unordered_multimap/55043.cc: Likewise.
* testsuite/23_containers/unordered_multiset/55043.cc: Likewise.
* testsuite/23_containers/unordered_set/55043.cc: Likewise.
* testsuite/23_containers/unordered_map/requirements/53339.cc: XFAIL,
cannot support incomplete types.
* testsuite/23_containers/unordered_multimap/requirements/53339.cc:
Likewise.

From-SVN: r195253

14 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/alloc_traits.h
libstdc++-v3/include/bits/unordered_map.h
libstdc++-v3/include/bits/unordered_set.h
libstdc++-v3/include/debug/unordered_map
libstdc++-v3/include/debug/unordered_set
libstdc++-v3/include/profile/unordered_map
libstdc++-v3/include/profile/unordered_set
libstdc++-v3/testsuite/23_containers/unordered_map/55043.cc
libstdc++-v3/testsuite/23_containers/unordered_map/requirements/53339.cc
libstdc++-v3/testsuite/23_containers/unordered_multimap/55043.cc
libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/53339.cc
libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc
libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc

index ac5c10affc868a6838d30aa0f825c028f30e072e..39fe5877382bf6155da536658d204bec774c2ff2 100644 (file)
@@ -1,3 +1,27 @@
+2013-01-16  Jonathan Wakely  <jwakely.gcc@gmail.com>
+
+       PR libstdc++/55043 (again)
+       * include/bits/alloc_traits.h (allocator_traits::construct): Disable
+       unless construction would be well-formed.
+       (__allow_copy_cons, __check_copy_constructible): Define.
+       * include/bits/unordered_map.h (__check_copy_constructible): Use as
+       base class so copy constructor will be deleted if appropriate.
+       (is_copy_constructible): Remove specialization.
+       * include/bits/unordered_set.h: Likewise.
+       * include/debug/unordered_map.h: Undo previous commit. Default copy
+       and move constructors.
+       * include/debug/unordered_set.h: Likewise.
+       * include/profile/unordered_map.h: Undo previous commit.
+       * include/profile/unordered_set.h: Likewise.
+       * testsuite/23_containers/unordered_map/55043.cc: Fix test.
+       * testsuite/23_containers/unordered_multimap/55043.cc: Likewise.
+       * testsuite/23_containers/unordered_multiset/55043.cc: Likewise.
+       * testsuite/23_containers/unordered_set/55043.cc: Likewise.
+       * testsuite/23_containers/unordered_map/requirements/53339.cc: XFAIL,
+       cannot support incomplete types.
+       * testsuite/23_containers/unordered_multimap/requirements/53339.cc:
+       Likewise.
+
 2013-01-16  Jonathan Wakely  <jwakely.gcc@gmail.com>
 
        PR libstdc++/55043
index c6259a1d014c78e97fdc9ad82f5d1a1af8ca8adc..26c64f257b5c00353882ab3e192891c11bc4de9a 100644 (file)
@@ -257,7 +257,8 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
 
       template<typename _Tp, typename... _Args>
        static typename
-               enable_if<!__construct_helper<_Tp, _Args...>::value, void>::type
+       enable_if<__and_<__not_<__construct_helper<_Tp, _Args...>>,
+                        is_constructible<_Tp, _Args...>>::value, void>::type
                _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
        { ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); }
 
@@ -389,7 +390,8 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
        *  arguments @a __args...
       */
       template<typename _Tp, typename... _Args>
-       static void construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
+       static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
+       -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
        { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
 
       /**
@@ -526,9 +528,10 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
        _M_select(...);
 
     public:
-       typedef decltype(_M_select<typename _Alloc::value_type>(0)) type;
+      typedef decltype(_M_select<typename _Alloc::value_type>(0)) type;
     };
 
+  // true if _Alloc::value_type is CopyInsertable into containers using _Alloc
   template<typename _Alloc>
     struct __is_copy_insertable
     : __is_copy_insertable_impl<_Alloc>::type
@@ -540,9 +543,23 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
     : is_copy_constructible<_Tp>
     { };
 
-  template<typename _Container>
-    using __has_copy_insertable_val
-      = __is_copy_insertable<typename _Container::allocator_type>;
+  // Used to allow copy construction of unordered containers
+  template<bool> struct __allow_copy_cons { };
+
+  // Used to delete copy constructor of unordered containers
+  template<>
+    struct __allow_copy_cons<false>
+    {
+      __allow_copy_cons() = default;
+      __allow_copy_cons(const __allow_copy_cons&) = delete;
+      __allow_copy_cons(__allow_copy_cons&&) = default;
+      __allow_copy_cons& operator=(const __allow_copy_cons&) = default;
+      __allow_copy_cons& operator=(__allow_copy_cons&&) = default;
+    };
+
+  template<typename _Alloc>
+    using __check_copy_constructible
+      = __allow_copy_cons<__is_copy_insertable<_Alloc>::value>;
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
index 0235a99e97054bdce86666d87434bd8094f90b58..be213e04a79e087a6552107c622ff17794240425 100644 (file)
@@ -94,7 +94,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
           class _Hash = hash<_Key>,
           class _Pred = std::equal_to<_Key>,
           class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
-    class unordered_map
+    class unordered_map : __check_copy_constructible<_Alloc>
     {
       typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc>  _Hashtable;
       _Hashtable _M_h;
@@ -775,7 +775,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
           class _Hash = hash<_Key>,
           class _Pred = std::equal_to<_Key>,
           class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
-    class unordered_multimap
+    class unordered_multimap : __check_copy_constructible<_Alloc>
     {
       typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc>  _Hashtable;
       _Hashtable _M_h;
@@ -1408,26 +1408,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     { return !(__x == __y); }
 
 _GLIBCXX_END_NAMESPACE_CONTAINER
-
-  template<typename _Key, typename _Tp, typename _Hash, typename _Pred,
-          typename _Alloc>
-    struct
-    is_copy_constructible<_GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
-                                                       _Pred, _Alloc>>
-    : __has_copy_insertable_val<_GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
-                                                             _Pred, _Alloc>>
-    { };
-
-  template<typename _Key, typename _Tp, typename _Hash, typename _Pred,
-          typename _Alloc>
-    struct
-    is_copy_constructible<_GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
-                                                            _Pred, _Alloc>>
-    : __has_copy_insertable_val<_GLIBCXX_STD_C::unordered_multimap<_Key, _Tp,
-                                                                  _Hash, _Pred,
-                                                                  _Alloc>>
-    { };
-
 } // namespace std
 
 #endif /* _UNORDERED_MAP_H */
index 2ada63dcde681f037c8056243770ee90c063bb66..50c233d0595f042112035222961e41a867a8be3f 100644 (file)
@@ -90,7 +90,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
           class _Hash = hash<_Value>,
           class _Pred = std::equal_to<_Value>,
           class _Alloc = std::allocator<_Value> >
-    class unordered_set
+    class unordered_set : __check_copy_constructible<_Alloc>
     {
       typedef __uset_hashtable<_Value, _Hash, _Pred, _Alloc>  _Hashtable;
       _Hashtable _M_h;
@@ -695,7 +695,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
           class _Hash = hash<_Value>,
           class _Pred = std::equal_to<_Value>,
           class _Alloc = std::allocator<_Value> >
-    class unordered_multiset
+    class unordered_multiset : __check_copy_constructible<_Alloc>
     {
       typedef __umset_hashtable<_Value, _Hash, _Pred, _Alloc>  _Hashtable;
       _Hashtable _M_h;
@@ -1291,23 +1291,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     { return !(__x == __y); }
 
 _GLIBCXX_END_NAMESPACE_CONTAINER
-
-  template<typename _Key, typename _Hash, typename _Pred, typename _Alloc>
-    struct is_copy_constructible<_GLIBCXX_STD_C::unordered_set<_Key, _Hash,
-                                                              _Pred, _Alloc>>
-    : __has_copy_insertable_val<_GLIBCXX_STD_C::unordered_set<_Key, _Hash,
-                                                             _Pred, _Alloc>>
-    { };
-
-  template<typename _Key, typename _Hash, typename _Pred, typename _Alloc>
-    struct
-    is_copy_constructible<_GLIBCXX_STD_C::unordered_multiset<_Key, _Hash,
-                                                            _Pred, _Alloc>>
-    : __has_copy_insertable_val<_GLIBCXX_STD_C::unordered_multiset<_Key, _Hash,
-                                                                  _Pred,
-                                                                  _Alloc>>
-    { };
-
 } // namespace std
 
 #endif /* _UNORDERED_SET_H */
index 115abb58865b98a9daae46f1b5eafd93e7f6bf88..284450fc7d8d749f4f2723cf8ea2a5b43b396d64 100644 (file)
@@ -96,14 +96,12 @@ namespace __debug
                __gnu_debug::__base(__last), __n,
                __hf, __eql, __a) { }
 
-      unordered_map(const unordered_map& __x) 
-      : _Base(__x) { }
+      unordered_map(const unordered_map& __x) = default;
 
       unordered_map(const _Base& __x)
       : _Base(__x) { }
 
-      unordered_map(unordered_map&& __x)
-      : _Base(std::move(__x)) { }
+      unordered_map(unordered_map&& __x) = default;
 
       unordered_map(initializer_list<value_type> __l,
                    size_type __n = 0,
@@ -547,14 +545,12 @@ namespace __debug
                __gnu_debug::__base(__last), __n,
                __hf, __eql, __a) { }
 
-      unordered_multimap(const unordered_multimap& __x) 
-      : _Base(__x) { }
+      unordered_multimap(const unordered_multimap& __x) = default;
 
       unordered_multimap(const _Base& __x) 
       : _Base(__x) { }
 
-      unordered_multimap(unordered_multimap&& __x)
-      : _Base(std::move(__x)) { }
+      unordered_multimap(unordered_multimap&& __x) = default;
 
       unordered_multimap(initializer_list<value_type> __l,
                         size_type __n = 0,
@@ -938,30 +934,6 @@ namespace __debug
     { return !(__x == __y); }
 
 } // namespace __debug
-
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<typename _Key, typename _Tp, typename _Hash, typename _Pred,
-          typename _Alloc>
-    struct
-    is_copy_constructible<__debug::unordered_map<_Key, _Tp, _Hash, _Pred,
-                                                _Alloc>>
-    : is_copy_constructible< _GLIBCXX_STD_C::unordered_map<_Key, _Tp,
-                                                          _Hash, _Pred,
-                                                          _Alloc> >
-    { };
-
-  template<typename _Key, typename _Tp, typename _Hash, typename _Pred,
-          typename _Alloc>
-    struct
-    is_copy_constructible<__debug::unordered_multimap<_Key, _Tp, _Hash, _Pred,
-                                                     _Alloc>>
-    : is_copy_constructible< _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp,
-                                                               _Hash, _Pred,
-                                                               _Alloc> >
-    { };
-
-_GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
 #endif // C++11
index 895c9439f6e0330162a43b196a2f76ac94e2e051..2fe71e4bb07c0020e3b2b77f24ee707002fa0ade 100644 (file)
@@ -96,14 +96,12 @@ namespace __debug
                __gnu_debug::__base(__last), __n,
                __hf, __eql, __a) { }
 
-      unordered_set(const unordered_set& __x) 
-      : _Base(__x) { }
+      unordered_set(const unordered_set& __x) = default;
 
       unordered_set(const _Base& __x) 
       : _Base(__x) { }
 
-      unordered_set(unordered_set&& __x)
-      : _Base(std::move(__x)) { }
+      unordered_set(unordered_set&& __x) = default;
 
       unordered_set(initializer_list<value_type> __l,
                    size_type __n = 0,
@@ -542,14 +540,12 @@ namespace __debug
                __gnu_debug::__base(__last), __n,
                __hf, __eql, __a) { }
 
-      unordered_multiset(const unordered_multiset& __x) 
-      : _Base(__x) { }
+      unordered_multiset(const unordered_multiset& __x) = default;
 
       unordered_multiset(const _Base& __x) 
       : _Base(__x) { }
 
-      unordered_multiset(unordered_multiset&& __x)
-      : _Base(std::move(__x)) { }
+      unordered_multiset(unordered_multiset&& __x) = default;
 
       unordered_multiset(initializer_list<value_type> __l,
                         size_type __n = 0,
@@ -920,27 +916,6 @@ namespace __debug
     { return !(__x == __y); }
 
 } // namespace __debug
-
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<typename _Key, typename _Hash, typename _Pred, typename _Alloc>
-    struct
-    is_copy_constructible<__debug::unordered_set<_Key, _Hash, _Pred, _Alloc>>
-    : is_copy_constructible< _GLIBCXX_STD_C::unordered_set<_Key,
-                                                          _Hash, _Pred,
-                                                          _Alloc> >
-    { };
-
-  template<typename _Key, typename _Hash, typename _Pred, typename _Alloc>
-    struct
-    is_copy_constructible<__debug::unordered_multiset<_Key, _Hash, _Pred,
-                                                     _Alloc>>
-    : is_copy_constructible< _GLIBCXX_STD_C::unordered_multiset<_Key,
-                                                               _Hash, _Pred,
-                                                               _Alloc> >
-    { };
-
-_GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
 #endif // C++11
index 5ebcbf60fcb2c0d68222e78df4c3c8971a81c949..0fee176e14a3873e066d08ddfe84d4af457beb5c 100644 (file)
@@ -339,25 +339,11 @@ namespace __profile
               const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
     { return !(__x == __y); }
 
-} // namespace __profile
-
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-  template<typename _Key, typename _Tp, typename _Hash, typename _Pred,
-          typename _Alloc>
-    struct
-    is_copy_constructible<__profile::unordered_map<_Key, _Tp, _Hash,
-                                                  _Pred, _Alloc>>
-    : is_copy_constructible< _GLIBCXX_STD_BASE >
-    { };
-_GLIBCXX_END_NAMESPACE_VERSION
-
 #undef _GLIBCXX_BASE
 #undef _GLIBCXX_STD_BASE
 #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
 
-namespace __profile
-{
   /// Class std::unordered_multimap wrapper with performance instrumentation.
   template<typename _Key, typename _Tp,
           typename _Hash  = std::hash<_Key>,
@@ -623,18 +609,6 @@ namespace __profile
     { return !(__x == __y); }
 
 } // namespace __profile
-
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<typename _Key, typename _Tp, typename _Hash, typename _Pred,
-          typename _Alloc>
-    struct
-    is_copy_constructible<__profile::unordered_multimap<_Key, _Tp, _Hash,
-                                                       _Pred, _Alloc>>
-    : is_copy_constructible< _GLIBCXX_STD_BASE >
-    { };
-
-_GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
 #undef _GLIBCXX_BASE
index ebe1c7d6f124c84da1ccf9f643341e56fe862c31..737b6ec6b96f8745ce5aa318aeaf28f5fe939db6 100644 (file)
@@ -305,23 +305,11 @@ namespace __profile
               const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y)
     { return !(__x == __y); }
 
-} // namespace __profile
-
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-  template<typename _Key, typename _Hash, typename _Pred, typename _Alloc>
-    struct
-    is_copy_constructible<__profile::unordered_set<_Key, _Hash, _Pred, _Alloc>>
-    : is_copy_constructible< _GLIBCXX_STD_BASE >
-    { };
-_GLIBCXX_END_NAMESPACE_VERSION
-
 #undef _GLIBCXX_BASE
 #undef _GLIBCXX_STD_BASE
 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
 #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc>
 
-namespace __profile
-{
   /** @brief Unordered_multiset wrapper with performance instrumentation.  */
   template<typename _Value,
        typename _Hash  = std::hash<_Value>,
@@ -580,17 +568,6 @@ namespace __profile
     { return !(__x == __y); }
 
 } // namespace __profile
-
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
-    struct
-    is_copy_constructible<__profile::unordered_multiset<_Value, _Hash,
-                                                       _Pred, _Alloc>>
-    : is_copy_constructible< _GLIBCXX_STD_BASE >
-    { };
-
-_GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
 #undef _GLIBCXX_BASE
index 10d36a057982150a1a443a3b994639090e3b5be3..50e5437044c7d70ca32626c095f331a3788cc212 100644 (file)
@@ -63,7 +63,7 @@ struct Alloc : std::allocator<T>
 
 // verify is_copy_constructible depends on allocator
 typedef test_type<Alloc<MoveOnly, true>> uim_rval;
-static_assert(std::is_copy_constructible<uim_rval>::value, "is not copyable");
+static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable");
 
 typedef test_type<Alloc<MoveOnly, false>> uim_lval;
 static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable");
index 4df449323ba27262b592040d2abb15d5e84801e9..10404ce08146c4eafd07670f5ad48d77fde0400b 100644 (file)
@@ -1,7 +1,9 @@
-// { dg-do compile }
+// XFAIL because of PR libstdc++/55043 fix
+// { dg-do compile { xfail *-*-* } }
+// { dg-excess-errors "" }
 // { dg-options "-std=gnu++11" }
 
-// Copyright (C) 2012 Free Software Foundation, Inc.
+// Copyright (C) 2012-2013 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
index 9ae912ef64171cf34a57ac27f0505822c0e1175e..afeecaad0ab44150039b0b5db6efae6b8376e23a 100644 (file)
@@ -63,7 +63,7 @@ struct Alloc : std::allocator<T>
 
 // verify is_copy_constructible depends on allocator
 typedef test_type<Alloc<MoveOnly, true>> uim_rval;
-static_assert(std::is_copy_constructible<uim_rval>::value, "is not copyable");
+static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable");
 
 typedef test_type<Alloc<MoveOnly, false>> uim_lval;
 static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable");
index 574561889e611287e8703edcd8257abb9003defc..cccd2a89513427a21508153bde33432bac7ab902 100644 (file)
@@ -1,7 +1,9 @@
-// { dg-do compile }
+// XFAIL because of PR libstdc++/55043 fix
+// { dg-do compile { xfail *-*-* } }
+// { dg-excess-errors "" }
 // { dg-options "-std=gnu++11" }
 
-// Copyright (C) 2012 Free Software Foundation, Inc.
+// Copyright (C) 2012-2013 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
index ebb8cb8ae1d575edcb0a7da886b02c0ebb07ccb8..445e4e48bc3c017c9630ecaf49c3185df5b06fb9 100644 (file)
@@ -67,7 +67,7 @@ struct Alloc : std::allocator<T>
 
 // verify is_copy_constructible depends on allocator
 typedef test_type<Alloc<MoveOnly, true>> uim_rval;
-static_assert(std::is_copy_constructible<uim_rval>::value, "is not copyable");
+static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable");
 
 typedef test_type<Alloc<MoveOnly, false>> uim_lval;
 static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable");
index 3b0b973e80da151b150addb497d093cc1796ada1..e5ba065f5d570a65a32191b6bb87b698a3c565c7 100644 (file)
@@ -67,7 +67,7 @@ struct Alloc : std::allocator<T>
 
 // verify is_copy_constructible depends on allocator
 typedef test_type<Alloc<MoveOnly, true>> uim_rval;
-static_assert(std::is_copy_constructible<uim_rval>::value, "is not copyable");
+static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable");
 
 typedef test_type<Alloc<MoveOnly, false>> uim_lval;
 static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable");