Re: [patch] std::unique_ptrT[], D improvements
On 1/1/13, Geoffrey Romer gro...@google.com wrote: AFAICT there's no way to distinguish between safe and unsafe conversions of user-defined pointers, because that's a property of the pointer implementation, not the type itself. My PR errs on the side of trusting the implementation to provide only correct conversions. As Jonathan notes, Howard has objected to that part of the PR, so it's possible the eventual resolution will differ in that respect; I intend to pick up that discussion next week when I'm back from vacation. BTW, I've attached my latest set of tests. -- Lawrence Crowl tests.tar.gz Description: GNU Zip compressed data
Re: [patch] std::unique_ptrT[], D improvements
On 12/28/12, Jonathan Wakely jwakely@gmail.com wrote: On 28 December 2012 01:51, Lawrence Crowl wrote: I'm not getting errors when converting from derived to base. E.g. the following compiles, when it should not. std::unique_ptrconst base [] acb_ad(new derived[3]); I get an error: shm$ cat up.cc #include memory struct base { }; struct derived : base { virtual ~derived() = default; }; std::unique_ptrconst base [] acb_ad(new derived[3]); shm$ shm$ g++11 up.cc -c up.cc:4:53: error: use of deleted function ‘std::unique_ptr_Tp [], _Dp::unique_ptr(_Up*) [with _Up = derived; template-parameter-2-2 = void; _Tp = const base; _Dp = std::default_deleteconst base []]’ std::unique_ptrconst base [] acb_ad(new derived[3]); ^ In file included from /home/redi/gcc/4.x/include/c++/4.8.0/memory:81:0, from up.cc:1: /home/redi/gcc/4.x/include/c++/4.8.0/bits/unique_ptr.h:343:2: error: declared here unique_ptr(_Up* __p) = delete; ^ That was pilot error on my part. However, I've been having trouble when the argument to the constructor or reset has a conversion operator. The code does distinquish between a safe conversion to base and an unsafe conversion to derived. Here is a simplified version of the problem. The code as is fails to reject the last two calls to accept. The primary reason is that is_convertable permits both the invocation of the conversion operator and the derived to base conversion. At present, I see no way to get a handle on the 'natural' return type of the conversion operator. #include type_traits struct base { }; struct derived : base { }; template typename T, typename F typename std::enable_if std::is_convertible F, T* ::value, T* ::type accept(F arg) { return arg; } template typename T, typename F typename std::enable_if !std::is_convertible F(*)[], T(*)[] ::value, T* ::type accept(F* arg) = delete; struct cvt_b { operator base*() { return 0; } }; struct cvt_d { operator derived*() { return 0; } }; int main() { // should PASS accept base ( (base*)0 ); accept const base ( (base*)0 ); accept base ( cvt_b() ); accept const base ( cvt_b() ); // should FAIL accept base ( (derived*)0 ); accept const base ( (derived*)0 ); accept base ( cvt_d() ); accept const base ( cvt_d() ); } -- Lawrence Crowl
Re: [patch] std::unique_ptrT[], D improvements
On 1 January 2013 20:40, Lawrence Crowl wrote: That was pilot error on my part. However, I've been having trouble when the argument to the constructor or reset has a conversion operator. The code does distinquish between a safe conversion to base and an unsafe conversion to derived. Here is a simplified version of the problem. The code as is fails to reject the last two calls to accept. The primary reason is that is_convertable permits both the invocation of the conversion operator and the derived to base conversion. At present, I see no way to get a handle on the 'natural' return type of the conversion operator. Is the issue here that Geoffrey's proposed resolution allows any conversions (safe or not) if the source type is not a built-in pointer, i.e. is some user-defined type? So a user-defined type that refers an array of derived classes is allowed to be converted to an array of base, even though that's not safe. Howard has strongly objected to this part of the P/R.
Re: [patch] std::unique_ptrT[], D improvements
On 1/1/13, Jonathan Wakely jwakely@gmail.com wrote: On 1 January 2013 20:40, Lawrence Crowl wrote: That was pilot error on my part. However, I've been having trouble when the argument to the constructor or reset has a conversion operator. The code does distinquish between a safe conversion to base and an unsafe conversion to derived. Here is a simplified version of the problem. The code as is fails to reject the last two calls to accept. The primary reason is that is_convertable permits both the invocation of the conversion operator and the derived to base conversion. At present, I see no way to get a handle on the 'natural' return type of the conversion operator. Is the issue here that Geoffrey's proposed resolution allows any conversions (safe or not) if the source type is not a built-in pointer, i.e. is some user-defined type? So a user-defined type that refers an array of derived classes is allowed to be converted to an array of base, even though that's not safe. Howard has strongly objected to this part of the P/R. Yes. I see no way to distinguish between objects with safe conversion operators and unsafe conversion operators. -- Lawrence Crowl
Re: [patch] std::unique_ptrT[], D improvements
On 28 December 2012 01:51, Lawrence Crowl wrote: I'm not getting errors when converting from derived to base. E.g. the following compiles, when it should not. std::unique_ptrconst base [] acb_ad(new derived[3]); I get an error: shm$ cat up.cc #include memory struct base { }; struct derived : base { virtual ~derived() = default; }; std::unique_ptrconst base [] acb_ad(new derived[3]); shm$ shm$ g++11 up.cc -c up.cc:4:53: error: use of deleted function ‘std::unique_ptr_Tp [], _Dp::unique_ptr(_Up*) [with _Up = derived; template-parameter-2-2 = void; _Tp = const base; _Dp = std::default_deleteconst base []]’ std::unique_ptrconst base [] acb_ad(new derived[3]); ^ In file included from /home/redi/gcc/4.x/include/c++/4.8.0/memory:81:0, from up.cc:1: /home/redi/gcc/4.x/include/c++/4.8.0/bits/unique_ptr.h:343:2: error: declared here unique_ptr(_Up* __p) = delete; ^
Re: [patch] std::unique_ptrT[], D improvements
On 12/20/12, Jonathan Wakely jwakely@gmail.com wrote: This patch started when I noticed that it's not possibly to construct a shared_ptrT from unique_ptrT[], D, then I discovered we don't use D::pointer if it exists, and there were a number of other non-conformance issues with our std::unique_ptrT[], D. I ended up fixing them by implementing Geoffrey's proposed resolution for LWG issue 2118, which isn't official yet but is better than what we had before so is a step in the right direction, even if it ends up needing further revision when 2118 is resolved. * include/std/functional (_Require): Move to ... * include/std/type_traits (_Require): ... here. * include/bits/shared_ptr_base.h (__shared_count::_S_create_from_up): Handle unique_ptr for arrays or with custom pointer types. (__shared_ptr::__shared_ptr(unique_ptr_Tp1, _Del): Likewise. * include/bits/unique_ptr.h (unique_ptr_Tp[], _Dp): Use _Dp::pointer if defined. Implement proposed resolution of LWG 2118. * testsuite/20_util/shared_ptr/cons/unique_ptr_array.cc: New. * testsuite/20_util/unique_ptr/assign/cv_qual.cc: New. * testsuite/20_util/unique_ptr/cons/array_convertible_neg.cc: New. * testsuite/20_util/unique_ptr/cons/convertible_neg.cc: New. * testsuite/20_util/unique_ptr/cons/cv_qual.cc: New. * testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: New. * testsuite/20_util/unique_ptr/requirements/pointer_type_array.cc: New. * testsuite/20_util/shared_ptr/cons/unique_ptr.cc: Adjust comments. * testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc: Likewise. * testsuite/20_util/unique_ptr/requirements/pointer_type.cc: Likewise. * testsuite/20_util/bind/ref_neg.cc: Adjust dg-error line number. * testsuite/20_util/declval/requirements/1_neg.cc: Likewise. * testsuite/20_util/default_delete/48631_neg.cc: Likewise. * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Likewise. * testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise. * testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: Adjust dg-error text. * testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc: Use different instantiations so static_assert fails for each. Thanks to Geoffrey and Lawrence for input and test cases. Tested x86_64-linux, committed to trunk. I'm not getting errors when converting from derived to base. E.g. the following compiles, when it should not. std::unique_ptrconst base [] acb_ad(new derived[3]); -- Lawrence Crowl
[patch] std::unique_ptrT[], D improvements
This patch started when I noticed that it's not possibly to construct a shared_ptrT from unique_ptrT[], D, then I discovered we don't use D::pointer if it exists, and there were a number of other non-conformance issues with our std::unique_ptrT[], D. I ended up fixing them by implementing Geoffrey's proposed resolution for LWG issue 2118, which isn't official yet but is better than what we had before so is a step in the right direction, even if it ends up needing further revision when 2118 is resolved. * include/std/functional (_Require): Move to ... * include/std/type_traits (_Require): ... here. * include/bits/shared_ptr_base.h (__shared_count::_S_create_from_up): Handle unique_ptr for arrays or with custom pointer types. (__shared_ptr::__shared_ptr(unique_ptr_Tp1, _Del): Likewise. * include/bits/unique_ptr.h (unique_ptr_Tp[], _Dp): Use _Dp::pointer if defined. Implement proposed resolution of LWG 2118. * testsuite/20_util/shared_ptr/cons/unique_ptr_array.cc: New. * testsuite/20_util/unique_ptr/assign/cv_qual.cc: New. * testsuite/20_util/unique_ptr/cons/array_convertible_neg.cc: New. * testsuite/20_util/unique_ptr/cons/convertible_neg.cc: New. * testsuite/20_util/unique_ptr/cons/cv_qual.cc: New. * testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: New. * testsuite/20_util/unique_ptr/requirements/pointer_type_array.cc: New. * testsuite/20_util/shared_ptr/cons/unique_ptr.cc: Adjust comments. * testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc: Likewise. * testsuite/20_util/unique_ptr/requirements/pointer_type.cc: Likewise. * testsuite/20_util/bind/ref_neg.cc: Adjust dg-error line number. * testsuite/20_util/declval/requirements/1_neg.cc: Likewise. * testsuite/20_util/default_delete/48631_neg.cc: Likewise. * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Likewise. * testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise. * testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: Adjust dg-error text. * testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc: Use different instantiations so static_assert fails for each. Thanks to Geoffrey and Lawrence for input and test cases. Tested x86_64-linux, committed to trunk. commit 907290c8077e6757c56fc64c9160c4bdaea86b90 Author: Jonathan Wakely jwakely@gmail.com Date: Thu Dec 20 17:57:33 2012 + * include/std/functional (_Require): Move to ... * include/std/type_traits (_Require): ... here. * include/bits/shared_ptr_base.h (__shared_count::_S_create_from_up): Handle unique_ptr for arrays or with custom pointer types. (__shared_ptr::__shared_ptr(unique_ptr_Tp1, _Del): Likewise. * include/bits/unique_ptr.h (unique_ptr_Tp[], _Dp): Use _Dp::pointer if defined. Implement proposed resolution of LWG 2118. * testsuite/20_util/shared_ptr/cons/unique_ptr_array.cc: New. * testsuite/20_util/unique_ptr/assign/cv_qual.cc: New. * testsuite/20_util/unique_ptr/cons/array_convertible_neg.cc: New. * testsuite/20_util/unique_ptr/cons/convertible_neg.cc: New. * testsuite/20_util/unique_ptr/cons/cv_qual.cc: New. * testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: New. * testsuite/20_util/unique_ptr/requirements/pointer_type_array.cc: New. * testsuite/20_util/shared_ptr/cons/unique_ptr.cc: Adjust comments. * testsuite/20_util/unique_ptr/cons/pointer_array_convertible_neg.cc: Likewise. * testsuite/20_util/unique_ptr/requirements/pointer_type.cc: Likewise. * testsuite/20_util/bind/ref_neg.cc: Adjust dg-error line number. * testsuite/20_util/declval/requirements/1_neg.cc: Likewise. * testsuite/20_util/default_delete/48631_neg.cc: Likewise. * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Likewise. * testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise. * testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: Adjust dg-error text. * testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc: Use different instantiations so static_assert fails for each. diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index ead3728..9d9fecb 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -616,7 +616,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_create_from_up(std::unique_ptr_Tp, _Del __r, typename std::enable_if!std::is_reference_Del::value::type* = 0) { - return new _Sp_counted_deleter_Tp*, _Del, std::allocatorvoid, + typedef typename unique_ptr_Tp, _Del::pointer _Ptr; + return new _Sp_counted_deleter_Ptr, _Del, std::allocatorvoid, _Lp(__r.get(), __r.get_deleter()); } @@