Skip to content

Commit 80c052b

Browse files
committed
Do not ICE in codegen given a extern_type static
The layout of a extern_type static is unsized, but may pass the Well-Formed check in typeck. As a result, we cannot assume that a static is sized when generating the `Place` for an r-value.
1 parent b2c6b8c commit 80c052b

File tree

4 files changed

+48
-1
lines changed

4 files changed

+48
-1
lines changed

src/librustc_codegen_ssa/mir/place.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,21 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> {
4141
}
4242
}
4343

44+
fn new_thin_place<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
45+
bx: &mut Bx,
46+
llval: V,
47+
layout: TyLayout<'tcx>,
48+
align: Align,
49+
) -> PlaceRef<'tcx, V> {
50+
assert!(!bx.cx().type_has_metadata(layout.ty));
51+
PlaceRef {
52+
llval,
53+
llextra: None,
54+
layout,
55+
align
56+
}
57+
}
58+
4459
pub fn alloca<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
4560
bx: &mut Bx,
4661
layout: TyLayout<'tcx>,
@@ -421,8 +436,10 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
421436
}
422437
}
423438
mir::Place::Static(box mir::Static { def_id, ty }) => {
439+
// NB: The layout of a static may be unsized as is the case when working
440+
// with a static that is an extern_type.
424441
let layout = cx.layout_of(self.monomorphize(&ty));
425-
PlaceRef::new_sized(bx.get_static(def_id), layout, layout.align.abi)
442+
PlaceRef::new_thin_place(bx, bx.get_static(def_id), layout, layout.align.abi)
426443
},
427444
mir::Place::Projection(box mir::Projection {
428445
ref base,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-include ../tools.mk
2+
3+
all: $(call NATIVE_STATICLIB,define-foo)
4+
$(RUSTC) -ldefine-foo use-foo.rs
5+
$(call RUN,use-foo) || exit 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <stdint.h>
2+
3+
struct Foo {
4+
uint8_t x;
5+
};
6+
7+
struct Foo FOO = { 42 };
8+
9+
uint8_t bar(const struct Foo* foo) {
10+
return foo->x;
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![feature(extern_types)]
2+
3+
extern "C" {
4+
type Foo;
5+
static FOO: Foo;
6+
fn bar(foo: *const Foo) -> u8;
7+
}
8+
9+
fn main() {
10+
unsafe {
11+
let foo = &FOO;
12+
assert_eq!(bar(foo), 42);
13+
}
14+
}

0 commit comments

Comments
 (0)