mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
Rollup merge of #58192 - dlrobertson:fix_57876, r=oli-obk
Do not ICE in codegen when using a extern_type static The layout of a extern_type static is unsized, but may pass the Well-Formed check in typeck (See #55257). As a result, we cannot assume that a static is sized when generating the `Place` for an r-value. Fixes: #57876 r? @oli-obk
This commit is contained in:
commit
7168eadafe
@ -41,6 +41,21 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> {
|
||||
}
|
||||
}
|
||||
|
||||
fn new_thin_place<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
|
||||
bx: &mut Bx,
|
||||
llval: V,
|
||||
layout: TyLayout<'tcx>,
|
||||
align: Align,
|
||||
) -> PlaceRef<'tcx, V> {
|
||||
assert!(!bx.cx().type_has_metadata(layout.ty));
|
||||
PlaceRef {
|
||||
llval,
|
||||
llextra: None,
|
||||
layout,
|
||||
align
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloca<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
|
||||
bx: &mut Bx,
|
||||
layout: TyLayout<'tcx>,
|
||||
@ -421,8 +436,10 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
}
|
||||
mir::Place::Static(box mir::Static { def_id, ty }) => {
|
||||
// NB: The layout of a static may be unsized as is the case when working
|
||||
// with a static that is an extern_type.
|
||||
let layout = cx.layout_of(self.monomorphize(&ty));
|
||||
PlaceRef::new_sized(bx.get_static(def_id), layout, layout.align.abi)
|
||||
PlaceRef::new_thin_place(bx, bx.get_static(def_id), layout, layout.align.abi)
|
||||
},
|
||||
mir::Place::Projection(box mir::Projection {
|
||||
ref base,
|
||||
|
5
src/test/run-make-fulldeps/static-extern-type/Makefile
Normal file
5
src/test/run-make-fulldeps/static-extern-type/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all: $(call NATIVE_STATICLIB,define-foo)
|
||||
$(RUSTC) -ldefine-foo use-foo.rs
|
||||
$(call RUN,use-foo) || exit 1
|
11
src/test/run-make-fulldeps/static-extern-type/define-foo.c
Normal file
11
src/test/run-make-fulldeps/static-extern-type/define-foo.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <stdint.h>
|
||||
|
||||
struct Foo {
|
||||
uint8_t x;
|
||||
};
|
||||
|
||||
struct Foo FOO = { 42 };
|
||||
|
||||
uint8_t bar(const struct Foo* foo) {
|
||||
return foo->x;
|
||||
}
|
14
src/test/run-make-fulldeps/static-extern-type/use-foo.rs
Normal file
14
src/test/run-make-fulldeps/static-extern-type/use-foo.rs
Normal file
@ -0,0 +1,14 @@
|
||||
#![feature(extern_types)]
|
||||
|
||||
extern "C" {
|
||||
type Foo;
|
||||
static FOO: Foo;
|
||||
fn bar(foo: *const Foo) -> u8;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let foo = &FOO;
|
||||
assert_eq!(bar(foo), 42);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user