Skip to content

Commit 722733c

Browse files
authored
Merge pull request rust-lang#1247 from bjorn3/melt_some_ice
Melt some ICE
2 parents 5fcedf6 + fd2669d commit 722733c

11 files changed

+229
-109
lines changed

example/mini_core_hello_world.rs

+11
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,17 @@ fn main() {
330330
static REF1: &u8 = &42;
331331
static REF2: &u8 = REF1;
332332
assert_eq!(*REF1, *REF2);
333+
334+
extern "C" {
335+
type A;
336+
}
337+
338+
fn main() {
339+
let x: &A = unsafe { &*(1usize as *const A) };
340+
341+
assert_eq!(unsafe { intrinsics::size_of_val(x) }, 0);
342+
assert_eq!(unsafe { intrinsics::min_align_of_val(x) }, 1);
343+
}
333344
}
334345

335346
#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]

example/std_example.rs

+19
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,25 @@ fn main() {
128128
0 => loop {},
129129
v => panic(v),
130130
};
131+
132+
if black_box(false) {
133+
// Based on https://github.com/rust-lang/rust/blob/2f320a224e827b400be25966755a621779f797cc/src/test/ui/debuginfo/debuginfo_with_uninhabitable_field_and_unsized.rs
134+
let _ = Foo::<dyn Send>::new();
135+
136+
#[allow(dead_code)]
137+
struct Foo<T: ?Sized> {
138+
base: Never,
139+
value: T,
140+
}
141+
142+
impl<T: ?Sized> Foo<T> {
143+
pub fn new() -> Box<Foo<T>> {
144+
todo!()
145+
}
146+
}
147+
148+
enum Never {}
149+
}
131150
}
132151

133152
fn panic(_: u128) {

scripts/test_rustc_tests.sh

-3
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,6 @@ rm -r src/test/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
9999
# ============
100100
rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition
101101

102-
rm -r src/test/ui/polymorphization/ # polymorphization not yet supported
103-
rm src/test/codegen-units/polymorphization/unused_type_parameters.rs # same
104-
105102
rm src/test/incremental/spike-neg1.rs # errors out for some reason
106103
rm src/test/incremental/spike-neg2.rs # same
107104
rm src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs

src/abi/mod.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod comments;
44
mod pass_mode;
55
mod returning;
66

7+
use cranelift_module::ModuleError;
78
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
89
use rustc_middle::ty::layout::FnAbiOf;
910
use rustc_target::abi::call::{Conv, FnAbi};
@@ -69,7 +70,17 @@ pub(crate) fn import_function<'tcx>(
6970
) -> FuncId {
7071
let name = tcx.symbol_name(inst).name;
7172
let sig = get_function_sig(tcx, module.isa().triple(), inst);
72-
module.declare_function(name, Linkage::Import, &sig).unwrap()
73+
match module.declare_function(name, Linkage::Import, &sig) {
74+
Ok(func_id) => func_id,
75+
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
76+
"attempt to declare `{name}` as function, but it was already declared as static"
77+
)),
78+
Err(ModuleError::IncompatibleSignature(_, prev_sig, new_sig)) => tcx.sess.fatal(&format!(
79+
"attempt to declare `{name}` with signature {new_sig:?}, \
80+
but it was already declared with signature {prev_sig:?}"
81+
)),
82+
Err(err) => Err::<_, _>(err).unwrap(),
83+
}
7384
}
7485

7586
impl<'tcx> FunctionCx<'_, '_, 'tcx> {
@@ -182,6 +193,15 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
182193
}
183194

184195
let fn_abi = fx.fn_abi.take().unwrap();
196+
197+
// FIXME implement variadics in cranelift
198+
if fn_abi.c_variadic {
199+
fx.tcx.sess.span_fatal(
200+
fx.mir.span,
201+
"Defining variadic functions is not yet supported by Cranelift",
202+
);
203+
}
204+
185205
let mut arg_abis_iter = fn_abi.args.iter();
186206

187207
let func_params = fx

