about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo.net>2016-06-09 13:39:21 -0400
committerMichael Woerister <michaelwoerister@posteo.net>2016-07-08 10:42:48 -0400
commitb149b9d19bb4dfbda4145b2667d87168da1e57d6 (patch)
treea57f4b13fa2dfe97cc6b27fc2e94e39b694646cc
parent4c27a3c6d597ce5ecd1b71e99e48075e625e7b27 (diff)
downloadrust-b149b9d19bb4dfbda4145b2667d87168da1e57d6.tar.gz
rust-b149b9d19bb4dfbda4145b2667d87168da1e57d6.zip
trans: Set COMDAT section for weak symbols so that Windows can handle them.
-rw-r--r--src/librustc_trans/closure.rs1
-rw-r--r--src/librustc_trans/trans_item.rs10
2 files changed, 10 insertions, 1 deletions
diff --git a/src/librustc_trans/closure.rs b/src/librustc_trans/closure.rs
index bf9cde9a441..b992ba362a9 100644
--- a/src/librustc_trans/closure.rs
+++ b/src/librustc_trans/closure.rs
@@ -212,6 +212,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
 
     let llfn = get_or_create_closure_declaration(ccx, closure_def_id, closure_substs);
     llvm::SetLinkage(llfn, llvm::WeakODRLinkage);
+    llvm::SetUniqueComdat(ccx.llmod(), llfn);
 
     // Get the type of this closure. Use the current `param_substs` as
     // the closure substitutions. This makes sense because the closure
diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs
index 2fc90b821fe..b9700f2cacf 100644
--- a/src/librustc_trans/trans_item.rs
+++ b/src/librustc_trans/trans_item.rs
@@ -190,9 +190,13 @@ impl<'a, 'tcx> TransItem<'tcx> {
             }) => {
                 let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty);
                 llvm::SetLinkage(lldecl, linkage);
-                attributes::from_fn_attrs(ccx, attrs, lldecl);
                 base::set_link_section(ccx, lldecl, attrs);
+                if linkage == llvm::LinkOnceODRLinkage ||
+                   linkage == llvm::WeakODRLinkage {
+                    llvm::SetUniqueComdat(ccx.llmod(), lldecl);
+                }
 
+                attributes::from_fn_attrs(ccx, attrs, lldecl);
                 ccx.instances().borrow_mut().insert(instance, lldecl);
             }
             _ => bug!("Invalid item for TransItem::Fn: `{:?}`", map_node)
@@ -223,6 +227,10 @@ impl<'a, 'tcx> TransItem<'tcx> {
         assert!(declare::get_defined_value(ccx, symbol_name).is_none());
         let llfn = declare::declare_cfn(ccx, symbol_name, llfnty);
         llvm::SetLinkage(llfn, linkage);
+        if linkage == llvm::LinkOnceODRLinkage ||
+           linkage == llvm::WeakODRLinkage {
+            llvm::SetUniqueComdat(ccx.llmod(), llfn);
+        }
         attributes::set_frame_pointer_elimination(ccx, llfn);
         ccx.drop_glues().borrow_mut().insert(dg, (llfn, fn_ty));
     }