diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index d21ee37f291..f7fb6646938 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -618,7 +618,7 @@ pub fn trans_case<'a>(bcx: &'a Block<'a>, r: &Repr, discr: Disr) RawNullablePointer { .. } | StructWrappedNullablePointer { .. } => { assert!(discr == 0 || discr == 1); - _match::single_result(Result::new(bcx, C_i1(bcx.ccx(), discr != 0))) + _match::single_result(Result::new(bcx, C_bool(bcx.ccx(), discr != 0))) } } } @@ -641,7 +641,7 @@ pub fn trans_start_init(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr) { } Univariant(ref st, true) => { assert_eq!(discr, 0); - Store(bcx, C_bool(bcx.ccx(), true), + Store(bcx, C_u8(bcx.ccx(), 1), GEPi(bcx, val, [0, st.fields.len() - 1])) } Univariant(..) => { diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 7e0fde80e7c..08cdde38c34 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -538,8 +538,8 @@ pub fn compare_scalar_values<'a>( // We don't need to do actual comparisons for nil. // () == () holds but () < () does not. match op { - ast::BiEq | ast::BiLe | ast::BiGe => return C_i1(cx.ccx(), true), - ast::BiNe | ast::BiLt | ast::BiGt => return C_i1(cx.ccx(), false), + ast::BiEq | ast::BiLe | ast::BiGe => return C_bool(cx.ccx(), true), + ast::BiNe | ast::BiLt | ast::BiGt => return C_bool(cx.ccx(), false), // refinements would be nice _ => die(cx) } @@ -958,10 +958,42 @@ pub fn need_invoke(bcx: &Block) -> bool { pub fn load_if_immediate(cx: &Block, v: ValueRef, t: ty::t) -> ValueRef { let _icx = push_ctxt("load_if_immediate"); - if type_is_immediate(cx.ccx(), t) { return Load(cx, v); } + if type_is_immediate(cx.ccx(), t) { return load_ty(cx, v, t); } return v; } +pub fn load_ty(cx: &Block, ptr: ValueRef, t: ty::t) -> ValueRef { + /*! + * Helper for loading values from memory. Does the necessary conversion if + * the in-memory type differs from the type used for SSA values. Also + * handles various special cases where the type gives us better information + * about what we are loading. + */ + if type_is_zero_size(cx.ccx(), t) { + C_undef(type_of::type_of(cx.ccx(), t)) + } else if ty::type_is_bool(t) { + Trunc(cx, LoadRangeAssert(cx, ptr, 0, 2, lib::llvm::False), Type::i1(cx.ccx())) + } else if ty::type_is_char(t) { + // a char is a unicode codepoint, and so takes values from 0 + // to 0x10FFFF inclusive only. + LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, lib::llvm::False) + } else { + Load(cx, ptr) + } +} + +pub fn store_ty(cx: &Block, v: ValueRef, dst: ValueRef, t: ty::t) { + /*! + * Helper for storing values in memory. Does the necessary conversion if + * the in-memory type differs from the type used for SSA values. + */ + if ty::type_is_bool(t) { + Store(cx, ZExt(cx, v, Type::i8(cx.ccx())), dst); + } else { + Store(cx, v, dst); + }; +} + pub fn ignore_lhs(_bcx: &Block, local: &ast::Local) -> bool { match local.pat.node { ast::PatWild => true, _ => false @@ -1013,7 +1045,7 @@ pub fn call_memcpy(cx: &Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, let dst_ptr = PointerCast(cx, dst, Type::i8p(ccx)); let size = IntCast(cx, n_bytes, ccx.int_type); let align = C_i32(ccx, align as i32); - let volatile = C_i1(ccx, false); + let volatile = C_bool(ccx, false); Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile], []); } @@ -1058,7 +1090,7 @@ fn memzero(b: &Builder, llptr: ValueRef, ty: Type) { let llzeroval = C_u8(ccx, 0); let size = machine::llsize_of(ccx, ty); let align = C_i32(ccx, llalign_of_min(ccx, ty) as i32); - let volatile = C_i1(ccx, false); + let volatile = C_bool(ccx, false); b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile], []); } @@ -1282,9 +1314,14 @@ fn copy_args_to_allocas<'a>(fcx: &FunctionContext<'a>, // Ties up the llstaticallocas -> llloadenv -> lltop edges, // and builds the return block. pub fn finish_fn<'a>(fcx: &'a FunctionContext<'a>, - last_bcx: &'a Block<'a>) { + last_bcx: &'a Block<'a>, + retty: ty::t) { let _icx = push_ctxt("finish_fn"); + // This shouldn't need to recompute the return type, + // as new_fn_ctxt did it already. + let substd_retty = retty.substp(fcx.ccx.tcx(), fcx.param_substs); + let ret_cx = match fcx.llreturn.get() { Some(llreturn) => { if !last_bcx.terminated.get() { @@ -1294,13 +1331,13 @@ pub fn finish_fn<'a>(fcx: &'a FunctionContext<'a>, } None => last_bcx }; - build_return_block(fcx, ret_cx); + build_return_block(fcx, ret_cx, substd_retty); debuginfo::clear_source_location(fcx); fcx.cleanup(); } // Builds the return block for a function. -pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) { +pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block, retty: ty::t) { // Return the value if this function immediate; otherwise, return void. if fcx.llretptr.get().is_none() || fcx.caller_expects_out_pointer { return RetVoid(ret_cx); @@ -1318,13 +1355,16 @@ pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) { retptr.erase_from_parent(); } - retval + if ty::type_is_bool(retty) { + Trunc(ret_cx, retval, Type::i1(fcx.ccx)) + } else { + retval + } } // Otherwise, load the return value from the ret slot - None => Load(ret_cx, fcx.llretptr.get().unwrap()) + None => load_ty(ret_cx, fcx.llretptr.get().unwrap(), retty) }; - Ret(ret_cx, retval); } @@ -1422,7 +1462,7 @@ pub fn trans_closure(ccx: &CrateContext, } // Insert the mandatory first few basic blocks before lltop. - finish_fn(&fcx, bcx); + finish_fn(&fcx, bcx, output_type); } // trans_fn: creates an LLVM function corresponding to a source language @@ -1512,7 +1552,7 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext, } } - finish_fn(&fcx, bcx); + finish_fn(&fcx, bcx, result_ty); } fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef, diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index 01bef64ebba..c44a4e02ad4 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -85,7 +85,7 @@ fn ty_size(ty: Type) -> uint { fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType { if is_reg_ty(ty) { - let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None }; + let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None }; return ArgType::direct(ty, None, None, attr); } let size = ty_size(ty); @@ -104,7 +104,7 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType { fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType { if is_reg_ty(ty) { - let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None }; + let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None }; return ArgType::direct(ty, None, None, attr); } let align = ty_align(ty); diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index 60db609e59e..9e5b38d2f7d 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -85,7 +85,7 @@ fn ty_size(ty: Type) -> uint { fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType { if is_reg_ty(ty) { - let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None }; + let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None }; ArgType::direct(ty, None, None, attr) } else { ArgType::indirect(ty, Some(StructRetAttribute)) @@ -102,7 +102,7 @@ fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut uint) -> ArgType { *offset += align_up_to(size, align * 8) / 8; if is_reg_ty(ty) { - let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None }; + let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None }; ArgType::direct(ty, None, None, attr) } else { ArgType::direct( diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs index 5fffdf08646..0d88c611cba 100644 --- a/src/librustc/middle/trans/cabi_x86.rs +++ b/src/librustc/middle/trans/cabi_x86.rs @@ -59,7 +59,7 @@ pub fn compute_abi_info(ccx: &CrateContext, } } } else { - let attr = if rty == Type::bool(ccx) { Some(ZExtAttribute) } else { None }; + let attr = if rty == Type::i1(ccx) { Some(ZExtAttribute) } else { None }; ret_ty = ArgType::direct(rty, None, None, attr); } @@ -74,7 +74,7 @@ pub fn compute_abi_info(ccx: &CrateContext, } } _ => { - let attr = if t == Type::bool(ccx) { Some(ZExtAttribute) } else { None }; + let attr = if t == Type::i1(ccx) { Some(ZExtAttribute) } else { None }; ArgType::direct(t, None, None, attr) } }; diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index b2cd9d256dd..5b8ddfe1be7 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -350,7 +350,7 @@ pub fn compute_abi_info(ccx: &CrateContext, None) } } else { - let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None }; + let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None }; ArgType::direct(ty, None, None, attr) } } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 2a1a6a379a7..c5361045549 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -345,7 +345,7 @@ pub fn trans_unboxing_shim(bcx: &Block, }).bcx; bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, arg_scope); - finish_fn(&fcx, bcx); + finish_fn(&fcx, bcx, return_type); llfn } @@ -757,7 +757,7 @@ pub fn trans_call_inner<'a>( if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) && !type_is_zero_size(bcx.ccx(), ret_ty) { - Store(bcx, llret, llretslot); + store_ty(bcx, llret, llretslot, ret_ty) } } None => {} diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 33e8d1736fb..de5de64e346 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -522,10 +522,6 @@ pub fn C_nil(ccx: &CrateContext) -> ValueRef { } pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef { - C_integral(Type::bool(ccx), val as u64, false) -} - -pub fn C_i1(ccx: &CrateContext, val: bool) -> ValueRef { C_integral(Type::i1(ccx), val as u64, false) } diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 440aa36b28c..b93469ad2fb 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -13,10 +13,8 @@ * Datums are and how they are intended to be used. */ -use lib; use lib::llvm::ValueRef; use middle::trans::base::*; -use middle::trans::build::*; use middle::trans::common::*; use middle::trans::cleanup; use middle::trans::cleanup::CleanupMethods; @@ -344,7 +342,7 @@ impl Datum { match self.kind.mode { ByValue => DatumBlock::new(bcx, self), ByRef => { - let llval = load(bcx, self.val, self.ty); + let llval = load_ty(bcx, self.val, self.ty); DatumBlock::new(bcx, Datum::new(llval, self.ty, Rvalue::new(ByValue))) } } @@ -471,7 +469,7 @@ impl Datum { DatumBlock::new(bcx, scratch) } ByValue => { - let v = load(bcx, l.val, l.ty); + let v = load_ty(bcx, l.val, l.ty); bcx = l.kind.post_store(bcx, l.val, l.ty); DatumBlock::new(bcx, Datum::new(v, l.ty, Rvalue::new(ByValue))) } @@ -516,24 +514,6 @@ impl Datum { } } -fn load<'a>(bcx: &'a Block<'a>, llptr: ValueRef, ty: ty::t) -> ValueRef { - /*! - * Private helper for loading from a by-ref datum. Handles various - * special cases where the type gives us better information about - * what we are loading. - */ - - if type_is_zero_size(bcx.ccx(), ty) { - C_undef(type_of::type_of(bcx.ccx(), ty)) - } else if ty::type_is_char(ty) { - // a char is a unicode codepoint, and so takes values from 0 - // to 0x10FFFF inclusive only. - LoadRangeAssert(bcx, llptr, 0, 0x10FFFF + 1, lib::llvm::False) - } else { - Load(bcx, llptr) - } -} - /** * Generic methods applicable to any sort of datum. */ @@ -591,7 +571,7 @@ impl Datum { if self.kind.is_by_ref() { memcpy_ty(bcx, dst, self.val, self.ty); } else { - Store(bcx, self.val, dst); + store_ty(bcx, self.val, dst, self.ty); } return bcx; @@ -642,7 +622,7 @@ impl Datum { assert!(!ty::type_needs_drop(bcx.tcx(), self.ty)); assert!(self.appropriate_rvalue_mode(bcx.ccx()) == ByValue); if self.kind.is_by_ref() { - load(bcx, self.val, self.ty) + load_ty(bcx, self.val, self.ty) } else { self.val } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index b10190b23c7..ac33f9bd1a8 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -505,7 +505,7 @@ fn trans_index<'a>(bcx: &'a Block<'a>, let bounds_check = ICmp(bcx, lib::llvm::IntUGE, ix_val, len); let expect = ccx.get_intrinsic(&("llvm.expect.i1")); - let expected = Call(bcx, expect, [bounds_check, C_i1(ccx, false)], []); + let expected = Call(bcx, expect, [bounds_check, C_bool(ccx, false)], []); let bcx = with_cond(bcx, expected, |bcx| { controlflow::trans_fail_bounds_check(bcx, index_expr.span, ix_val, len) }); @@ -1149,13 +1149,7 @@ fn trans_unary<'a>(bcx: &'a Block<'a>, match op { ast::UnNot => { let datum = unpack_datum!(bcx, trans(bcx, sub_expr)); - let llresult = if ty::type_is_bool(un_ty) { - let val = datum.to_llscalarish(bcx); - Xor(bcx, val, C_bool(ccx, true)) - } else { - // Note: `Not` is bitwise, not suitable for logical not. - Not(bcx, datum.to_llscalarish(bcx)) - }; + let llresult = Not(bcx, datum.to_llscalarish(bcx)); immediate_rvalue_bcx(bcx, llresult, un_ty).to_expr_datumblock() } ast::UnNeg => { @@ -1380,7 +1374,7 @@ fn trans_lazy_binop<'a>( } Br(past_rhs, join.llbb); - let phi = Phi(join, Type::bool(bcx.ccx()), [lhs, rhs], + let phi = Phi(join, Type::i1(bcx.ccx()), [lhs, rhs], [past_lhs.llbb, past_rhs.llbb]); return immediate_rvalue_bcx(join, phi, binop_ty).to_expr_datumblock(); @@ -1597,8 +1591,8 @@ fn trans_imm_cast<'a>(bcx: &'a Block<'a>, let k_in = cast_type_kind(t_in); let k_out = cast_type_kind(t_out); let s_in = k_in == cast_integral && ty::type_is_signed(t_in); - let ll_t_in = type_of::type_of(ccx, t_in); - let ll_t_out = type_of::type_of(ccx, t_out); + let ll_t_in = type_of::arg_type_of(ccx, t_in); + let ll_t_out = type_of::arg_type_of(ccx, t_out); // Convert the value to be cast into a ValueRef, either by-ref or // by-value as appropriate given its type: @@ -1689,7 +1683,7 @@ fn trans_assign_op<'a>( let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op")); assert!(!ty::type_needs_drop(bcx.tcx(), dst_datum.ty)); let dst_ty = dst_datum.ty; - let dst = Load(bcx, dst_datum.val); + let dst = load_ty(bcx, dst_datum.val, dst_datum.ty); // Evaluate RHS let rhs_datum = unpack_datum!(bcx, trans(bcx, &*src)); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index ff28f668c47..9d7261f8094 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -325,7 +325,7 @@ pub fn trans_native_call<'a>( base::alloca(bcx, type_of::type_of(ccx, *passed_arg_tys.get(i)), "__arg"); - Store(bcx, llarg_rust, scratch); + base::store_ty(bcx, llarg_rust, scratch, *passed_arg_tys.get(i)); llarg_rust = scratch; } @@ -346,7 +346,12 @@ pub fn trans_native_call<'a>( let llarg_foreign = if foreign_indirect { llarg_rust } else { - Load(bcx, llarg_rust) + if ty::type_is_bool(*passed_arg_tys.get(i)) { + let val = LoadRangeAssert(bcx, llarg_rust, 0, 2, lib::llvm::False); + Trunc(bcx, val, Type::i1(bcx.ccx())) + } else { + Load(bcx, llarg_rust) + } }; debug!("argument {}, llarg_foreign={}", @@ -431,7 +436,7 @@ pub fn trans_native_call<'a>( debug!("llforeign_ret_ty={}", ccx.tn.type_to_str(llforeign_ret_ty)); if llrust_ret_ty == llforeign_ret_ty { - Store(bcx, llforeign_retval, llretptr); + base::store_ty(bcx, llforeign_retval, llretptr, fn_sig.output) } else { // The actual return type is a struct, but the ABI // adaptation code has cast it into some scalar type. The @@ -715,9 +720,15 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext, // pointer). It makes adapting types easier, since we can // always just bitcast pointers. if !foreign_indirect { - let lltemp = builder.alloca(val_ty(llforeign_arg), ""); - builder.store(llforeign_arg, lltemp); - llforeign_arg = lltemp; + llforeign_arg = if ty::type_is_bool(rust_ty) { + let lltemp = builder.alloca(Type::bool(ccx), ""); + builder.store(builder.zext(llforeign_arg, Type::bool(ccx)), lltemp); + lltemp + } else { + let lltemp = builder.alloca(val_ty(llforeign_arg), ""); + builder.store(llforeign_arg, lltemp); + lltemp + } } // If the types in the ABI and the Rust types don't match, @@ -731,7 +742,12 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext, let llrust_arg = if rust_indirect { llforeign_arg } else { - builder.load(llforeign_arg) + if ty::type_is_bool(rust_ty) { + let tmp = builder.load_range_assert(llforeign_arg, 0, 2, lib::llvm::False); + builder.trunc(tmp, Type::i1(ccx)) + } else { + builder.load(llforeign_arg) + } }; debug!("llrust_arg {}{}: {}", "#", @@ -828,8 +844,8 @@ fn foreign_signature(ccx: &CrateContext, fn_sig: &ty::FnSig, arg_tys: &[ty::t]) * values by pointer like we do. */ - let llarg_tys = arg_tys.iter().map(|&arg| type_of(ccx, arg)).collect(); - let llret_ty = type_of::type_of(ccx, fn_sig.output); + let llarg_tys = arg_tys.iter().map(|&arg| arg_type_of(ccx, arg)).collect(); + let llret_ty = type_of::arg_type_of(ccx, fn_sig.output); LlvmSignature { llarg_tys: llarg_tys, llret_ty: llret_ty diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index a59bcda0c59..d046778485c 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -234,7 +234,7 @@ fn trans_struct_drop_flag<'a>(bcx: &'a Block<'a>, -> &'a Block<'a> { let repr = adt::represent_type(bcx.ccx(), t); let drop_flag = adt::trans_drop_flag_ptr(bcx, &*repr, v0); - with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag)), |cx| { + with_cond(bcx, load_ty(bcx, drop_flag, ty::mk_bool()), |cx| { trans_struct_drop(cx, t, v0, dtor_did, class_did, substs) }) } @@ -504,7 +504,7 @@ fn make_generic_glue(ccx: &CrateContext, let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, fcx.arg_pos(0) as c_uint) }; let bcx = helper(bcx, llrawptr0, t); - finish_fn(&fcx, bcx); + finish_fn(&fcx, bcx, ty::mk_nil()); llfn } diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index fbfd38d7be3..5022e0bf05b 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -96,13 +96,19 @@ pub fn trans_intrinsic(ccx: &CrateContext, let b = get_param(bcx.fcx.llfn, first_real_arg + 1); let llfn = bcx.ccx().get_intrinsic(&name); + // convert `i1` to a `bool`, and write to the out parameter let val = Call(bcx, llfn, [a, b], []); + let result = ExtractValue(bcx, val, 0); + let overflow = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool(bcx.ccx())); + let ret = C_undef(type_of::type_of(bcx.ccx(), t)); + let ret = InsertValue(bcx, ret, result, 0); + let ret = InsertValue(bcx, ret, overflow, 1); if type_is_immediate(bcx.ccx(), t) { - Ret(bcx, val); + Ret(bcx, ret); } else { let retptr = get_param(bcx.fcx.llfn, bcx.fcx.out_arg_pos()); - Store(bcx, val, retptr); + Store(bcx, ret, retptr); RetVoid(bcx); } } @@ -150,7 +156,8 @@ pub fn trans_intrinsic(ccx: &CrateContext, let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p(ccx)); let count = get_param(decl, first_real_arg + 2); let llfn = ccx.get_intrinsic(&name); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, C_i1(ccx, volatile)], []); + Call(bcx, llfn, + [dst_ptr, src_ptr, Mul(bcx, size, count), align, C_bool(ccx, volatile)], []); RetVoid(bcx); } @@ -171,13 +178,13 @@ pub fn trans_intrinsic(ccx: &CrateContext, let val = get_param(decl, first_real_arg + 1); let count = get_param(decl, first_real_arg + 2); let llfn = ccx.get_intrinsic(&name); - Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, C_i1(ccx, volatile)], []); + Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, C_bool(ccx, volatile)], []); RetVoid(bcx); } fn count_zeros_intrinsic(bcx: &Block, name: &'static str) { let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u)); - let y = C_i1(bcx.ccx(), false); + let y = C_bool(bcx.ccx(), false); let llfn = bcx.ccx().get_intrinsic(&name); let llcall = Call(bcx, llfn, [x, y], []); Ret(bcx, llcall); @@ -365,7 +372,7 @@ pub fn trans_intrinsic(ccx: &CrateContext, let retty = *substs.substs.types.get(FnSpace, 0); if type_is_immediate(ccx, retty) && !return_type_is_void(ccx, retty) { unsafe { - Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref())); + Ret(bcx, lib::llvm::llvm::LLVMGetUndef(arg_type_of(ccx, retty).to_ref())); } } else { RetVoid(bcx) diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 1d21180f5ab..ee581f75634 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -330,7 +330,7 @@ impl<'a, 'b> Reflector<'a, 'b> { Some(llreturn) => Br(bcx, llreturn), None => {} }; - finish_fn(&fcx, bcx); + finish_fn(&fcx, bcx, ty::mk_u64()); llfdecl }; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 1ec792182bd..b10f6eda880 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -89,7 +89,7 @@ impl Type { } pub fn bool(ccx: &CrateContext) -> Type { - Type::i1(ccx) + Type::i8(ccx) } pub fn char(ccx: &CrateContext) -> Type { diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index c26e11134b6..028722071a6 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -31,7 +31,7 @@ pub fn return_uses_outptr(ccx: &CrateContext, ty: ty::t) -> bool { } pub fn type_of_explicit_arg(ccx: &CrateContext, arg_ty: ty::t) -> Type { - let llty = type_of(ccx, arg_ty); + let llty = arg_type_of(ccx, arg_ty); if arg_is_indirect(ccx, arg_ty) { llty.ptr_to() } else { @@ -46,7 +46,7 @@ pub fn type_of_rust_fn(cx: &CrateContext, has_env: bool, // Arg 0: Output pointer. // (if the output type is non-immediate) let use_out_pointer = return_uses_outptr(cx, output); - let lloutputtype = type_of(cx, output); + let lloutputtype = arg_type_of(cx, output); if use_out_pointer { atys.push(lloutputtype.ptr_to()); } @@ -167,6 +167,14 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type { llsizingty } +pub fn arg_type_of(cx: &CrateContext, t: ty::t) -> Type { + if ty::type_is_bool(t) { + Type::i1(cx) + } else { + type_of(cx, t) + } +} + // NB: If you update this, be sure to update `sizing_type_of()` as well. pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { // Check the cache.