Skip to content

Commit fbe9109

Browse files
authored
Merge pull request #19 from facebookexperimental/from_raw_ub
Fix UB in from_raw
2 parents a596961 + d82da9e commit fbe9109

4 files changed

Lines changed: 32 additions & 27 deletions

File tree

include/cxx.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,10 @@ void Option<T&>::reset() {
10051005

10061006
template <typename T>
10071007
Option<T&> Option<T&>::from_raw(T* ptr) noexcept {
1008-
Option<T&> opt{*ptr};
1008+
Option<T&> opt;
1009+
if (ptr) {
1010+
opt.set(*ptr);
1011+
}
10091012
return opt;
10101013
}
10111014

@@ -1083,7 +1086,10 @@ void Option<const T&>::reset() {
10831086

10841087
template <typename T>
10851088
Option<const T&> Option<const T&>::from_raw(const T* ptr) noexcept {
1086-
Option<const T&> opt{*ptr};
1089+
Option<const T&> opt;
1090+
if (ptr) {
1091+
opt.set(*ptr);
1092+
}
10871093
return opt;
10881094
}
10891095

@@ -1154,7 +1160,10 @@ void Option<Box<T>>::reset() {
11541160

11551161
template <typename T>
11561162
Option<Box<T>> Option<Box<T>>::from_raw(T* ptr) noexcept {
1157-
Option<Box<T>> opt{Box<T>::from_raw(ptr)};
1163+
Option<Box<T>> opt;
1164+
if (ptr) {
1165+
opt.set(Box<T>::from_raw(ptr));
1166+
}
11581167
return opt;
11591168
}
11601169

tests/ui/option_not_sized.stderr

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be know
44
2 | const _: cxx::RustOption::<&dyn core::fmt::Debug> = cxx::RustOption::<&dyn core::fmt::Debug>::new();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
66
|
7-
= help: the trait `Sized` is not implemented for `(dyn Debug + 'static)`, which is required by `&'static (dyn Debug + 'static): cxx::rust_option::OptionTarget`
7+
= help: the trait `Sized` is not implemented for `(dyn Debug + 'static)`
88
= help: the following other types implement trait `cxx::rust_option::OptionTarget`:
99
&T
1010
&mut T
@@ -17,28 +17,13 @@ note: required by a bound in `RustOption`
1717
| pub struct RustOption<T: OptionTarget> {
1818
| ^^^^^^^^^^^^ required by this bound in `RustOption`
1919

20-
error[E0599]: the function or associated item `new` exists for struct `RustOption<&dyn Debug>`, but its trait bounds were not satisfied
21-
--> tests/ui/option_not_sized.rs:2:99
22-
|
23-
2 | const _: cxx::RustOption::<&dyn core::fmt::Debug> = cxx::RustOption::<&dyn core::fmt::Debug>::new();
24-
| ^^^ function or associated item cannot be called on `RustOption<&dyn Debug>` due to unsatisfied trait bounds
25-
|
26-
::: $RUST/core/src/fmt/mod.rs
27-
|
28-
| pub trait Debug {
29-
| --------------- doesn't satisfy `dyn Debug: Sized`
30-
|
31-
= note: the following trait bounds were not satisfied:
32-
`dyn Debug: Sized`
33-
which is required by `&dyn Debug: cxx::rust_option::OptionTarget`
34-
3520
error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time
3621
--> tests/ui/option_not_sized.rs:2:57
3722
|
3823
2 | const _: cxx::RustOption::<&dyn core::fmt::Debug> = cxx::RustOption::<&dyn core::fmt::Debug>::new();
3924
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
4025
|
41-
= help: the trait `Sized` is not implemented for `(dyn Debug + 'static)`, which is required by `&'static (dyn Debug + 'static): cxx::rust_option::OptionTarget`
26+
= help: the trait `Sized` is not implemented for `(dyn Debug + 'static)`
4227
= help: the following other types implement trait `cxx::rust_option::OptionTarget`:
4328
&T
4429
&mut T
@@ -57,7 +42,7 @@ error[E0277]: the size for values of type `dyn Debug` cannot be known at compila
5742
2 | const _: cxx::RustOption::<&dyn core::fmt::Debug> = cxx::RustOption::<&dyn core::fmt::Debug>::new();
5843
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
5944
|
60-
= help: the trait `Sized` is not implemented for `dyn Debug`, which is required by `&dyn Debug: cxx::rust_option::OptionTarget`
45+
= help: the trait `Sized` is not implemented for `dyn Debug`
6146
= help: the following other types implement trait `cxx::rust_option::OptionTarget`:
6247
&T
6348
&mut T
@@ -69,3 +54,18 @@ note: required by a bound in `RustOption`
6954
|
7055
| pub struct RustOption<T: OptionTarget> {
7156
| ^^^^^^^^^^^^ required by this bound in `RustOption`
57+
58+
error[E0599]: the function or associated item `new` exists for struct `RustOption<&dyn Debug>`, but its trait bounds were not satisfied
59+
--> tests/ui/option_not_sized.rs:2:99
60+
|
61+
2 | const _: cxx::RustOption::<&dyn core::fmt::Debug> = cxx::RustOption::<&dyn core::fmt::Debug>::new();
62+
| ^^^ function or associated item cannot be called on `RustOption<&dyn Debug>` due to unsatisfied trait bounds
63+
|
64+
::: $RUST/core/src/fmt/mod.rs
65+
|
66+
| pub trait Debug {
67+
| --------------- doesn't satisfy `dyn Debug: Sized`
68+
|
69+
= note: the following trait bounds were not satisfied:
70+
`dyn Debug: Sized`
71+
which is required by `&dyn Debug: cxx::rust_option::OptionTarget`

tests/ui/option_safe_unsized.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ error[E0080]: evaluation of `cxx::private::assert_option_safe::__SizeCheck::<&st
22
--> src/rust_option.rs
33
|
44
| const _IS_OPTION_SIZE: () = assert!(mem::size_of::<Option<U>>() == mem::size_of::<Repr>());
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: mem::size_of::<Option<U>>() == mem::size_of::<Repr>()', $DIR/src/rust_option.rs:51:37
6-
|
7-
= note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: assertion failed: mem::size_of::<Option<U>>() == mem::size_of::<Repr>()
86

97
note: erroneous constant encountered
108
--> src/rust_option.rs

tests/ui/option_safe_usize.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ error[E0080]: evaluation of `cxx::private::assert_option_safe::__SizeCheck::<usi
22
--> src/rust_option.rs
33
|
44
| const _IS_OPTION_SIZE: () = assert!(mem::size_of::<Option<U>>() == mem::size_of::<Repr>());
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: mem::size_of::<Option<U>>() == mem::size_of::<Repr>()', $DIR/src/rust_option.rs:51:37
6-
|
7-
= note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation panicked: assertion failed: mem::size_of::<Option<U>>() == mem::size_of::<Repr>()
86

97
note: erroneous constant encountered
108
--> src/rust_option.rs

0 commit comments

Comments
 (0)