b4ce4e3b09
Backport rust#91070, fixes rhbz#1990657 Add rust-std-static-wasm32-wasi
95 lines
3.1 KiB
Diff
95 lines
3.1 KiB
Diff
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
|
|
index e77d29bed712..f3d8eb2602a3 100644
|
|
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
|
|
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
|
|
@@ -124,8 +124,18 @@ extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
|
|
|
|
extern "C" LLVMValueRef
|
|
LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
|
|
+ Module *Mod = unwrap(M);
|
|
StringRef NameRef(Name, NameLen);
|
|
- return wrap(unwrap(M)->getOrInsertGlobal(NameRef, unwrap(Ty)));
|
|
+
|
|
+ // We don't use Module::getOrInsertGlobal because that returns a Constant*,
|
|
+ // which may either be the real GlobalVariable*, or a constant bitcast of it
|
|
+ // if our type doesn't match the original declaration. We always want the
|
|
+ // GlobalVariable* so we can access linkage, visibility, etc.
|
|
+ GlobalVariable *GV = Mod->getGlobalVariable(NameRef, true);
|
|
+ if (!GV)
|
|
+ GV = new GlobalVariable(*Mod, unwrap(Ty), false,
|
|
+ GlobalValue::ExternalLinkage, nullptr, NameRef);
|
|
+ return wrap(GV);
|
|
}
|
|
|
|
extern "C" LLVMValueRef
|
|
diff --git a/src/test/ui/statics/issue-91050-1.rs b/src/test/ui/statics/issue-91050-1.rs
|
|
new file mode 100644
|
|
index 000000000000..403a41462ef1
|
|
--- /dev/null
|
|
+++ b/src/test/ui/statics/issue-91050-1.rs
|
|
@@ -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];
|
|
+}
|
|
diff --git a/src/test/ui/statics/issue-91050-2.rs b/src/test/ui/statics/issue-91050-2.rs
|
|
new file mode 100644
|
|
index 000000000000..2ff954d15cab
|
|
--- /dev/null
|
|
+++ b/src/test/ui/statics/issue-91050-2.rs
|
|
@@ -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
|
|
+ }
|
|
+}
|