Use weak_odr linkage when reusing definitions across codegen units
When reuing a definition across codegen units, we obviously cannot use internal linkage, but using external linkage means that we can end up with multiple conflicting definitions of a single symbol across multiple crates. Since the definitions should all be equal semantically, we can use weak_odr linkage to resolve the situation. Fixes #32518
This commit is contained in:
@@ -2125,6 +2125,9 @@ extern {
|
||||
pub fn LLVMRustFreeOperandBundleDef(Bundle: OperandBundleDefRef);
|
||||
|
||||
pub fn LLVMRustPositionBuilderAtStart(B: BuilderRef, BB: BasicBlockRef);
|
||||
|
||||
pub fn LLVMRustSetComdat(M: ModuleRef, V: ValueRef, Name: *const c_char);
|
||||
pub fn LLVMRustUnsetComdat(V: ValueRef);
|
||||
}
|
||||
|
||||
// LLVM requires symbols from this library, but apparently they're not printed
|
||||
@@ -2149,6 +2152,24 @@ pub fn SetLinkage(global: ValueRef, link: Linkage) {
|
||||
}
|
||||
}
|
||||
|
||||
// Externally visible symbols that might appear in multiple translation units need to appear in
|
||||
// their own comdat section so that the duplicates can be discarded at link time. This can for
|
||||
// example happen for generics when using multiple codegen units. This function simply uses the
|
||||
// value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the
|
||||
// function.
|
||||
// For more details on COMDAT sections see e.g. http://www.airs.com/blog/archives/52
|
||||
pub fn SetUniqueComdat(llmod: ModuleRef, val: ValueRef) {
|
||||
unsafe {
|
||||
LLVMRustSetComdat(llmod, val, LLVMGetValueName(val));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn UnsetComdat(val: ValueRef) {
|
||||
unsafe {
|
||||
LLVMRustUnsetComdat(val);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn SetDLLStorageClass(global: ValueRef, class: DLLStorageClassTypes) {
|
||||
unsafe {
|
||||
LLVMRustSetDLLStorageClass(global, class);
|
||||
|
||||
Reference in New Issue
Block a user