Skip to content

Commit e6aa92c

Browse files
trans: Make names of internal symbols independent of CGU translation order.
Every codegen unit gets its own local counter for generating new symbol names. This makes bitcode and object files reproducible at the binary level even when incremental compilation is used.
1 parent da5b646 commit e6aa92c

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

src/librustc_trans/common.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -799,9 +799,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
799799
s.as_ptr() as *const c_char,
800800
s.len() as c_uint,
801801
!null_terminated as Bool);
802-
803-
let gsym = token::gensym("str");
804-
let sym = format!("str{}", gsym.0);
802+
let sym = cx.generate_local_symbol_name("str");
805803
let g = declare::define_global(cx, &sym[..], val_ty(sc)).unwrap_or_else(||{
806804
bug!("symbol `{}` is already defined", sym);
807805
});

src/librustc_trans/consts.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use rustc::hir;
3030
use std::ffi::{CStr, CString};
3131
use syntax::ast;
3232
use syntax::attr;
33-
use syntax::parse::token;
3433

3534
pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
3635
unsafe {
@@ -44,10 +43,7 @@ pub fn addr_of_mut(ccx: &CrateContext,
4443
kind: &str)
4544
-> ValueRef {
4645
unsafe {
47-
// FIXME: this totally needs a better name generation scheme, perhaps a simple global
48-
// counter? Also most other uses of gensym in trans.
49-
let gsym = token::gensym("_");
50-
let name = format!("{}{}", kind, gsym.0);
46+
let name = ccx.generate_local_symbol_name(kind);
5147
let gv = declare::define_global(ccx, &name[..], val_ty(cv)).unwrap_or_else(||{
5248
bug!("symbol `{}` is already defined", name);
5349
});

src/librustc_trans/context.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ pub struct LocalCrateContext<'tcx> {
166166
type_of_depth: Cell<usize>,
167167

168168
symbol_map: Rc<SymbolMap<'tcx>>,
169+
170+
/// A counter that is used for generating local symbol names
171+
local_gen_sym_counter: Cell<usize>,
169172
}
170173

171174
// Implement DepTrackingMapConfig for `trait_cache`
@@ -688,6 +691,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
688691
n_llvm_insns: Cell::new(0),
689692
type_of_depth: Cell::new(0),
690693
symbol_map: symbol_map,
694+
local_gen_sym_counter: Cell::new(0),
691695
};
692696

693697
let (int_type, opaque_vec_type, str_slice_ty, mut local_ccx) = {
@@ -1021,6 +1025,16 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
10211025
pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
10221026
self.shared().empty_substs_for_def_id(item_def_id)
10231027
}
1028+
1029+
/// Generate a new symbol name with the given prefix. This symbol name must
1030+
/// only be used for definitions with `internal` or `private` linkage.
1031+
pub fn generate_local_symbol_name(&self, prefix: &str) -> String {
1032+
let idx = self.local().local_gen_sym_counter.get();
1033+
self.local().local_gen_sym_counter.set(idx + 1);
1034+
// Include a '.' character, so there can be no accidental conflicts with
1035+
// user defined names
1036+
format!("{}.{}", prefix, idx)
1037+
}
10241038
}
10251039

10261040
pub struct TypeOfDepthLock<'a, 'tcx: 'a>(&'a LocalCrateContext<'tcx>);

0 commit comments

Comments
 (0)