Skip to content
This repository has been archived by the owner on Feb 7, 2021. It is now read-only.

Undefined Behavior when T is zero-sized #5

Closed
TyPR124 opened this issue Feb 7, 2020 · 7 comments · Fixed by #7
Closed

Undefined Behavior when T is zero-sized #5

TyPR124 opened this issue Feb 7, 2020 · 7 comments · Fixed by #7

Comments

@TyPR124
Copy link
Contributor

TyPR124 commented Feb 7, 2020

stowaway/src/lib.rs

Lines 212 to 217 in fb1d8d1

pub fn new(value: T) -> Self {
let storage = match Self::size_class() {
SizeClass::Zero => {
mem::forget(value);
ptr::null_mut()
}

SizeClass::Zero => unsafe { ptr::read(storage) },

Per ptr::read: Note that even if T has size 0, the pointer must be non-NULL and properly aligned.

https://doc.rust-lang.org/std/ptr/fn.read.html

@TyPR124
Copy link
Contributor Author

TyPR124 commented Feb 7, 2020

I also want to point out that this is very much NOT fine, as ALL references must be non-null.

stowaway/src/lib.rs

Lines 537 to 540 in fb1d8d1

fn as_ref(&self) -> &T {
let ptr_to_storage = match Self::size_class() {
// In the ZST case, ptr::read is a no-op, so the null ptr here is fine
SizeClass::Zero => self.storage,

unsafe { &*ptr_to_storage }

@Lucretiel
Copy link
Owner

Lucretiel commented Feb 7, 2020

I also want to point out that this is very much NOT fine, as ALL references must be non-null.

Are you certain this is the case? This contradicts the nomicon:

So if the allocator API doesn't support zero-sized allocations, what on earth do we store as our allocation? Unique::empty() of course! Almost every operation with a ZST is a no-op since ZSTs have exactly one value, and therefore no state needs to be considered to store or load them. This actually extends to ptr::read and ptr::write: they won't actually look at the pointer at all. As such we never need to change the pointer.

@Lucretiel
Copy link
Owner

Opened rust-lang/nomicon#198

@TyPR124
Copy link
Contributor Author

TyPR124 commented Feb 7, 2020 via email

@TyPR124
Copy link
Contributor Author

TyPR124 commented Feb 7, 2020 via email

@TyPR124
Copy link
Contributor Author

TyPR124 commented Feb 7, 2020 via email

@TyPR124
Copy link
Contributor Author

TyPR124 commented Feb 10, 2020

Here is an assembly comparison between Box and Stowaway using mem::align_of::<T>() for ZSTs, per discussion in #4.

https://rust.godbolt.org/z/cFsRij

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants