Rollup merge of #91070 - cuviper:insert-global, r=nagisa
Make `LLVMRustGetOrInsertGlobal` always return a `GlobalVariable` `Module::getOrInsertGlobal` returns a `Constant*`, which is a super class of `GlobalVariable`, but if the given type doesn't match an existing declaration, it returns a bitcast of that global instead. This causes UB when we pass that to `LLVMGetVisibility` which unconditionally casts the opaque argument to a `GlobalValue*`. Instead, we can do our own get-or-insert without worrying whether existing types match exactly. It's not relevant when we're just trying to get/set the linkage and visibility, and if types are needed we can bitcast or error nicely from `rustc_codegen_llvm` instead. Fixes #91050, fixes #87933, fixes #87813.
This commit is contained in:
commit
df552b3c24
3 changed files with 69 additions and 1 deletions
34
src/test/ui/statics/issue-91050-1.rs
Normal file
34
src/test/ui/statics/issue-91050-1.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// build-pass
|
||||
// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes
|
||||
|
||||
// This test declares globals by the same name with different types, which
|
||||
// caused problems because Module::getOrInsertGlobal would return a Constant*
|
||||
// bitcast instead of a GlobalVariable* that could access linkage/visibility.
|
||||
// In alt builds with LLVM assertions this would fail:
|
||||
//
|
||||
// rustc: /checkout/src/llvm-project/llvm/include/llvm/Support/Casting.h:269:
|
||||
// typename cast_retty<X, Y *>::ret_type llvm::cast(Y *) [X = llvm::GlobalValue, Y = llvm::Value]:
|
||||
// Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
|
||||
//
|
||||
// In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!"
|
||||
|
||||
pub mod before {
|
||||
#[no_mangle]
|
||||
pub static GLOBAL1: [u8; 1] = [1];
|
||||
}
|
||||
|
||||
pub mod inner {
|
||||
extern "C" {
|
||||
pub static GLOBAL1: u8;
|
||||
pub static GLOBAL2: u8;
|
||||
}
|
||||
|
||||
pub fn call() {
|
||||
drop(unsafe { (GLOBAL1, GLOBAL2) });
|
||||
}
|
||||
}
|
||||
|
||||
pub mod after {
|
||||
#[no_mangle]
|
||||
pub static GLOBAL2: [u8; 1] = [2];
|
||||
}
|
||||
24
src/test/ui/statics/issue-91050-2.rs
Normal file
24
src/test/ui/statics/issue-91050-2.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// build-pass
|
||||
// compile-flags: --crate-type=rlib --emit=llvm-ir -Cno-prepopulate-passes
|
||||
|
||||
// This is a variant of issue-91050-1.rs -- see there for an explanation.
|
||||
|
||||
pub mod before {
|
||||
extern "C" {
|
||||
pub static GLOBAL1: [u8; 1];
|
||||
}
|
||||
|
||||
pub unsafe fn do_something_with_array() -> u8 {
|
||||
GLOBAL1[0]
|
||||
}
|
||||
}
|
||||
|
||||
pub mod inner {
|
||||
extern "C" {
|
||||
pub static GLOBAL1: u8;
|
||||
}
|
||||
|
||||
pub unsafe fn call() -> u8 {
|
||||
GLOBAL1 + 42
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue