|
1 | 1 | use super::operand::OperandRef;
|
2 |
| -use super::operand::OperandValue::{Immediate, Pair, Ref}; |
| 2 | +use super::operand::OperandValue::{Immediate, Pair, Ref, ZeroSized}; |
3 | 3 | use super::place::PlaceRef;
|
4 | 4 | use super::{CachedLlbb, FunctionCx, LocalRef};
|
5 | 5 |
|
@@ -427,6 +427,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
427 | 427 | assert_eq!(align, op.layout.align.abi, "return place is unaligned!");
|
428 | 428 | llval
|
429 | 429 | }
|
| 430 | + ZeroSized => bug!("ZST return value shouldn't be in PassMode::Cast"), |
430 | 431 | };
|
431 | 432 | let ty = bx.cast_backend_type(cast_ty);
|
432 | 433 | let addr = bx.pointercast(llslot, bx.type_ptr_to(ty));
|
@@ -1386,6 +1387,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
1386 | 1387 | (llval, align, true)
|
1387 | 1388 | }
|
1388 | 1389 | }
|
| 1390 | + ZeroSized => match arg.mode { |
| 1391 | + PassMode::Indirect { .. } => { |
| 1392 | + // Though `extern "Rust"` doesn't pass ZSTs, some ABIs pass |
| 1393 | + // a pointer for `repr(C)` structs even when empty, so get |
| 1394 | + // one from an `alloca` (which can be left uninitialized). |
| 1395 | + let scratch = PlaceRef::alloca(bx, arg.layout); |
| 1396 | + (scratch.llval, scratch.align, true) |
| 1397 | + } |
| 1398 | + _ => bug!("ZST {op:?} wasn't ignored, but was passed with abi {arg:?}"), |
| 1399 | + }, |
1389 | 1400 | };
|
1390 | 1401 |
|
1391 | 1402 | if by_ref && !arg.is_indirect() {
|
|
0 commit comments