-
Notifications
You must be signed in to change notification settings - Fork 97
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
Correctly handle assert_*
intrinsics
#742
Conversation
@zhassan-aws brought #648 to my attention, thanks!! Removing/Changing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests I see are for primitive types. Would it make sense to also ensure that we do the right thing for enums and structs?
@@ -567,6 +548,48 @@ impl<'tcx> GotocCtx<'tcx> { | |||
) | |||
} | |||
|
|||
/// Generates either a panic or no-op for `assert_*` intrinsics. | |||
/// These are intrinsics that statically compile to panics if the type | |||
/// layout is invalid so we get a message that mentions the offending type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reference to rust documentation here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added links to rust docs.
); | ||
} | ||
|
||
if intrinsic == "assert_uninit_valid" && !layout.might_permit_raw_init(self, false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a spec we can point to here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was not able to find one as documentation regarding these intrinsics is quite hard to find.
The closest thing I could find is the actual implementation in rustc_codegen_ssa/src/mir/block.rs
(codegen_panic_intrinsic
) in addition to PR discussions. But if you know of one I will be happy to add it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I think links directly to code serve as a reasonable reference, too. Maybe add that as a comment? (e.g. link directly to it on github?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main concern with that is that links to rustc
code may become outdated pretty quickly. But even that is better that no links, so just added a note here linking to that function.
|
||
// Then we check if the type allows "raw" initialization for the cases | ||
// where memory is zero-initialized or entirely uninitialized | ||
if intrinsic == "assert_zero_valid" && !layout.might_permit_raw_init(self, true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a spec we can point to here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
// The code below attempts to instantiate uninhabited type `!`. | ||
// This should cause the intrinsic `assert_inhabited` to generate a panic during | ||
// compilation, but at present it triggers the `Nevers` hook instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have a tracking issue for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created #751 which I linked here.
|
||
// The code below attempts to zero-initialize type `&i32`, causing the intrinsic | ||
// `assert_zero_valid` to generate a panic during compilation. | ||
fn main() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also have a test with an expected pass (e.g. zero initializing a u8
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test in src/test/rmc/Intrinsics/Assert/zero_valid.rs
(path updated in this PR) already does this for several types, including a user-defined struct.
); | ||
} | ||
|
||
if intrinsic == "assert_uninit_valid" && !layout.might_permit_raw_init(self, false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I think links directly to code serve as a reasonable reference, too. Maybe add that as a comment? (e.g. link directly to it on github?)
5cc5515
to
e20525f
Compare
e20525f
to
797ecc3
Compare
Description of changes:
Adds support for the
assert_uninit
andassert_zero
intrinsics. Inserts the code for them andassert_inhabited
into a single function.Resolved issues:
Resolves #6
Resolves #7
Call-outs:
assert_inhabited
first, then proceed to do the other ones. This proposal follows the same pattern.assert_inhabited
(i.e., insrc/test/rmc/Intrinsics/Assert/inhabited_panic.rs
) isThis is due to the
Nevers
hook being applied instead of theIntrinsics
one. I have tried doing some changes to the application condition (for example, returnfalse
if the instance is an intrinsic) to no success (ended up in some code that expected theNevers
hook to have applied).Assert
now contains the multiple assertions test only, and anotherAssert
folder has been created withinIntrinsics
to keep the tests related to the intrinsics in this PR.Testing:
How is this change tested? Existing regression + 3 new tests + 1 removed test.
Is this a refactor change? No.
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.