Skip to content

Commit 40601f6

Browse files
committed
---
yaml --- r: 6492 b: refs/heads/master c: 152bb31 h: refs/heads/master v: v3
1 parent 0494594 commit 40601f6

File tree

5 files changed

+48
-8
lines changed

5 files changed

+48
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 8371beb5905158377689b9efb5cdb4a07ae17ada
2+
refs/heads/master: 152bb314f5665b66d1eb91b7ce90f14c01c1197d

trunk/src/comp/middle/shape.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import lib::llvm::llvm::{ModuleRef, TypeRef, ValueRef};
66
import driver::session;
77
import middle::{trans, trans_common};
88
import middle::trans_common::{crate_ctxt, val_ty, C_bytes,
9-
C_named_struct, C_struct};
9+
C_named_struct, C_struct, T_tag_variant};
1010
import middle::ty;
1111
import middle::ty::field;
1212
import syntax::ast;
@@ -213,7 +213,12 @@ fn compute_static_tag_size(ccx: @crate_ctxt, largest_variants: [uint],
213213
// Add space for the tag if applicable.
214214
// FIXME (issue #792): This is wrong. If the tag starts with an 8 byte
215215
// aligned quantity, we don't align it.
216-
if vec::len(variants) > 1u { max_size += 4u16; max_align = 4u8; }
216+
if vec::len(variants) > 1u {
217+
let variant_t = T_tag_variant(ccx);
218+
max_size += trans::llsize_of_real(ccx, variant_t) as u16;
219+
let align = trans::llalign_of_real(ccx, variant_t) as u8;
220+
if max_align < align { max_align = align; }
221+
}
217222

218223
ret {size: max_size, align: max_align};
219224
}

trunk/src/comp/middle/trans.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,11 @@ fn type_of_tag(cx: @crate_ctxt, sp: span, did: ast::def_id, t: ty::t)
220220
if check type_has_static_size(cx, t) {
221221
let size = static_size_of_tag(cx, sp, t);
222222
if !degen { T_tag(cx, size) }
223-
else if size == 0u { T_struct([cx.int_type]) }
223+
else if size == 0u { T_struct([T_tag_variant(cx)]) }
224224
else { T_array(T_i8(), size) }
225225
}
226226
else {
227-
if degen { T_struct([cx.int_type]) }
227+
if degen { T_struct([T_tag_variant(cx)]) }
228228
else { T_opaque_tag(cx) }
229229
}
230230
}

trunk/src/comp/middle/trans_common.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -676,21 +676,25 @@ fn T_opaque_closure_ptr(cx: @crate_ctxt) -> TypeRef {
676676
ret t;
677677
}
678678

679+
fn T_tag_variant(cx: @crate_ctxt) -> TypeRef {
680+
ret cx.int_type;
681+
}
682+
679683
fn T_tag(cx: @crate_ctxt, size: uint) -> TypeRef {
680684
let s = "tag_" + uint::to_str(size, 10u);
681685
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
682686
let t =
683687
if size == 0u {
684-
T_struct([cx.int_type])
685-
} else { T_struct([cx.int_type, T_array(T_i8(), size)]) };
688+
T_struct([T_tag_variant(cx)])
689+
} else { T_struct([T_tag_variant(cx), T_array(T_i8(), size)]) };
686690
cx.tn.associate(s, t);
687691
ret t;
688692
}
689693

690694
fn T_opaque_tag(cx: @crate_ctxt) -> TypeRef {
691695
let s = "opaque_tag";
692696
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
693-
let t = T_struct([cx.int_type, T_i8()]);
697+
let t = T_struct([T_tag_variant(cx), T_i8()]);
694698
cx.tn.associate(s, t);
695699
ret t;
696700
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Exercises a bug in the shape code that was exposed
2+
// on x86_64: when there is a tag embedded in an
3+
// interior record which is then itself interior to
4+
// something else, shape calculations were off.
5+
use std;
6+
import std::list;
7+
import std::list::list;
8+
import std::option;
9+
10+
tag opt_span {
11+
12+
//hack (as opposed to option::t), to make `span` compile
13+
os_none;
14+
os_some(@span);
15+
}
16+
type span = {lo: uint, hi: uint, expanded_from: opt_span};
17+
type spanned<T> = { data: T, span: span };
18+
type ty_ = uint;
19+
type path_ = { global: bool, idents: [str], types: [@ty] };
20+
type path = spanned<path_>;
21+
type ty = spanned<ty_>;
22+
23+
fn main() {
24+
let sp: span = {lo: 57451u, hi: 57542u, expanded_from: os_none};
25+
let t: @ty = @{ data: 3u, span: sp };
26+
let p_: path_ = { global: true, idents: ["hi"], types: [t] };
27+
let p: path = { data: p_, span: sp };
28+
let x = { sp: sp, path: p };
29+
log_err x.path;
30+
log_err x;
31+
}

0 commit comments

Comments
 (0)