Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
f4eec655
Commit
f4eec655
authored
Oct 22, 2016
by
Wenzel Jakob
Committed by
GitHub
Oct 22, 2016
Browse files
Merge pull request #455 from bennorth/bugfix/bad-delete-if-no-copy-ctor
Bugfix: bad delete if no copy ctor
parents
43a88f45
bbe45082
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
91 additions
and
15 deletions
+91
-15
include/pybind11/cast.h
include/pybind11/cast.h
+32
-15
tests/CMakeLists.txt
tests/CMakeLists.txt
+1
-0
tests/test_copy_move_policies.cpp
tests/test_copy_move_policies.cpp
+41
-0
tests/test_copy_move_policies.py
tests/test_copy_move_policies.py
+17
-0
No files found.
include/pybind11/cast.h
View file @
f4eec655
...
@@ -258,31 +258,48 @@ public:
...
@@ -258,31 +258,48 @@ public:
auto
wrapper
=
(
instance
<
void
>
*
)
inst
.
ptr
();
auto
wrapper
=
(
instance
<
void
>
*
)
inst
.
ptr
();
wrapper
->
value
=
src
;
wrapper
->
value
=
nullptr
;
wrapper
->
owned
=
true
;
wrapper
->
owned
=
false
;
if
(
policy
==
return_value_policy
::
automatic
)
switch
(
policy
)
{
policy
=
return_value_policy
::
take_ownership
;
case
return_value_policy
::
automatic
:
else
if
(
policy
==
return_value_policy
::
automatic_reference
)
case
return_value_policy
::
take_ownership
:
policy
=
return_value_policy
::
reference
;
wrapper
->
value
=
src
;
wrapper
->
owned
=
true
;
break
;
case
return_value_policy
::
automatic_reference
:
case
return_value_policy
::
reference
:
wrapper
->
value
=
src
;
wrapper
->
owned
=
false
;
break
;
if
(
policy
==
return_value_policy
::
copy
)
{
case
return_value_policy
::
copy
:
if
(
copy_constructor
)
if
(
copy_constructor
)
wrapper
->
value
=
copy_constructor
(
wrapper
->
value
);
wrapper
->
value
=
copy_constructor
(
src
);
else
else
throw
cast_error
(
"return_value_policy = copy, but the object is non-copyable!"
);
throw
cast_error
(
"return_value_policy = copy, but the object is non-copyable!"
);
}
else
if
(
policy
==
return_value_policy
::
move
)
{
wrapper
->
owned
=
true
;
break
;
case
return_value_policy
::
move
:
if
(
move_constructor
)
if
(
move_constructor
)
wrapper
->
value
=
move_constructor
(
wrapper
->
value
);
wrapper
->
value
=
move_constructor
(
src
);
else
if
(
copy_constructor
)
else
if
(
copy_constructor
)
wrapper
->
value
=
copy_constructor
(
wrapper
->
value
);
wrapper
->
value
=
copy_constructor
(
src
);
else
else
throw
cast_error
(
"return_value_policy = move, but the object is neither movable nor copyable!"
);
throw
cast_error
(
"return_value_policy = move, but the object is neither movable nor copyable!"
);
}
else
if
(
policy
==
return_value_policy
::
reference
)
{
wrapper
->
owned
=
true
;
wrapper
->
owned
=
false
;
break
;
}
else
if
(
policy
==
return_value_policy
::
reference_internal
)
{
case
return_value_policy
::
reference_internal
:
wrapper
->
value
=
src
;
wrapper
->
owned
=
false
;
wrapper
->
owned
=
false
;
detail
::
keep_alive_impl
(
inst
,
parent
);
detail
::
keep_alive_impl
(
inst
,
parent
);
break
;
default:
throw
cast_error
(
"unhandled return_value_policy: should not happen!"
);
}
}
tinfo
->
init_holder
(
inst
.
ptr
(),
existing_holder
);
tinfo
->
init_holder
(
inst
.
ptr
(),
existing_holder
);
...
...
tests/CMakeLists.txt
View file @
f4eec655
...
@@ -12,6 +12,7 @@ set(PYBIND11_TEST_FILES
...
@@ -12,6 +12,7 @@ set(PYBIND11_TEST_FILES
test_chrono.cpp
test_chrono.cpp
test_class_args.cpp
test_class_args.cpp
test_constants_and_functions.cpp
test_constants_and_functions.cpp
test_copy_move_policies.cpp
test_eigen.cpp
test_eigen.cpp
test_enum.cpp
test_enum.cpp
test_eval.cpp
test_eval.cpp
...
...
tests/test_copy_move_policies.cpp
0 → 100644
View file @
f4eec655
/*
tests/test_copy_move_policies.cpp -- 'copy' and 'move'
return value policies
Copyright (c) 2016 Ben North <ben@redfrontdoor.org>
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.
*/
#include "pybind11_tests.h"
template
<
typename
derived
>
struct
empty
{
static
const
derived
&
get_one
()
{
return
instance_
;
}
static
derived
instance_
;
};
struct
lacking_copy_ctor
:
public
empty
<
lacking_copy_ctor
>
{
lacking_copy_ctor
()
{}
lacking_copy_ctor
(
const
lacking_copy_ctor
&
other
)
=
delete
;
};
template
<
>
lacking_copy_ctor
empty
<
lacking_copy_ctor
>::
instance_
{};
struct
lacking_move_ctor
:
public
empty
<
lacking_move_ctor
>
{
lacking_move_ctor
()
{}
lacking_move_ctor
(
const
lacking_move_ctor
&
other
)
=
delete
;
lacking_move_ctor
(
lacking_move_ctor
&&
other
)
=
delete
;
};
template
<
>
lacking_move_ctor
empty
<
lacking_move_ctor
>::
instance_
{};
test_initializer
copy_move_policies
([](
py
::
module
&
m
)
{
py
::
class_
<
lacking_copy_ctor
>
(
m
,
"lacking_copy_ctor"
)
.
def_static
(
"get_one"
,
&
lacking_copy_ctor
::
get_one
,
py
::
return_value_policy
::
copy
);
py
::
class_
<
lacking_move_ctor
>
(
m
,
"lacking_move_ctor"
)
.
def_static
(
"get_one"
,
&
lacking_move_ctor
::
get_one
,
py
::
return_value_policy
::
move
);
});
tests/test_copy_move_policies.py
0 → 100644
View file @
f4eec655
import
pytest
def
test_lacking_copy_ctor
():
from
pybind11_tests
import
lacking_copy_ctor
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
lacking_copy_ctor
.
get_one
()
assert
"the object is non-copyable!"
in
str
(
excinfo
.
value
)
def
test_lacking_move_ctor
():
from
pybind11_tests
import
lacking_move_ctor
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
lacking_move_ctor
.
get_one
()
assert
"the object is neither movable nor copyable!"
in
str
(
excinfo
.
value
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment