]> git.lizzy.rs Git - rust.git/commitdiff
trans: Make names of internal symbols independent of CGU translation order.
authorMichael Woerister <michaelwoerister@posteo.net>
Fri, 21 Oct 2016 16:41:20 +0000 (12:41 -0400)
committerMichael Woerister <michaelwoerister@posteo.net>
Fri, 21 Oct 2016 18:58:53 +0000 (14:58 -0400)
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.

src/librustc_trans/common.rs
src/librustc_trans/consts.rs
src/librustc_trans/context.rs

index 6ae5fc1657aa728359f7b8f27df4743b537ec15a..76b778fb61f258b9154eac81cc2f70dddc5d31aa 100644 (file)
@@ -799,9 +799,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
                                                 s.as_ptr() as *const c_char,
                                                 s.len() as c_uint,
                                                 !null_terminated as Bool);
-
-        let gsym = token::gensym("str");
-        let sym = format!("str{}", gsym.0);
+        let sym = cx.generate_local_symbol_name("str");
         let g = declare::define_global(cx, &sym[..], val_ty(sc)).unwrap_or_else(||{
             bug!("symbol `{}` is already defined", sym);
         });
index 15f7132e52d2f66b8e8dd18f39268dcfca58152d..0dc10aa7759ea8bee754ed1f9f792ec61735ee60 100644 (file)
@@ -30,7 +30,6 @@
 use std::ffi::{CStr, CString};
 use syntax::ast;
 use syntax::attr;
-use syntax::parse::token;
 
 pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
     unsafe {
@@ -44,10 +43,7 @@ pub fn addr_of_mut(ccx: &CrateContext,
                    kind: &str)
                     -> ValueRef {
     unsafe {
-        // FIXME: this totally needs a better name generation scheme, perhaps a simple global
-        // counter? Also most other uses of gensym in trans.
-        let gsym = token::gensym("_");
-        let name = format!("{}{}", kind, gsym.0);
+        let name = ccx.generate_local_symbol_name(kind);
         let gv = declare::define_global(ccx, &name[..], val_ty(cv)).unwrap_or_else(||{
             bug!("symbol `{}` is already defined", name);
         });
index 1b67516a9e6d0f025b254f91ee7a0558624c1fef..2a72d42296d19b733c05fb300a967af1d43cb598 100644 (file)
@@ -166,6 +166,9 @@ pub struct LocalCrateContext<'tcx> {
     type_of_depth: Cell<usize>,
 
     symbol_map: Rc<SymbolMap<'tcx>>,
+
+    /// A counter that is used for generating local symbol names
+    local_gen_sym_counter: Cell<usize>,
 }
 
 // Implement DepTrackingMapConfig for `trait_cache`
@@ -688,6 +691,7 @@ fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
                 n_llvm_insns: Cell::new(0),
                 type_of_depth: Cell::new(0),
                 symbol_map: symbol_map,
+                local_gen_sym_counter: Cell::new(0),
             };
 
             let (int_type, opaque_vec_type, str_slice_ty, mut local_ccx) = {
@@ -1021,6 +1025,16 @@ pub fn translation_items(&self) -> &RefCell<FnvHashSet<TransItem<'tcx>>> {
     pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
         self.shared().empty_substs_for_def_id(item_def_id)
     }
+
+    /// Generate a new symbol name with the given prefix. This symbol name must
+    /// only be used for definitions with `internal` or `private` linkage.
+    pub fn generate_local_symbol_name(&self, prefix: &str) -> String {
+        let idx = self.local().local_gen_sym_counter.get();
+        self.local().local_gen_sym_counter.set(idx + 1);
+        // Include a '.' character, so there can be no accidental conflicts with
+        // user defined names
+        format!("{}.{}", prefix, idx)
+    }
 }
 
 pub struct TypeOfDepthLock<'a, 'tcx: 'a>(&'a LocalCrateContext<'tcx>);