Skip to content

Commit 97bf80f

Browse files
committed
Fix handling of C arguments
Fixes #33868
1 parent da66f2f commit 97bf80f

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

src/librustc_trans/base.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,21 +1663,30 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
16631663
arg_ty,
16641664
datum::Lvalue::new("FunctionContext::bind_args"))
16651665
} else {
1666-
unpack_datum!(bcx, datum::lvalue_scratch_datum(bcx, arg_ty, "",
1667-
uninit_reason,
1668-
arg_scope_id, |bcx, dst| {
1669-
debug!("FunctionContext::bind_args: {:?}: {:?}", hir_arg, arg_ty);
1666+
let lltmp = if common::type_is_fat_ptr(bcx.tcx(), arg_ty) {
1667+
let lltemp = alloc_ty(bcx, arg_ty, "");
16701668
let b = &bcx.build();
1671-
if common::type_is_fat_ptr(bcx.tcx(), arg_ty) {
1672-
let meta = &self.fn_ty.args[idx];
1673-
idx += 1;
1674-
arg.store_fn_arg(b, &mut llarg_idx, expr::get_dataptr(bcx, dst));
1675-
meta.store_fn_arg(b, &mut llarg_idx, expr::get_meta(bcx, dst));
1676-
} else {
1677-
arg.store_fn_arg(b, &mut llarg_idx, dst);
1678-
}
1679-
bcx
1680-
}))
1669+
// we pass fat pointers as two words, but we want to
1670+
// represent them internally as a pointer to two words,
1671+
// so make an alloca to store them in.
1672+
let meta = &self.fn_ty.args[idx];
1673+
idx += 1;
1674+
arg.store_fn_arg(b, &mut llarg_idx, expr::get_dataptr(bcx, lltemp));
1675+
meta.store_fn_arg(b, &mut llarg_idx, expr::get_meta(bcx, lltemp));
1676+
lltemp
1677+
} else {
1678+
// otherwise, arg is passed by value, so store it into a temporary.
1679+
let llarg_ty = arg.cast.unwrap_or(arg.memory_ty(bcx.ccx()));
1680+
let lltemp = alloca(bcx, llarg_ty, "");
1681+
let b = &bcx.build();
1682+
arg.store_fn_arg(b, &mut llarg_idx, lltemp);
1683+
// And coerce the temporary into the type we expect.
1684+
b.pointercast(lltemp, arg.memory_ty(bcx.ccx()).ptr_to())
1685+
};
1686+
1687+
// FIXME: hacky lol?
1688+
datum::Datum::new(lltmp, arg_ty,
1689+
datum::Lvalue::new("datum::lvalue_scratch_datum"))
16811690
}
16821691
} else {
16831692
// FIXME(pcwalton): Reduce the amount of code bloat this is responsible for.

src/librustc_trans/mir/mod.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -327,23 +327,28 @@ fn arg_value_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
327327
llarg_idx += 1;
328328
llarg
329329
} else {
330-
let lltemp = bcx.with_block(|bcx| {
331-
base::alloc_ty(bcx, arg_ty, &format!("arg{}", arg_index))
332-
});
333330
if common::type_is_fat_ptr(tcx, arg_ty) {
331+
let lltemp = bcx.with_block(|bcx| {
332+
base::alloc_ty(bcx, arg_ty, &format!("arg{}", arg_index))
333+
});
334334
// we pass fat pointers as two words, but we want to
335335
// represent them internally as a pointer to two words,
336336
// so make an alloca to store them in.
337337
let meta = &fcx.fn_ty.args[idx];
338338
idx += 1;
339339
arg.store_fn_arg(bcx, &mut llarg_idx, get_dataptr(bcx, lltemp));
340340
meta.store_fn_arg(bcx, &mut llarg_idx, get_meta(bcx, lltemp));
341+
lltemp
341342
} else {
342-
// otherwise, arg is passed by value, so make a
343-
// temporary and store it there
343+
// otherwise, arg is passed by value, so store it into a temporary.
344+
let llarg_ty = arg.cast.unwrap_or(arg.memory_ty(bcx.ccx()));
345+
let lltemp = bcx.with_block(|bcx| {
346+
base::alloca(bcx, llarg_ty, &format!("arg{}", arg_index))
347+
});
344348
arg.store_fn_arg(bcx, &mut llarg_idx, lltemp);
349+
// And coerce the temporary into the type we expect.
350+
bcx.pointercast(lltemp, arg.memory_ty(bcx.ccx()).ptr_to())
345351
}
346-
lltemp
347352
};
348353
bcx.with_block(|bcx| arg_scope.map(|scope| {
349354
// Is this a regular argument?

0 commit comments

Comments
 (0)