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:
kennytm 2019-02-07 13:57:44 +08:00 committed by GitHub
commit 7168eadafe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 1 deletions

View File

@ -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,

View 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

View 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;
}

View 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);
}
}