about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-12-13 08:33:05 +0000
committerbors <bors@rust-lang.org>2023-12-13 08:33:05 +0000
commit2fdd9eda0ce4fa0ecbf3099783f4f505235ceb44 (patch)
tree7b71f6689b6d293b08c6d48b0fb834f0da1f1dc6 /src
parentf651b436ce70a6f89ec1636fbedb128a473d809b (diff)
parentf813ccd7840e7aee205d39be06166e5cbdaf54e3 (diff)
downloadrust-2fdd9eda0ce4fa0ecbf3099783f4f505235ceb44.tar.gz
rust-2fdd9eda0ce4fa0ecbf3099783f4f505235ceb44.zip
Auto merge of #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.
Diffstat (limited to 'src')
-rw-r--r--src/tools/miri/tests/fail/extern-type-field-offset.rs29
-rw-r--r--src/tools/miri/tests/fail/extern-type-field-offset.stderr14
2 files changed, 43 insertions, 0 deletions
diff --git a/src/tools/miri/tests/fail/extern-type-field-offset.rs b/src/tools/miri/tests/fail/extern-type-field-offset.rs
new file mode 100644
index 00000000000..139405fc374
--- /dev/null
+++ b/src/tools/miri/tests/fail/extern-type-field-offset.rs
@@ -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
+}
diff --git a/src/tools/miri/tests/fail/extern-type-field-offset.stderr b/src/tools/miri/tests/fail/extern-type-field-offset.stderr
new file mode 100644
index 00000000000..cbbf1b38361
--- /dev/null
+++ b/src/tools/miri/tests/fail/extern-type-field-offset.stderr
@@ -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
+