|
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