librustc: Fix ICE with cross-crate extern statics. rs=bugfix

This commit is contained in:
Patrick Walton 2013-03-27 15:41:43 -07:00
parent 70b56fa5e9
commit 58338dd3d0
3 changed files with 39 additions and 7 deletions

View file

@ -2540,8 +2540,9 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::node_id) -> ValueRef {
} }
} }
_ => { ref variant => {
ccx.sess.bug(~"get_item_val(): unexpected variant") ccx.sess.bug(fmt!("get_item_val(): unexpected variant: %?",
variant))
} }
}; };
if !(exprt || ccx.reachable.contains(&id)) { if !(exprt || ccx.reachable.contains(&id)) {
@ -3085,6 +3086,7 @@ pub fn trans_crate(sess: session::Session,
const_cstr_cache: @mut LinearMap::new(), const_cstr_cache: @mut LinearMap::new(),
const_globals: @mut LinearMap::new(), const_globals: @mut LinearMap::new(),
const_values: @mut LinearMap::new(), const_values: @mut LinearMap::new(),
extern_const_values: @mut LinearMap::new(),
module_data: @mut LinearMap::new(), module_data: @mut LinearMap::new(),
lltypes: @mut LinearMap::new(), lltypes: @mut LinearMap::new(),
llsizingtypes: @mut LinearMap::new(), llsizingtypes: @mut LinearMap::new(),

View file

@ -201,6 +201,10 @@ pub struct CrateContext {
// Cache of emitted const values // Cache of emitted const values
const_values: @mut LinearMap<ast::node_id, ValueRef>, const_values: @mut LinearMap<ast::node_id, ValueRef>,
// Cache of external const values
extern_const_values: @mut LinearMap<ast::def_id, ValueRef>,
module_data: @mut LinearMap<~str, ValueRef>, module_data: @mut LinearMap<~str, ValueRef>,
lltypes: @mut LinearMap<ty::t, TypeRef>, lltypes: @mut LinearMap<ty::t, TypeRef>,
llsizingtypes: @mut LinearMap<ty::t, TypeRef>, llsizingtypes: @mut LinearMap<ty::t, TypeRef>,

View file

@ -124,6 +124,7 @@
use back::abi; use back::abi;
use lib; use lib;
use lib::llvm::{ValueRef, TypeRef, llvm, True}; use lib::llvm::{ValueRef, TypeRef, llvm, True};
use metadata::csearch;
use middle::borrowck::root_map_key; use middle::borrowck::root_map_key;
use middle::trans::_match; use middle::trans::_match;
use middle::trans::adt; use middle::trans::adt;
@ -150,6 +151,7 @@
use util::common::indenter; use util::common::indenter;
use util::ppaux::ty_to_str; use util::ppaux::ty_to_str;
use core::cast::transmute;
use core::hashmap::linear::LinearMap; use core::hashmap::linear::LinearMap;
use syntax::print::pprust::{expr_to_str}; use syntax::print::pprust::{expr_to_str};
use syntax::ast; use syntax::ast;
@ -1096,11 +1098,35 @@ fn get_did(ccx: @CrateContext, did: ast::def_id)
fn get_val(bcx: block, did: ast::def_id, const_ty: ty::t) fn get_val(bcx: block, did: ast::def_id, const_ty: ty::t)
-> ValueRef { -> ValueRef {
// The LLVM global has the type of its initializer, if did.crate == ast::local_crate {
// which may not be equal to the enum's type for // The LLVM global has the type of its initializer,
// non-C-like enums. // which may not be equal to the enum's type for
PointerCast(bcx, base::get_item_val(bcx.ccx(), did.node), // non-C-like enums.
T_ptr(type_of(bcx.ccx(), const_ty))) PointerCast(bcx,
base::get_item_val(bcx.ccx(), did.node),
T_ptr(type_of(bcx.ccx(), const_ty)))
} else {
// For external constants, we don't inline.
match bcx.ccx().extern_const_values.find(&did) {
None => {
unsafe {
let llty = type_of(bcx.ccx(), const_ty);
let symbol = csearch::get_symbol(
bcx.ccx().sess.cstore,
did);
let llval = llvm::LLVMAddGlobal(
bcx.ccx().llmod,
llty,
transmute::<&u8,*i8>(&symbol[0]));
bcx.ccx().extern_const_values.insert(
did,
llval);
llval
}
}
Some(llval) => *llval
}
}
} }
let did = get_did(ccx, did); let did = get_did(ccx, did);