forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of rust-lang#118534 - RalfJung:extern-type-size-of-val, r=…
…WaffleLapkin codegen: panic when trying to compute size/align of extern type The alignment is also computed when accessing a field of extern type at non-zero offset, so we also panic in that case. Previously `size_of_val` worked because the code path there assumed that "thin pointer" means "sized". But that's not true any more with extern types. The returned size and align are just blatantly wrong, so it seems better to panic than returning wrong results. We use a non-unwinding panic since code probably does not expect size_of_val to panic.
- Loading branch information
Showing
18 changed files
with
211 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 0 additions & 55 deletions
55
compiler/rustc_codegen_cranelift/example/issue-91827-extern-types.rs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#![feature(extern_types)] | ||
|
||
extern "C" { | ||
type Opaque; | ||
} | ||
|
||
struct Newtype(Opaque); | ||
|
||
struct S { | ||
i: i32, | ||
j: i32, | ||
a: Newtype, | ||
} | ||
|
||
fn main() { | ||
let buf = [0i32; 4]; | ||
|
||
let x: &Newtype = unsafe { &*(&buf as *const _ as *const Newtype) }; | ||
// Projecting to the newtype works, because it is always at offset 0. | ||
let _field = &x.0; | ||
|
||
let x: &S = unsafe { &*(&buf as *const _ as *const S) }; | ||
// Accessing sized fields is perfectly fine, even at non-zero offsets. | ||
let _field = &x.i; | ||
let _field = &x.j; | ||
// This needs to compute the field offset, but we don't know the type's alignment, | ||
// so this panics. | ||
let _field = &x.a; //~ERROR: does not have a known offset | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
error: unsupported operation: `extern type` does not have a known offset | ||
--> $DIR/extern-type-field-offset.rs:LL:CC | ||
| | ||
LL | let _field = &x.a; | ||
| ^^^^ `extern type` does not have a known offset | ||
| | ||
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support | ||
= note: BACKTRACE: | ||
= note: inside `main` at $DIR/extern-type-field-offset.rs:LL:CC | ||
|
||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | ||
|
||
error: aborting due to 1 previous error | ||
|
43 changes: 43 additions & 0 deletions
43
tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// Test that we can handle unsized types with an extern type tail part. | ||
// Regression test for issue #91827. | ||
|
||
#![feature(extern_types)] | ||
|
||
use std::ptr::addr_of; | ||
|
||
extern "C" { | ||
type Opaque; | ||
} | ||
|
||
struct Newtype(Opaque); | ||
|
||
struct S { | ||
i: i32, | ||
j: i32, | ||
a: Newtype, | ||
} | ||
|
||
const NEWTYPE: () = unsafe { | ||
let buf = [0i32; 4]; | ||
let x: &Newtype = &*(&buf as *const _ as *const Newtype); | ||
|
||
// Projecting to the newtype works, because it is always at offset 0. | ||
let field = &x.0; | ||
}; | ||
|
||
const OFFSET: () = unsafe { | ||
let buf = [0i32; 4]; | ||
let x: &S = &*(&buf as *const _ as *const S); | ||
|
||
// Accessing sized fields is perfectly fine, even at non-zero offsets. | ||
let field = &x.i; | ||
let field = &x.j; | ||
|
||
// This needs to compute the field offset, but we don't know the type's alignment, so this | ||
// fails. | ||
let field = &x.a; | ||
//~^ ERROR: evaluation of constant value failed | ||
//~| does not have a known offset | ||
}; | ||
|
||
fn main() {} |
9 changes: 9 additions & 0 deletions
9
tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
error[E0080]: evaluation of constant value failed | ||
--> $DIR/issue-91827-extern-types-field-offset.rs:38:17 | ||
| | ||
LL | let field = &x.a; | ||
| ^^^^ `extern type` does not have a known offset | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0080`. |
Oops, something went wrong.