Fix incorrectly qualified return type from unique_ptr::get_deleter().
authorEric Fiselier <eric@efcs.ca>
Wed, 12 Apr 2017 22:43:49 +0000 (22:43 +0000)
committerEric Fiselier <eric@efcs.ca>
Wed, 12 Apr 2017 22:43:49 +0000 (22:43 +0000)
For reference deleter types the const qualifier on the return type
of get_deleter() should be ignored, and a non-const deleter should
be returned.

This patch fixes a bug where "const deleter_type&" is incorrectly
formed.

llvm-svn: 300121

libcxx/include/memory
libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.observers/get_deleter.pass.cpp
libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.observers/get_deleter.pass.cpp
libcxx/test/support/test_macros.h

index bd911a8..6eb2184 100644 (file)
@@ -2110,8 +2110,8 @@ public:
     typedef typename remove_reference<_T1>::type& _T1_reference;
     typedef typename remove_reference<_T2>::type& _T2_reference;
 
-    typedef const typename remove_reference<_T1>::type& _T1_const_reference;
-    typedef const typename remove_reference<_T2>::type& _T2_const_reference;
+    typedef typename remove_reference<typename add_const<_T1>::type>::type& _T1_const_reference;
+    typedef typename remove_reference<typename add_const<_T2>::type>::type& _T2_const_reference;
 
     _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_(), __second_() {}
     _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
@@ -2166,7 +2166,8 @@ public:
     typedef typename remove_reference<_T2>::type& _T2_reference;
 
     typedef const _T1&                                        _T1_const_reference;
-    typedef const typename remove_reference<_T2>::type& _T2_const_reference;
+    typedef typename remove_reference<typename add_const<_T2>::type>::type&
+        _T2_const_reference;
 
     _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __second_() {}
     _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
@@ -2219,7 +2220,8 @@ public:
     typedef typename remove_reference<_T1>::type& _T1_reference;
     typedef _T2&                                        _T2_reference;
 
-    typedef const typename remove_reference<_T1>::type& _T1_const_reference;
+    typedef typename remove_reference<typename add_const<_T1>::type>::type&
+        _T1_const_reference;
     typedef const _T2&                                        _T2_const_reference;
 
     _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_() {}
@@ -2459,8 +2461,9 @@ private:
 
     struct __nat {int __for_bool_;};
 
-    typedef       typename remove_reference<deleter_type>::type& _Dp_reference;
-    typedef const typename remove_reference<deleter_type>::type& _Dp_const_reference;
+    typedef typename remove_reference<deleter_type>::type& _Dp_reference;
+    typedef typename remove_reference<typename add_const<deleter_type>::type>::type&
+        _Dp_const_reference;
 public:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT
         : __ptr_(pointer())
@@ -2648,8 +2651,9 @@ private:
 
     struct __nat {int __for_bool_;};
 
-    typedef       typename remove_reference<deleter_type>::type& _Dp_reference;
-    typedef const typename remove_reference<deleter_type>::type& _Dp_const_reference;
+    typedef typename remove_reference<deleter_type>::type& _Dp_reference;
+    typedef typename remove_reference<typename add_const<deleter_type>::type>::type&
+        _Dp_const_reference;
 public:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT
         : __ptr_(pointer())
index 4496740..a3bb1a0 100644 (file)
 
 #include <memory>
 #include <cassert>
+#include "test_macros.h"
 
-struct Deleter
-{
-    void operator()(void*) {}
+struct Deleter {
+  void operator()(void*) const {}
 
-    int test() {return 5;}
-    int test() const {return 6;}
+  int test() { return 5; }
+  int test() const { return 6; }
 };
 
-int main()
-{
-    {
+int main() {
+  {
     std::unique_ptr<int[], Deleter> p;
     assert(p.get_deleter().test() == 5);
-    }
-    {
+  }
+  {
     const std::unique_ptr<int[], Deleter> p;
     assert(p.get_deleter().test() == 6);
-    }
+  }
+  {
+    typedef std::unique_ptr<int[], const Deleter&> UPtr;
+    const Deleter d;
+    UPtr p(nullptr, d);
+    const UPtr& cp = p;
+    ASSERT_SAME_TYPE(decltype(p.get_deleter()), const Deleter&);
+    ASSERT_SAME_TYPE(decltype(cp.get_deleter()), const Deleter&);
+    assert(p.get_deleter().test() == 6);
+    assert(cp.get_deleter().test() == 6);
+  }
+  {
+    typedef std::unique_ptr<int[], Deleter&> UPtr;
+    Deleter d;
+    UPtr p(nullptr, d);
+    const UPtr& cp = p;
+    ASSERT_SAME_TYPE(decltype(p.get_deleter()), Deleter&);
+    ASSERT_SAME_TYPE(decltype(cp.get_deleter()), Deleter&);
+    assert(p.get_deleter().test() == 5);
+    assert(cp.get_deleter().test() == 5);
+  }
 }
index 5ed8a22..3262abb 100644 (file)
 
 #include <memory>
 #include <cassert>
+#include "test_macros.h"
 
-struct Deleter
-{
-    void operator()(void*) {}
+struct Deleter {
+  void operator()(void*) const {}
 
-    int test() {return 5;}
-    int test() const {return 6;}
+  int test() { return 5; }
+  int test() const { return 6; }
 };
 
-int main()
-{
-    {
+int main() {
+  {
     std::unique_ptr<int, Deleter> p;
     assert(p.get_deleter().test() == 5);
-    }
-    {
+  }
+  {
     const std::unique_ptr<int, Deleter> p;
     assert(p.get_deleter().test() == 6);
-    }
+  }
+  {
+    typedef std::unique_ptr<int, const Deleter&> UPtr;
+    const Deleter d;
+    UPtr p(nullptr, d);
+    const UPtr& cp = p;
+    ASSERT_SAME_TYPE(decltype(p.get_deleter()), const Deleter&);
+    ASSERT_SAME_TYPE(decltype(cp.get_deleter()), const Deleter&);
+    assert(p.get_deleter().test() == 6);
+    assert(cp.get_deleter().test() == 6);
+  }
+  {
+    typedef std::unique_ptr<int, Deleter&> UPtr;
+    Deleter d;
+    UPtr p(nullptr, d);
+    const UPtr& cp = p;
+    ASSERT_SAME_TYPE(decltype(p.get_deleter()), Deleter&);
+    ASSERT_SAME_TYPE(decltype(cp.get_deleter()), Deleter&);
+    assert(p.get_deleter().test() == 5);
+    assert(cp.get_deleter().test() == 5);
+  }
 }
index 3cde8cc..bb3bea7 100644 (file)
@@ -184,7 +184,7 @@ struct is_same<T, T> { enum {value = 1}; };
 } // namespace test_macros_detail
 
 #define ASSERT_SAME_TYPE(...) \
-    static_assert(test_macros_detail::is_same<__VA_ARGS__>::value, \
+    static_assert((test_macros_detail::is_same<__VA_ARGS__>::value), \
                  "Types differ uexpectedly")
 
 #ifndef TEST_HAS_NO_EXCEPTIONS