make C-like enums immediate

This fixes two existing bugs along the way:

* The `transmute` intrinsic did not correctly handle casts of immediate
  aggregates like newtype structs and tuples.
* The code for calling foreign functions used the wrong type to create
  an `alloca` temporary

    enum Foo { A, B }
    fn foo() -> Foo { A }

Before:

    ; Function Attrs: nounwind uwtable
    define void @_ZN3foo18hbedc642d5d9cf5aag4v0.0E(%enum.Foo* noalias nocapture sret, { i64, %tydesc*, i8*, i8*, i8 }* nocapture readnone) #0 {
    "function top level":
      %2 = getelementptr inbounds %enum.Foo* %0, i64 0, i32 0
      store i64 0, i64* %2, align 8
      ret void
    }

After:

    ; Function Attrs: nounwind readnone uwtable
    define %enum.Foo @_ZN3foo18hbedc642d5d9cf5aag4v0.0E({ i64, %tydesc*, i8*, i8*, i8 }* nocapture readnone) #0 {
    "function top level":
      ret %enum.Foo zeroinitializer
    }
This commit is contained in:
Daniel Micay 2013-10-03 06:19:02 -04:00
parent 249b356fb3
commit f504461a40
4 changed files with 11 additions and 9 deletions

View file

@ -69,10 +69,6 @@ pub fn type_is_immediate(ccx: &mut CrateContext, ty: ty::t) -> bool {
if simple {
return true;
}
// FIXME: #9651: C-like enums should also be immediate
if ty::type_is_c_like_enum(ccx.tcx, ty) {
return false;
}
match ty::get(ty).sty {
// FIXME: #9651: small `ty_struct` should also be immediate
ty::ty_struct(def_id, ref substs) => {

View file

@ -1727,7 +1727,9 @@ fn trans_imm_cast(bcx: @mut Block, expr: &ast::Expr,
(cast_enum, cast_float) => {
let bcx = bcx;
let repr = adt::represent_type(ccx, t_in);
let lldiscrim_a = adt::trans_get_discr(bcx, repr, llexpr);
let slot = Alloca(bcx, ll_t_in, "");
Store(bcx, llexpr, slot);
let lldiscrim_a = adt::trans_get_discr(bcx, repr, slot);
match k_out {
cast_integral => int_cast(bcx, ll_t_out,
val_ty(lldiscrim_a),

View file

@ -222,7 +222,7 @@ pub fn trans_native_call(bcx: @mut Block,
// Ensure that we always have the Rust value indirectly,
// because it makes bitcasting easier.
if !rust_indirect {
let scratch = base::alloca(bcx, arg_tys[i].ty, "__arg");
let scratch = base::alloca(bcx, type_of::type_of(ccx, fn_sig.inputs[i]), "__arg");
Store(bcx, llarg_rust, scratch);
llarg_rust = scratch;
}

View file

@ -12,7 +12,7 @@
use back::{abi};
use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg};
use lib::llvm::{ValueRef, Pointer};
use lib::llvm::{ValueRef, Pointer, Array, Struct};
use lib;
use middle::trans::base::*;
use middle::trans::build::*;
@ -333,8 +333,12 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
(Pointer, other) | (other, Pointer) if other != Pointer => {
let tmp = Alloca(bcx, llouttype, "");
Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
let ll_load = Load(bcx, tmp);
Ret(bcx, ll_load);
Ret(bcx, Load(bcx, tmp));
}
(Array, _) | (_, Array) | (Struct, _) | (_, Struct) => {
let tmp = Alloca(bcx, llouttype, "");
Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
Ret(bcx, Load(bcx, tmp));
}
_ => {
let llbitcast = BitCast(bcx, llsrcval, llouttype);