Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace zeroing-on-drop with filling-on-drop. #23535

Merged
merged 9 commits into from
Mar 28, 2015

Conversation

pnkfelix
Copy link
Member

Replace zeroing-on-drop with filling-on-drop.

This is meant to set the stage for removing all zeroing and filling (on drop) in the future.

Note that the code is meant to be entirely abstract with respect to the particular values used for the drop flags: the final commit demonstrates how to go from zeroing-on-drop to filling-on-drop by changing the value of three constants (in two files).

See further discussion on the internals thread:
http://internals.rust-lang.org/t/attention-hackers-filling-drop/1715/11

[breaking-change] especially for structs / enums using #[unsafe_no_drop_flag].

@rust-highfive
Copy link
Collaborator

r? @nrc

(rust_highfive has picked a reviewer for you, use r? to override)

@pnkfelix
Copy link
Member Author

r? @nikomatsakis

@rust-highfive rust-highfive assigned nikomatsakis and unassigned nrc Mar 19, 2015
/// to non-zeroing drop.
#[inline]
#[unstable(feature = "filling_drop")]
pub unsafe fn dropped<T>() -> T {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be a wrapper around init_dropped?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to make it such a wrapper at one point in the history of the PR, but I got tired of trying to work out the staging issues involved...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh.

I guess this might work? (it might not too.)

#[cfg(stage0)]
pub unsafe fn dropped<T>() -> T { zeroed() }
#[cfg(not(stage0))]
pub unsafe fn dropped<T>() -> T { intrinsics::init_dropped() }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay i will try that tomorrow morning

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah it works like a charm, thanks huon, now I feel dumb. :)

@pnkfelix
Copy link
Member Author

(@nrc notes that this PR is probably a good candidate for some run-pass-valgrind tests.)

@pnkfelix
Copy link
Member Author

I may add a lint for enums using #[unsafe_no_drop_flag] because this really breaks those. (Is anyone using them?)

@eddyb
Copy link
Member

eddyb commented Mar 20, 2015

@pnkfelix IME I don't recall ever seeing Drop implemented on enums, I wonder if we can quickly count them across the ecosystem.
The attribute itself applied on enums would be easy to grep for.

@nikomatsakis
Copy link
Contributor

Oh, man, I totally missed this PR! Sorry for the delay @pnkfelix

@nikomatsakis
Copy link
Contributor

r+ -- no real nits, just some questions

@pnkfelix
Copy link
Member Author

@bors try

@bors
Copy link
Contributor

bors commented Mar 25, 2015

⌛ Trying commit fc87aa8 with merge 6efae5d...

@bors
Copy link
Contributor

bors commented Mar 25, 2015

💔 Test failed - try-bsd

@pnkfelix
Copy link
Member Author

@bors try

@bors
Copy link
Contributor

bors commented Mar 25, 2015

⌛ Trying commit 94392c8 with merge 969b386...

bors added a commit that referenced this pull request Mar 25, 2015
Replace zeroing-on-drop with filling-on-drop.

This is meant to set the stage for removing *all* zeroing and filling (on drop) in the future.

Note that the code is meant to be entirely abstract with respect to the particular values used for the drop flags: the final commit demonstrates how to go from zeroing-on-drop to filling-on-drop by changing the value of three constants (in two files).

See further discussion on the internals thread:
  http://internals.rust-lang.org/t/attention-hackers-filling-drop/1715/11

[breaking-change] especially for structs / enums using `#[unsafe_no_drop_flag]`.
@bors
Copy link
Contributor

bors commented Mar 25, 2015

💔 Test failed - try-mac

@Manishearth
Copy link
Member

/Users/rustbuild/src/rust-buildbot/slave/try-mac/build/src/librustc_trans/trans/glue.rs:43:5: 43:33 error: unused import, #[deny(unused_imports)] on by default
/Users/rustbuild/src/rust-buildbot/slave/try-mac/build/src/librustc_trans/trans/glue.rs:43 use session::config::NoDebugInfo;
                                                                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
make: *** [x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/stamp.rustc_trans] Error 101
make: *** Waiting for unfinished jobs....

@pnkfelix
Copy link
Member Author

@bors try fd65e4f

@bors
Copy link
Contributor

bors commented Mar 26, 2015

⌛ Trying commit fd65e4f with merge a21e18f...

bors added a commit that referenced this pull request Mar 26, 2015
Replace zeroing-on-drop with filling-on-drop.

This is meant to set the stage for removing *all* zeroing and filling (on drop) in the future.

Note that the code is meant to be entirely abstract with respect to the particular values used for the drop flags: the final commit demonstrates how to go from zeroing-on-drop to filling-on-drop by changing the value of three constants (in two files).

See further discussion on the internals thread:
  http://internals.rust-lang.org/t/attention-hackers-filling-drop/1715/11

[breaking-change] especially for structs / enums using `#[unsafe_no_drop_flag]`.
@bors
Copy link
Contributor

bors commented Mar 26, 2015