src/abi/pass_mode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
216216
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
217217
is_owned: bool,
218218
) -> SmallVec<[Value; 2]> {
219-
assert_assignable(fx, arg.layout().ty, arg_abi.layout.ty);
219+
assert_assignable(fx, arg.layout().ty, arg_abi.layout.ty, 16);
220220
match arg_abi.mode {
221221
PassMode::Ignore => smallvec![],
222222
PassMode::Direct(_) => smallvec![arg.load_scalar(fx)],

src/constant.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,18 @@ fn data_id_for_static(
316316

317317
let attrs = tcx.codegen_fn_attrs(def_id);
318318

319-
let data_id = module
320-
.declare_data(
321-
&*symbol_name,
322-
linkage,
323-
is_mutable,
324-
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
325-
)
326-
.unwrap();
319+
let data_id = match module.declare_data(
320+
&*symbol_name,
321+
linkage,
322+
is_mutable,
323+
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
324+
) {
325+
Ok(data_id) => data_id,
326+
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
327+
"attempt to declare `{symbol_name}` as static, but it was already declared as function"
328+
)),
329+
Err(err) => Err::<_, _>(err).unwrap(),
330+
};
327331

328332
if rlinkage.is_some() {
329333
// Comment copied from https://github.com/rust-lang/rust/blob/45060c2a66dfd667f88bd8b94261b28a58d85bd5/src/librustc_codegen_llvm/consts.rs#L141
@@ -428,7 +432,8 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
428432
let data_id = match reloc_target_alloc {
429433
GlobalAlloc::Function(instance) => {
430434
assert_eq!(addend, 0);
431-
let func_id = crate::abi::import_function(tcx, module, instance);
435+
let func_id =
436+
crate::abi::import_function(tcx, module, instance.polymorphize(tcx));
432437
let local_func_id = module.declare_func_in_data(func_id, &mut data_ctx);
433438
data_ctx.write_function_addr(offset.bytes() as u32, local_func_id);
434439
continue;

src/inline_asm.rs

+90-80
Original file line numberDiff line numberDiff line change
@@ -18,86 +18,96 @@ pub(crate) fn codegen_inline_asm<'tcx>(
1818
) {
1919
// FIXME add .eh_frame unwind info directives
2020

21-
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
22-
let true_ = fx.bcx.ins().iconst(types::I32, 1);
23-
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
24-
return;
25-
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
26-
&& matches!(
27-
template[1],
28-
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
29-
)
30-
&& template[2] == InlineAsmTemplatePiece::String("\n".to_string())
31-
&& template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
32-
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string())
33-
&& template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
34-
&& matches!(
35-
template[6],
36-
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
37-
)
38-
{
39-
assert_eq!(operands.len(), 4);
40-
let (leaf, eax_place) = match operands[1] {
41-
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
42-
assert_eq!(
43-
reg,
44-
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax))
45-
);
46-
(
47-
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
48-
crate::base::codegen_place(fx, out_place.unwrap()),
49-
)
50-
}
51-
_ => unreachable!(),
52-
};
53-
let ebx_place = match operands[0] {
54-
InlineAsmOperand::Out { reg, late: true, place } => {
55-
assert_eq!(
56-
reg,
57-
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
58-
X86InlineAsmRegClass::reg
59-
))
60-
);
61-
crate::base::codegen_place(fx, place.unwrap())
62-
}
63-
_ => unreachable!(),
64-
};
65-
let (sub_leaf, ecx_place) = match operands[2] {
66-
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
67-
assert_eq!(
68-
reg,
69-
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx))
70-
);
71-
(
72-
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
73-
crate::base::codegen_place(fx, out_place.unwrap()),
74-
)
75-
}
76-
_ => unreachable!(),
77-
};
78-
let edx_place = match operands[3] {
79-
InlineAsmOperand::Out { reg, late: true, place } => {
80-
assert_eq!(
81-
reg,
82-
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx))
83-
);
84-
crate::base::codegen_place(fx, place.unwrap())
85-
}
86-
_ => unreachable!(),
87-
};
88-
89-
let (eax, ebx, ecx, edx) = crate::intrinsics::codegen_cpuid_call(fx, leaf, sub_leaf);
90-
91-
eax_place.write_cvalue(fx, CValue::by_val(eax, fx.layout_of(fx.tcx.types.u32)));
92-
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
93-
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
94-
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
95-
return;
96-
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
97-
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
98-
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
99-
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
100-
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
21+
if !template.is_empty() {
22+
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
23+
let true_ = fx.bcx.ins().iconst(types::I32, 1);
24+
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
25+
return;
26+
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
27+
&& matches!(
28+
template[1],
29+
InlineAsmTemplatePiece::Placeholder {
30+
operand_idx: 0,
31+
modifier: Some('r'),
32+
span: _
33+
}
34+
)
35+
&& template[2] == InlineAsmTemplatePiece::String("\n".to_string())
36+
&& template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
37+
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string())
38+
&& template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
39+
&& matches!(
40+
template[6],
41+
InlineAsmTemplatePiece::Placeholder {
42+
operand_idx: 0,
43+
modifier: Some('r'),
44+
span: _
45+
}
46+
)
47+
{
48+
assert_eq!(operands.len(), 4);
49+
let (leaf, eax_place) = match operands[1] {
50+
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
51+
assert_eq!(
52+
reg,
53+
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax))
54+
);
55+
(
56+
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
57+
crate::base::codegen_place(fx, out_place.unwrap()),
58+
)
59+
}
60+
_ => unreachable!(),
61+
};
62+
let ebx_place = match operands[0] {
63+
InlineAsmOperand::Out { reg, late: true, place } => {
64+
assert_eq!(
65+
reg,
66+
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
67+
X86InlineAsmRegClass::reg
68+
))
69+
);
70+
crate::base::codegen_place(fx, place.unwrap())
71+
}
72+
_ => unreachable!(),
73+
};
74+
let (sub_leaf, ecx_place) = match operands[2] {
75+
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
76+
assert_eq!(
77+
reg,
78+
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx))
79+
);
80+
(
81+
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
82+
crate::base::codegen_place(fx, out_place.unwrap()),
83+
)
84+
}
85+
_ => unreachable!(),
86+
};
87+
let edx_place = match operands[3] {
88+
InlineAsmOperand::Out { reg, late: true, place } => {
89+
assert_eq!(
90+
reg,
91+
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx))
92+
);
93+
crate::base::codegen_place(fx, place.unwrap())
94+
}
95+
_ => unreachable!(),
96+
};
97+
98+
let (eax, ebx, ecx, edx) = crate::intrinsics::codegen_cpuid_call(fx, leaf, sub_leaf);
99+
100+
eax_place.write_cvalue(fx, CValue::by_val(eax, fx.layout_of(fx.tcx.types.u32)));
101+
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
102+
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
103+
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
104+
return;
105+
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
106+
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
107+
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
108+
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
109+
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
110+
}
101111
}
102112

