fix bug in shape concerning size of tag variant

This commit is contained in:
Niko Matsakis 2011-11-23 12:01:15 -08:00
parent 8371beb590
commit 152bb314f5
4 changed files with 47 additions and 7 deletions

View file

@ -6,7 +6,7 @@ import lib::llvm::llvm::{ModuleRef, TypeRef, ValueRef};
import driver::session;
import middle::{trans, trans_common};
import middle::trans_common::{crate_ctxt, val_ty, C_bytes,
C_named_struct, C_struct};
C_named_struct, C_struct, T_tag_variant};
import middle::ty;
import middle::ty::field;
import syntax::ast;
@ -213,7 +213,12 @@ fn compute_static_tag_size(ccx: @crate_ctxt, largest_variants: [uint],
// Add space for the tag if applicable.
// FIXME (issue #792): This is wrong. If the tag starts with an 8 byte
// aligned quantity, we don't align it.
if vec::len(variants) > 1u { max_size += 4u16; max_align = 4u8; }
if vec::len(variants) > 1u {
let variant_t = T_tag_variant(ccx);
max_size += trans::llsize_of_real(ccx, variant_t) as u16;
let align = trans::llalign_of_real(ccx, variant_t) as u8;
if max_align < align { max_align = align; }
}
ret {size: max_size, align: max_align};
}

View file

@ -220,11 +220,11 @@ fn type_of_tag(cx: @crate_ctxt, sp: span, did: ast::def_id, t: ty::t)
if check type_has_static_size(cx, t) {
let size = static_size_of_tag(cx, sp, t);
if !degen { T_tag(cx, size) }
else if size == 0u { T_struct([cx.int_type]) }
else if size == 0u { T_struct([T_tag_variant(cx)]) }
else { T_array(T_i8(), size) }
}
else {
if degen { T_struct([cx.int_type]) }
if degen { T_struct([T_tag_variant(cx)]) }
else { T_opaque_tag(cx) }
}
}

View file

@ -676,13 +676,17 @@ fn T_opaque_closure_ptr(cx: @crate_ctxt) -> TypeRef {
ret t;
}
fn T_tag_variant(cx: @crate_ctxt) -> TypeRef {
ret cx.int_type;
}
fn T_tag(cx: @crate_ctxt, size: uint) -> TypeRef {
let s = "tag_" + uint::to_str(size, 10u);
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
let t =
if size == 0u {
T_struct([cx.int_type])
} else { T_struct([cx.int_type, T_array(T_i8(), size)]) };
T_struct([T_tag_variant(cx)])
} else { T_struct([T_tag_variant(cx), T_array(T_i8(), size)]) };
cx.tn.associate(s, t);
ret t;
}
@ -690,7 +694,7 @@ fn T_tag(cx: @crate_ctxt, size: uint) -> TypeRef {
fn T_opaque_tag(cx: @crate_ctxt) -> TypeRef {
let s = "opaque_tag";
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
let t = T_struct([cx.int_type, T_i8()]);
let t = T_struct([T_tag_variant(cx), T_i8()]);
cx.tn.associate(s, t);
ret t;
}