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

View file

@ -201,6 +201,10 @@ pub struct CrateContext {
// Cache of emitted const values
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>,
lltypes: @mut LinearMap<ty::t, TypeRef>,
llsizingtypes: @mut LinearMap<ty::t, TypeRef>,

View file

@ -124,6 +124,7 @@
use back::abi;
use lib;
use lib::llvm::{ValueRef, TypeRef, llvm, True};
use metadata::csearch;
use middle::borrowck::root_map_key;
use middle::trans::_match;
use middle::trans::adt;
@ -150,6 +151,7 @@
use util::common::indenter;
use util::ppaux::ty_to_str;
use core::cast::transmute;
use core::hashmap::linear::LinearMap;
use syntax::print::pprust::{expr_to_str};
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)
-> ValueRef {
if did.crate == ast::local_crate {
// The LLVM global has the type of its initializer,
// which may not be equal to the enum's type for
// non-C-like enums.
PointerCast(bcx, base::get_item_val(bcx.ccx(), did.node),
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);