Skip to content

Don't ICE on packed structs in a static. #9832

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 13, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/librustc/middle/trans/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,26 +505,27 @@ pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: Disr,
}
Univariant(ref st, _dro) => {
assert_eq!(discr, 0);
C_struct(build_const_struct(ccx, st, vals))
let contents = build_const_struct(ccx, st, vals);
C_struct(contents, st.packed)
}
General(ref cases) => {
let case = &cases[discr];
let max_sz = cases.iter().map(|x| x.size).max().unwrap();
let discr_ty = C_disr(ccx, discr);
let contents = build_const_struct(ccx, case,
~[discr_ty] + vals);
C_struct(contents + &[padding(max_sz - case.size)])
C_struct(contents + &[padding(max_sz - case.size)], false)
}
NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => {
if discr == nndiscr {
C_struct(build_const_struct(ccx, nonnull, vals))
C_struct(build_const_struct(ccx, nonnull, vals), false)
} else {
assert_eq!(vals.len(), 0);
let vals = do nonnull.fields.iter().enumerate().map |(i, &ty)| {
let llty = type_of::sizing_type_of(ccx, ty);
if i == ptrfield { C_null(llty) } else { C_undef(llty) }
}.collect::<~[ValueRef]>();
C_struct(build_const_struct(ccx, nonnull, vals))
C_struct(build_const_struct(ccx, nonnull, vals), false)
}
}
}
Expand Down Expand Up @@ -559,7 +560,7 @@ fn build_const_struct(ccx: &mut CrateContext, st: &Struct, vals: &[ValueRef])
offset = target_offset;
}
let val = if is_undef(vals[i]) {
let wrapped = C_struct([vals[i]]);
let wrapped = C_struct([vals[i]], false);
assert!(!is_undef(wrapped));
wrapped
} else {
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2936,7 +2936,7 @@ pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint, uint) {
let elt = C_struct([
C_estr_slice(ccx, *key),
v_ptr
]);
], false);
elts.push(elt);
}
unsafe {
Expand Down Expand Up @@ -3012,13 +3012,13 @@ pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) {
p2i(ccx, mod_map),
// byte size of the module map array, an entry consists of two integers
C_int(ccx, ((mod_count * mod_struct_size) as int))
]),
], false),
C_struct([
p2i(ccx, vec_elements),
// byte size of the subcrates array, an entry consists of an integer
C_int(ccx, (subcrates.len() * llsize_of_alloc(ccx, ccx.int_type)) as int)
])
]));
], false)
], false));
}
}

Expand Down Expand Up @@ -3052,7 +3052,7 @@ pub fn write_metadata(cx: &CrateContext, crate: &ast::Crate) {

let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
let llmeta = C_bytes(encoder::encode_metadata(encode_parms, crate));
let llconst = C_struct([llmeta]);
let llconst = C_struct([llmeta], false);
let mut llglobal = do "rust_metadata".with_c_str |buf| {
unsafe {
llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst).to_ref(), buf)
Expand Down
16 changes: 4 additions & 12 deletions src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ pub fn C_floating(s: &str, t: Type) -> ValueRef {
}

pub fn C_nil() -> ValueRef {
return C_struct([]);
C_struct([], false)
}

pub fn C_bool(val: bool) -> ValueRef {
Expand Down Expand Up @@ -913,7 +913,7 @@ pub fn C_estr_slice(cx: &mut CrateContext, s: @str) -> ValueRef {
unsafe {
let len = s.len();
let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), Type::i8p().to_ref());
C_struct([cs, C_uint(cx, len)])
C_struct([cs, C_uint(cx, len)], false)
}
}

Expand All @@ -927,18 +927,10 @@ pub fn C_zero_byte_arr(size: uint) -> ValueRef {
}
}

pub fn C_struct(elts: &[ValueRef]) -> ValueRef {
pub fn C_struct(elts: &[ValueRef], packed: bool) -> ValueRef {
unsafe {
do elts.as_imm_buf |ptr, len| {
llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, False)
}
}
}

pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef {
unsafe {
do elts.as_imm_buf |ptr, len| {
llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, True)
llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, packed as Bool)
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/middle/trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ pub fn const_vec(cx: @mut CrateContext, e: &ast::Expr, es: &[@ast::Expr])
let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e)));
// If the vector contains enums, an LLVM array won't work.
let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
C_struct(vs)
C_struct(vs, false)
} else {
C_array(llunitty, vs)
};
Expand Down Expand Up @@ -186,7 +186,7 @@ pub fn const_expr(cx: @mut CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
match adjustment {
None => { }
Some(@ty::AutoAddEnv(ty::re_static, ast::BorrowedSigil)) => {
llconst = C_struct([llconst, C_null(Type::opaque_box(cx).ptr_to())])
llconst = C_struct([llconst, C_null(Type::opaque_box(cx).ptr_to())], false)
}
Some(@ty::AutoAddEnv(ref r, ref s)) => {
cx.sess.span_bug(e.span, format!("unexpected static function: \
Expand Down Expand Up @@ -227,7 +227,7 @@ pub fn const_expr(cx: @mut CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
match ty::get(ty).sty {
ty::ty_evec(_, ty::vstore_fixed(*)) => {
let size = machine::llsize_of(cx, val_ty(llconst));
llconst = C_struct([llptr, size]);
llconst = C_struct([llptr, size], false);
}
_ => {}
}
Expand Down Expand Up @@ -559,7 +559,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext,
llvm::LLVMSetGlobalConstant(gv, True);
SetLinkage(gv, PrivateLinkage);
let p = const_ptrcast(cx, gv, llunitty);
(C_struct([p, sz]), false)
(C_struct([p, sz], false), false)
}
_ => cx.sess.span_bug(e.span, "bad const-slice expr")
}
Expand All @@ -575,7 +575,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext,
};
let vs = vec::from_elem(n, const_expr(cx, elem).first());
let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
C_struct(vs)
C_struct(vs, false)
} else {
C_array(llunitty, vs)
};
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ pub fn make_vtable(ccx: &mut CrateContext,
components.push(ptr)
}

let tbl = C_struct(components);
let tbl = C_struct(components, false);
let sym = token::gensym("vtable");
let vt_gvar = do format!("vtable{}", sym).with_c_str |buf| {
llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf)
Expand Down
5 changes: 5 additions & 0 deletions src/test/run-pass/packed-struct-size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ struct S7_Option {
d: Option<@mut f64>
}

// Placing packed structs in statics should work
static TEST_S4: S4 = S4 { a: 1, b: [2, 3, 4] };
static TEST_S5: S5 = S5 { a: 3, b: 67 };
static TEST_S3_Foo: S3_Foo = S3_Foo { a: 1, b: 2, c: Baz };


pub fn main() {
assert_eq!(sys::size_of::<S4>(), 4);
Expand Down