mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-10 14:57:14 +00:00
Distinguish zero-size types from those that we return as void
This commit is contained in:
parent
76c90283ce
commit
5e7657fafb
@ -1320,7 +1320,7 @@ pub fn init_function<'a>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if !type_is_voidish(fcx.ccx, substd_output_type) {
|
if !return_type_is_void(fcx.ccx, substd_output_type) {
|
||||||
// If the function returns nil/bot, there is no real return
|
// If the function returns nil/bot, there is no real return
|
||||||
// value, so do not set `llretptr`.
|
// value, so do not set `llretptr`.
|
||||||
if !skip_retptr || fcx.caller_expects_out_pointer {
|
if !skip_retptr || fcx.caller_expects_out_pointer {
|
||||||
@ -1539,7 +1539,7 @@ pub fn trans_closure(ccx: @CrateContext,
|
|||||||
// translation calls that don't have a return value (trans_crate,
|
// translation calls that don't have a return value (trans_crate,
|
||||||
// trans_mod, trans_item, et cetera) and those that do
|
// trans_mod, trans_item, et cetera) and those that do
|
||||||
// (trans_block, trans_expr, et cetera).
|
// (trans_block, trans_expr, et cetera).
|
||||||
if body.expr.is_none() || type_is_voidish(bcx.ccx(), block_ty) {
|
if body.expr.is_none() || type_is_zero_size(bcx.ccx(), block_ty) {
|
||||||
bcx = controlflow::trans_block(bcx, body, expr::Ignore);
|
bcx = controlflow::trans_block(bcx, body, expr::Ignore);
|
||||||
} else {
|
} else {
|
||||||
let dest = expr::SaveIn(fcx.llretptr.get().unwrap());
|
let dest = expr::SaveIn(fcx.llretptr.get().unwrap());
|
||||||
@ -1679,7 +1679,7 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: @CrateContext,
|
|||||||
|
|
||||||
let bcx = fcx.entry_bcx.get().unwrap();
|
let bcx = fcx.entry_bcx.get().unwrap();
|
||||||
|
|
||||||
if !type_is_voidish(fcx.ccx, result_ty) {
|
if !type_is_zero_size(fcx.ccx, result_ty) {
|
||||||
let repr = adt::represent_type(ccx, result_ty);
|
let repr = adt::represent_type(ccx, result_ty);
|
||||||
adt::trans_start_init(bcx, repr, fcx.llretptr.get().unwrap(), disr);
|
adt::trans_start_init(bcx, repr, fcx.llretptr.get().unwrap(), disr);
|
||||||
for (i, arg_datum) in arg_datums.move_iter().enumerate() {
|
for (i, arg_datum) in arg_datums.move_iter().enumerate() {
|
||||||
|
@ -667,7 +667,7 @@ pub fn trans_call_inner<'a>(
|
|||||||
}
|
}
|
||||||
Some(expr::SaveIn(dst)) => Some(dst),
|
Some(expr::SaveIn(dst)) => Some(dst),
|
||||||
Some(expr::Ignore) => {
|
Some(expr::Ignore) => {
|
||||||
if !type_is_voidish(ccx, ret_ty) {
|
if !type_is_zero_size(ccx, ret_ty) {
|
||||||
Some(alloc_ty(bcx, ret_ty, "__llret"))
|
Some(alloc_ty(bcx, ret_ty, "__llret"))
|
||||||
} else {
|
} else {
|
||||||
let llty = type_of::type_of(ccx, ret_ty);
|
let llty = type_of::type_of(ccx, ret_ty);
|
||||||
@ -736,7 +736,7 @@ pub fn trans_call_inner<'a>(
|
|||||||
match opt_llretslot {
|
match opt_llretslot {
|
||||||
Some(llretslot) => {
|
Some(llretslot) => {
|
||||||
if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
|
if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
|
||||||
!type_is_voidish(bcx.ccx(), ret_ty)
|
!type_is_zero_size(bcx.ccx(), ret_ty)
|
||||||
{
|
{
|
||||||
Store(bcx, llret, llretslot);
|
Store(bcx, llret, llretslot);
|
||||||
}
|
}
|
||||||
|
@ -75,19 +75,33 @@ pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
|
|||||||
let llty = sizing_type_of(ccx, ty);
|
let llty = sizing_type_of(ccx, ty);
|
||||||
llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type)
|
llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type)
|
||||||
}
|
}
|
||||||
_ => type_is_voidish(ccx, ty)
|
_ => type_is_zero_size(ccx, ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_is_voidish(ccx: &CrateContext, ty: ty::t) -> bool {
|
pub fn type_is_zero_size(ccx: &CrateContext, ty: ty::t) -> bool {
|
||||||
//! Identify types like `()`, bottom, or empty structs, which
|
/*!
|
||||||
//! contain no information at all.
|
* Identify types which have size zero at runtime.
|
||||||
|
*/
|
||||||
|
|
||||||
use middle::trans::machine::llsize_of_alloc;
|
use middle::trans::machine::llsize_of_alloc;
|
||||||
use middle::trans::type_of::sizing_type_of;
|
use middle::trans::type_of::sizing_type_of;
|
||||||
let llty = sizing_type_of(ccx, ty);
|
let llty = sizing_type_of(ccx, ty);
|
||||||
llsize_of_alloc(ccx, llty) == 0
|
llsize_of_alloc(ccx, llty) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool {
|
||||||
|
/*!
|
||||||
|
* Identifies types which we declare to be equivalent to `void`
|
||||||
|
* in C for the purpose of function return types. These are
|
||||||
|
* `()`, bot, and uninhabited enums. Note that all such types
|
||||||
|
* are also zero-size, but not all zero-size types use a `void`
|
||||||
|
* return type (in order to aid with C ABI compatibility).
|
||||||
|
*/
|
||||||
|
|
||||||
|
ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx, ty)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn gensym_name(name: &str) -> (Ident, PathElem) {
|
pub fn gensym_name(name: &str) -> (Ident, PathElem) {
|
||||||
let name = token::gensym(name);
|
let name = token::gensym(name);
|
||||||
let ident = Ident::new(name);
|
let ident = Ident::new(name);
|
||||||
|
@ -171,7 +171,7 @@ pub fn appropriate_rvalue_mode(ccx: &CrateContext, ty: ty::t) -> RvalueMode {
|
|||||||
* on whether type is immediate or not.
|
* on whether type is immediate or not.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if type_is_voidish(ccx, ty) {
|
if type_is_zero_size(ccx, ty) {
|
||||||
ByValue
|
ByValue
|
||||||
} else if type_is_immediate(ccx, ty) {
|
} else if type_is_immediate(ccx, ty) {
|
||||||
ByValue
|
ByValue
|
||||||
@ -583,7 +583,7 @@ fn load<'a>(bcx: &'a Block<'a>, llptr: ValueRef, ty: ty::t) -> ValueRef {
|
|||||||
* what we are loading.
|
* what we are loading.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if type_is_voidish(bcx.ccx(), ty) {
|
if type_is_zero_size(bcx.ccx(), ty) {
|
||||||
C_undef(type_of::type_of(bcx.ccx(), ty))
|
C_undef(type_of::type_of(bcx.ccx(), ty))
|
||||||
} else if ty::type_is_bool(ty) {
|
} else if ty::type_is_bool(ty) {
|
||||||
LoadRangeAssert(bcx, llptr, 0, 2, lib::llvm::True)
|
LoadRangeAssert(bcx, llptr, 0, 2, lib::llvm::True)
|
||||||
@ -638,7 +638,7 @@ impl<K:KindOps> Datum<K> {
|
|||||||
|
|
||||||
let _icx = push_ctxt("copy_to_no_check");
|
let _icx = push_ctxt("copy_to_no_check");
|
||||||
|
|
||||||
if type_is_voidish(bcx.ccx(), self.ty) {
|
if type_is_zero_size(bcx.ccx(), self.ty) {
|
||||||
return bcx;
|
return bcx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +474,7 @@ fn trans_unadjusted<'a>(bcx: &'a Block<'a>,
|
|||||||
|
|
||||||
ty::RvalueDpsExpr => {
|
ty::RvalueDpsExpr => {
|
||||||
let ty = expr_ty(bcx, expr);
|
let ty = expr_ty(bcx, expr);
|
||||||
if type_is_voidish(bcx.ccx(), ty) {
|
if type_is_zero_size(bcx.ccx(), ty) {
|
||||||
bcx = trans_rvalue_dps_unadjusted(bcx, expr, Ignore);
|
bcx = trans_rvalue_dps_unadjusted(bcx, expr, Ignore);
|
||||||
nil(bcx, ty)
|
nil(bcx, ty)
|
||||||
} else {
|
} else {
|
||||||
|
@ -198,7 +198,7 @@ pub fn trans_native_call<'a>(
|
|||||||
_ => ccx.sess.bug("trans_native_call called on non-function type")
|
_ => ccx.sess.bug("trans_native_call called on non-function type")
|
||||||
};
|
};
|
||||||
let llsig = foreign_signature(ccx, &fn_sig, passed_arg_tys);
|
let llsig = foreign_signature(ccx, &fn_sig, passed_arg_tys);
|
||||||
let ret_def = !type_is_voidish(bcx.ccx(), fn_sig.output);
|
let ret_def = !return_type_is_void(bcx.ccx(), fn_sig.output);
|
||||||
let fn_type = cabi::compute_abi_info(ccx,
|
let fn_type = cabi::compute_abi_info(ccx,
|
||||||
llsig.llarg_tys,
|
llsig.llarg_tys,
|
||||||
llsig.llret_ty,
|
llsig.llret_ty,
|
||||||
@ -778,7 +778,7 @@ fn foreign_types_for_fn_ty(ccx: &CrateContext,
|
|||||||
_ => ccx.sess.bug("foreign_types_for_fn_ty called on non-function type")
|
_ => ccx.sess.bug("foreign_types_for_fn_ty called on non-function type")
|
||||||
};
|
};
|
||||||
let llsig = foreign_signature(ccx, &fn_sig, fn_sig.inputs);
|
let llsig = foreign_signature(ccx, &fn_sig, fn_sig.inputs);
|
||||||
let ret_def = !type_is_voidish(ccx, fn_sig.output);
|
let ret_def = !return_type_is_void(ccx, fn_sig.output);
|
||||||
let fn_ty = cabi::compute_abi_info(ccx,
|
let fn_ty = cabi::compute_abi_info(ccx,
|
||||||
llsig.llarg_tys,
|
llsig.llarg_tys,
|
||||||
llsig.llret_ty,
|
llsig.llret_ty,
|
||||||
|
@ -317,7 +317,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
|
|||||||
"uninit" => {
|
"uninit" => {
|
||||||
// Do nothing, this is effectively a no-op
|
// Do nothing, this is effectively a no-op
|
||||||
let retty = substs.tys[0];
|
let retty = substs.tys[0];
|
||||||
if type_is_immediate(ccx, retty) && !type_is_voidish(ccx, retty) {
|
if type_is_immediate(ccx, retty) && !return_type_is_void(ccx, retty) {
|
||||||
unsafe {
|
unsafe {
|
||||||
Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref()));
|
Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref()));
|
||||||
}
|
}
|
||||||
@ -356,7 +356,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
|
|||||||
pluralize(out_type_size)));
|
pluralize(out_type_size)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !type_is_voidish(ccx, out_type) {
|
if !return_type_is_void(ccx, out_type) {
|
||||||
let llsrcval = get_param(decl, first_real_arg);
|
let llsrcval = get_param(decl, first_real_arg);
|
||||||
if type_is_immediate(ccx, in_type) {
|
if type_is_immediate(ccx, in_type) {
|
||||||
match fcx.llretptr.get() {
|
match fcx.llretptr.get() {
|
||||||
|
@ -68,10 +68,10 @@ pub fn type_of_rust_fn(cx: &CrateContext,
|
|||||||
atys.push_all(type_of_explicit_args(cx, inputs));
|
atys.push_all(type_of_explicit_args(cx, inputs));
|
||||||
|
|
||||||
// Use the output as the actual return value if it's immediate.
|
// Use the output as the actual return value if it's immediate.
|
||||||
if !use_out_pointer && !type_is_voidish(cx, output) {
|
if use_out_pointer || return_type_is_void(cx, output) {
|
||||||
Type::func(atys, &lloutputtype)
|
|
||||||
} else {
|
|
||||||
Type::func(atys, &Type::void())
|
Type::func(atys, &Type::void())
|
||||||
|
} else {
|
||||||
|
Type::func(atys, &lloutputtype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user