Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pybind11
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
pybind11
Commits
02e09035
Commit
02e09035
authored
Dec 22, 2020
by
Ralf W. Grosse-Kunstleve
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Additional demonstration of Undefined Behavior in handling of shared_ptr holder.
parent
d8796bb1
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
23 additions
and
3 deletions
+23
-3
tests/test_smart_ptr_private_first_base.cpp
+13
-2
tests/test_smart_ptr_private_first_base.py
+10
-1
No files found.
tests/test_smart_ptr_private_first_base.cpp
View file @
02e09035
...
@@ -3,8 +3,12 @@
...
@@ -3,8 +3,12 @@
// https://github.com/pybind/pybind11/blob/30eb39ed79d1e2eeff15219ac00773034300a5e6/include/pybind11/cast.h#L235
// https://github.com/pybind/pybind11/blob/30eb39ed79d1e2eeff15219ac00773034300a5e6/include/pybind11/cast.h#L235
// `return reinterpret_cast<H &>(vh[1]);`
// `return reinterpret_cast<H &>(vh[1]);`
// indirectly casts a `shared_ptr<drvd>` reference to a `shared_ptr<base>`.
// indirectly casts a `shared_ptr<drvd>` reference to a `shared_ptr<base>`.
// `test_smart_ptr_private_first_base.py` fails with an AssertionError and
// Similarly:
// a subsequent Segmentation Fault (Linux, clang++ -std=c++17).
// https://github.com/pybind/pybind11/blob/30eb39ed79d1e2eeff15219ac00773034300a5e6/include/pybind11/pybind11.h#L1505
// `init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>());`
// explictly casts a `shared_ptr<base>` reference to a `shared_ptr<drvd>`.
// Both tests in `test_smart_ptr_private_first_base.py` fail with a
// Segmentation Fault (Linux, clang++ -std=c++17).
#include <memory>
#include <memory>
...
@@ -33,14 +37,21 @@ inline std::shared_ptr<drvd> make_shared_drvd() {
...
@@ -33,14 +37,21 @@ inline std::shared_ptr<drvd> make_shared_drvd() {
return
std
::
shared_ptr
<
drvd
>
(
new
drvd
);
return
std
::
shared_ptr
<
drvd
>
(
new
drvd
);
}
}
inline
std
::
shared_ptr
<
base
>
make_shared_drvd_up_cast
()
{
return
std
::
shared_ptr
<
base
>
(
new
drvd
);
}
inline
int
pass_shared_base
(
std
::
shared_ptr
<
base
>
b
)
{
return
b
->
id
();
}
inline
int
pass_shared_base
(
std
::
shared_ptr
<
base
>
b
)
{
return
b
->
id
();
}
inline
int
pass_shared_drvd
(
std
::
shared_ptr
<
drvd
>
d
)
{
return
d
->
id
();
}
TEST_SUBMODULE
(
smart_ptr_private_first_base
,
m
)
{
TEST_SUBMODULE
(
smart_ptr_private_first_base
,
m
)
{
py
::
class_
<
base
,
std
::
shared_ptr
<
base
>>
(
m
,
"base"
);
py
::
class_
<
base
,
std
::
shared_ptr
<
base
>>
(
m
,
"base"
);
py
::
class_
<
drvd
,
base
,
std
::
shared_ptr
<
drvd
>>
(
m
,
"drvd"
);
py
::
class_
<
drvd
,
base
,
std
::
shared_ptr
<
drvd
>>
(
m
,
"drvd"
);
m
.
def
(
"make_shared_drvd"
,
make_shared_drvd
);
m
.
def
(
"make_shared_drvd"
,
make_shared_drvd
);
m
.
def
(
"make_shared_drvd_up_cast"
,
make_shared_drvd_up_cast
);
m
.
def
(
"pass_shared_base"
,
pass_shared_base
);
m
.
def
(
"pass_shared_base"
,
pass_shared_base
);
m
.
def
(
"pass_shared_drvd"
,
pass_shared_drvd
);
}
}
}
// namespace smart_ptr_private_first_base
}
// namespace smart_ptr_private_first_base
...
...
tests/test_smart_ptr_private_first_base.py
View file @
02e09035
...
@@ -3,7 +3,16 @@ import pytest
...
@@ -3,7 +3,16 @@ import pytest
from
pybind11_tests
import
smart_ptr_private_first_base
as
m
from
pybind11_tests
import
smart_ptr_private_first_base
as
m
def
test_make_pass
():
def
test_make_drvd_pass_base
():
d
=
m
.
make_shared_drvd
()
d
=
m
.
make_shared_drvd
()
i
=
m
.
pass_shared_base
(
d
)
i
=
m
.
pass_shared_base
(
d
)
assert
i
==
200
assert
i
==
200
def
test_make_drvd_up_cast_pass_drvd
():
b
=
m
.
make_shared_drvd_up_cast
()
# the base return is up-cast immediately.
assert
b
.
__class__
.
__name__
==
"drvd"
i
=
m
.
pass_shared_drvd
(
b
)
assert
i
==
200
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