💔 Test failed - try-mac

Refactored code so that the drop-flag values for initialized
(`DTOR_NEEDED`) versus dropped (`DTOR_DONE`) are given explicit names.

Add `mem::dropped()` (which with `DTOR_DONE == 0` is semantically the
same as `mem::zeroed`, but the point is that it abstracts away from
the particular choice of value for `DTOR_DONE`).

Filling-drop needs to use something other than `ptr::read_and_zero`,
so I added such a function: `ptr::read_and_drop`.  But, libraries
should not use it if they can otherwise avoid it.

Fixes to tests to accommodate filling-drop.
…ile-fail tests.

(I.e. the idea being, lets catch errors in these basic constructs
sometime *before* we start doing the doc tests.)
@bors
Copy link
Contributor

bors commented Mar 26, 2015

⌛ Trying commit e2cc8b1 with merge 961e035...

@bors
Copy link
Contributor

bors commented Mar 26, 2015

☀️ Test successful - try-bsd, try-linux, try-mac, try-win-32, try-win-64

@pnkfelix
Copy link
Member Author

@bors r=nikomatsakis e2cc8b1

@bors
Copy link
Contributor

bors commented Mar 26, 2015

⌛ Testing commit e2cc8b1 with merge b50bf4a...

@bors
Copy link
Contributor

bors commented Mar 26, 2015

💔 Test failed - auto-mac-64-opt

@pnkfelix
Copy link
Member Author

@bors r=nikomatsakis b68ca84

@bors
Copy link
Contributor

bors commented Mar 27, 2015

⌛ Testing commit b68ca84 with merge 74ab665...

@bors
Copy link
Contributor

bors commented Mar 27, 2015

💔 Test failed - auto-win-64-nopt-t

@pnkfelix
Copy link
Member Author

@bors retry

@bors
Copy link
Contributor

bors commented Mar 27, 2015

⌛ Testing commit b68ca84 with merge be7f6ac...

@bors
Copy link
Contributor

bors commented Mar 27, 2015

💔 Test failed - auto-win-32-nopt-t

@alexcrichton
Copy link
Member

@bors: retry

On Fri, Mar 27, 2015 at 10:59 AM, bors notifications@github.com wrote:

[image: 💔] Test failed - auto-win-32-nopt-t
http://buildbot.rust-lang.org/builders/auto-win-32-nopt-t/builds/3922


Reply to this email directly or view it on GitHub
#23535 (comment).

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Mar 27, 2015
Replace zeroing-on-drop with filling-on-drop.

This is meant to set the stage for removing *all* zeroing and filling (on drop) in the future.

Note that the code is meant to be entirely abstract with respect to the particular values used for the drop flags: the final commit demonstrates how to go from zeroing-on-drop to filling-on-drop by changing the value of three constants (in two files).

See further discussion on the internals thread:
  http://internals.rust-lang.org/t/attention-hackers-filling-drop/1715/11

[breaking-change] especially for structs / enums using `#[unsafe_no_drop_flag]`.
@bors
Copy link
Contributor

bors commented Mar 28, 2015

⌛ Testing commit b68ca84 with merge 46fa43d...

@pnkfelix
Copy link
Member Author

pnkfelix commented Jun 5, 2015

Note: #26025 points out a potential bug injected by filling-drop; namely, there is a switch on the discriminant of an enum, which will now be set to a value outside the range of typical discriminants, and ends up jumping into an unreachable block of the switch (which is then treated as undefined-behavior by LLVM).

@eddyb
Copy link
Member

eddyb commented Jun 5, 2015

@pnkfelix but wouldn't there be a check for that value before the match on the discriminant?
Though I'm not aware of all the filling-drop details.

When I suggested the "poke as little to disable all possible dtors" interim solution, enum variants were the interesting case, because you could search for a variant with little (or no, e.g. None) data that could drop and set the discriminant to it.

Is that viable at all here? Or since this is a temporary measure, after all, maybe just add a case for the discriminant being filled with the value - but what if it's a valid discriminant for that enum?
Oh, it doesn't matter, because the data inside should be inert as well.

@pnkfelix
Copy link
Member Author

pnkfelix commented Jun 5, 2015

@eddyb we might need to add such a check-before-switch if filling-drop stays as it is today. But historically, as I understand it from what niko tells me, we were relying on the fact that every enum that could implement Drop also had 0 as a valid discriminant, and thus the compiler was freely inspecting the discriminant even on moved/dropped enum values.

I don't know how viable it would be to attempt to fill with a "valid" enum variant. It seems sort of sketchy to me; it would require the filling code to be more aware of structural layout than it is today... I'd prefer to invest effort in finishing nonzeroing drop.

@eddyb
Copy link
Member

eddyb commented Jun 5, 2015

@alexcrichton's ret void seems fine as long as it's limited to drop glue - I just checked #26025 and it isn't; might not be hard to add a parameter controlling that.

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

Successfully merging this pull request may close these issues.

9 participants