Skip to content

Commit

Permalink
Do not ICE in codegen given a extern_type static
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dlrobertson committed Feb 5, 2019
1 parent b2c6b8c commit 80c052b
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
19 changes: 18 additions & 1 deletion src/librustc_codegen_ssa/mir/place.rs
Expand Up @@ -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>,
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions src/test/run-make-fulldeps/static-extern-type/Makefile
@@ -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 changes: 11 additions & 0 deletions src/test/run-make-fulldeps/static-extern-type/define-foo.c
@@ -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 changes: 14 additions & 0 deletions src/test/run-make-fulldeps/static-extern-type/use-foo.rs
@@ -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);
}
}

0 comments on commit 80c052b

Please sign in to comment.