103113
let mut inputs = Vec::new();

src/intrinsics/mod.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
404404
};
405405
size_of_val, (c ptr) {
406406
let layout = fx.layout_of(substs.type_at(0));
407-
let size = if layout.is_unsized() {
407+
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
408+
// branch
409+
let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
408410
let (_ptr, info) = ptr.load_scalar_pair(fx);
409411
let (size, _align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
410412
size
@@ -418,7 +420,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
418420
};
419421
min_align_of_val, (c ptr) {
420422
let layout = fx.layout_of(substs.type_at(0));
421-
let align = if layout.is_unsized() {
423+
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
424+
// branch
425+
let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
422426
let (_ptr, info) = ptr.load_scalar_pair(fx);
423427
let (_size, align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
424428
align
@@ -1135,6 +1139,20 @@ fn codegen_regular_intrinsic_call<'tcx>(
11351139
// FIXME implement black_box semantics
11361140
ret.write_cvalue(fx, a);
11371141
};
1142+
1143+
// FIXME implement variadics in cranelift
1144+
va_copy, (o _dest, o _src) {
1145+
fx.tcx.sess.span_fatal(
1146+
source_info.span,
1147+
"Defining variadic functions is not yet supported by Cranelift",
1148+
);
1149+
};
1150+
va_arg | va_end, (o _valist) {
1151+
fx.tcx.sess.span_fatal(
1152+
source_info.span,
1153+
"Defining variadic functions is not yet supported by Cranelift",
1154+
);
1155+
};
11381156
}
11391157

11401158
let ret_block = fx.get_block(destination.unwrap());

src/main_shim.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ pub(crate) fn maybe_create_entry_wrapper(
109109
tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()),
110110
)
111111
.unwrap()
112-
.unwrap();
112+
.unwrap()
113+
.polymorphize(tcx);
113114

114115
let report_name = tcx.symbol_name(report).name;
115116
let report_sig = get_function_sig(tcx, m.isa().triple(), report);

src/unsize.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
153153
layout: TyAndLayout<'tcx>,
154154
info: Value,
155155
) -> (Value, Value) {
156-
if !layout.is_unsized() {
157-
let size = fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64);
158-
let align = fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64);
159-
return (size, align);
160-
}
156+
assert!(layout.is_unsized() || layout.abi == Abi::Uninhabited);
161157
match layout.ty.kind() {
162158
ty::Dynamic(..) => {
163159
// load size/align from vtable

0 commit comments

Comments
 (0)