Re: [patch] std::unique_ptrT[], D improvements

2013-01-03 Thread Lawrence Crowl
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

2013-01-01 Thread Lawrence Crowl
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

2013-01-01 Thread Jonathan Wakely
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

2013-01-01 Thread Lawrence Crowl
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

2012-12-28 Thread Jonathan Wakely
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

2012-12-27 Thread Lawrence Crowl
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

2012-12-20 Thread Jonathan Wakely
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());
}
 
@@