return;
}
+ if (intrinsic == Some("init") || intrinsic == Some("uninit")) &&
+ bx.cx.layout_of(sig.output()).abi.is_uninhabited()
+ {
+ let loc = bx.sess().codemap().lookup_char_pos(span.lo());
+ let filename = Symbol::intern(&loc.file.name.to_string()).as_str();
+ let filename = C_str_slice(bx.cx, filename);
+ let line = C_u32(bx.cx, loc.line as u32);
+ let col = C_u32(bx.cx, loc.col.to_usize() as u32 + 1);
+ let align = tcx.data_layout.aggregate_align
+ .max(tcx.data_layout.i32_align)
+ .max(tcx.data_layout.pointer_align);
+
+ let str = if intrinsic == Some("init") {
+ "Attempted to instantiate an uninhabited type (e.g. `!`) \
+ using mem::zeroed()"
+ } else {
+ "Attempted to instantiate an uninhabited type (e.g. `!`) \
+ using mem::uninitialized()"
+ };
+ let msg_str = Symbol::intern(str).as_str();
+ let msg_str = C_str_slice(bx.cx, msg_str);
+ let msg_file_line_col = C_struct(bx.cx,
+ &[msg_str, filename, line, col],
+ false);
+ let msg_file_line_col = consts::addr_of(bx.cx,
+ msg_file_line_col,
+ align,
+ Some("panic_loc"));
+
+ // Obtain the panic entry point.
+ let def_id =
+ common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem);
+ let instance = ty::Instance::mono(bx.tcx(), def_id);
+ let fn_ty = FnType::of_instance(bx.cx, &instance);
+ let llfn = callee::get_fn(bx.cx, instance);
+
+ // Codegen the actual panic invoke/call.
+ do_call(
+ self,
+ bx,
+ fn_ty,
+ llfn,
+ &[msg_file_line_col],
+ destination.as_ref().map(|(_, bb)| (ReturnDest::Nothing, *bb)),
+ cleanup,
+ );
+ return;
+ }
+
let extra_args = &args[sig.inputs().len()..];
let extra_args = extra_args.iter().map(|op_arg| {
let op_ty = op_arg.ty(self.mir, bx.tcx());
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results
+// in a runtime panic.
+
+#![feature(never_type)]
+
+use std::{mem, panic};
+
+struct Foo {
+ x: u8,
+ y: !,
+}
+
+fn main() {
+ unsafe {
+ panic::catch_unwind(|| mem::uninitialized::<!>()).is_err();
+ panic::catch_unwind(|| mem::zeroed::<!>()).is_err();
+
+ panic::catch_unwind(|| mem::uninitialized::<Foo>()).is_err();
+ panic::catch_unwind(|| mem::zeroed::<Foo>()).is_err();
+ }
+}