diff options
| author | Josh Stone <jistone@redhat.com> | 2021-11-19 19:33:29 -0800 |
|---|---|---|
| committer | Josh Stone <jistone@redhat.com> | 2021-11-19 19:33:29 -0800 |
| commit | 023cc968e1295994ed8039da43b0f2f4ea4e9390 (patch) | |
| tree | 4bc92bd38d5dc3ff7f8f157eee092cd69dcd3a1f /src | |
| parent | a77da2d454e6caa227a85b16410b95f93495e7e0 (diff) | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/test/ui/issues/issue-91050.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/test/ui/issues/issue-91050.rs b/src/test/ui/issues/issue-91050.rs new file mode 100644 index 00000000000..50763d30931 --- /dev/null +++ b/src/test/ui/issues/issue-91050.rs @@ -0,0 +1,34 @@ +// build-pass +// compile-flags: --crate-type lib -Ccodegen-units=1 + +// 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]; +} |
