-
Notifications
You must be signed in to change notification settings - Fork 386
Validate more things #477
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
Validate more things #477
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,3 @@ | ||
//ignore-test FIXME: do some basic validation of invariants for all values in flight | ||
//This does currently not get caught becuase it compiles to SwitchInt, which | ||
//has no knowledge about data invariants. | ||
|
||
fn main() { | ||
let b = unsafe { std::mem::transmute::<u8, bool>(2) }; | ||
if b { unreachable!() } else { unreachable!() } //~ ERROR constant evaluation error | ||
//~^ NOTE invalid boolean value read | ||
let _b = unsafe { std::mem::transmute::<u8, bool>(2) }; //~ ERROR encountered 2, but expected something in the range 0..=1 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
fn main() { | ||
assert!(std::char::from_u32(-1_i32 as u32).is_none()); | ||
let _ = match unsafe { std::mem::transmute::<i32, char>(-1) } { //~ ERROR encountered 4294967295, but expected something in the range 0..=1114111 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. char has a range? what's going on here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes it does? It must be a valid unicode codepoint. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought char's value ranges had gaps and were generally totally insane. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It has gaps. Remember we do first layout-based validation and then type-based validation. This value is so out of range it is already caught by the first. But if that's too low, our layout code would be wrong and that would be BAD (TM). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The maximal value currently seems to be 0x10ffff. In decimal that's 1114111. Maybe we should make validation print the range in hexadecimal... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nah seems fine. Or we could print both. It's not really clear what is more readable... |
||
'a' => {true}, | ||
'b' => {false}, | ||
_ => {true}, | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,8 @@ | ||
// Validation makes this fail in the wrong place | ||
// compile-flags: -Zmir-emit-validate=0 | ||
|
||
#[repr(C)] | ||
pub enum Foo { | ||
A, B, C, D | ||
} | ||
|
||
fn main() { | ||
let f = unsafe { std::mem::transmute::<i32, Foo>(42) }; | ||
match f { | ||
Foo::A => {}, //~ ERROR invalid enum discriminant | ||
Foo::B => {}, | ||
Foo::C => {}, | ||
Foo::D => {}, | ||
} | ||
let _f = unsafe { std::mem::transmute::<i32, Foo>(42) }; //~ ERROR encountered invalid enum discriminant 42 | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
fn main() { | ||
// Cast a function pointer such that on a call, the argument gets transmuted | ||
// from raw ptr to reference. This is ABI-compatible, so it's not the call that | ||
// should fail, but validation should. | ||
fn f(_x: &i32) { } | ||
|
||
let g: fn(*const i32) = unsafe { std::mem::transmute(f as fn(&i32)) }; | ||
|
||
g(0usize as *const i32) //~ ERROR encountered 0, but expected something greater or equal to 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sweet |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
fn main() { | ||
// Cast a function pointer such that when returning, the return value gets transmuted | ||
// from raw ptr to reference. This is ABI-compatible, so it's not the call that | ||
// should fail, but validation should. | ||
fn f() -> *const i32 { 0usize as *const i32 } | ||
|
||
let g: fn() -> &'static i32 = unsafe { std::mem::transmute(f as fn() -> *const i32) }; | ||
|
||
let _x = g(); //~ ERROR encountered 0, but expected something greater or equal to 1 | ||
} |
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.
lol, the last 3 stackframes!?
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.
Yeah well, I had to pick some number. I didn't want to manually whitelist all callees, but also didn't want to walk up the entire stack.
It's a hack to even have a whitelist, so... whatever?^^