about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/context.rs')
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs259
1 files changed, 149 insertions, 110 deletions
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 77beb9a6bb3..49677dcf12f 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -120,7 +120,7 @@ pub unsafe fn create_module<'ll>(
 ) -> &'ll llvm::Module {
     let sess = tcx.sess;
     let mod_name = SmallCStr::new(mod_name);
-    let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
+    let llmod = unsafe { llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx) };
 
     let mut target_data_layout = sess.target.data_layout.to_string();
     let llvm_version = llvm_util::get_version();
@@ -153,11 +153,14 @@ pub unsafe fn create_module<'ll>(
     // Ensure the data-layout values hardcoded remain the defaults.
     {
         let tm = crate::back::write::create_informational_target_machine(tcx.sess);
-        llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
+        unsafe {
+            llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
+        }
 
-        let llvm_data_layout = llvm::LLVMGetDataLayoutStr(llmod);
-        let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes())
-            .expect("got a non-UTF8 data-layout from LLVM");
+        let llvm_data_layout = unsafe { llvm::LLVMGetDataLayoutStr(llmod) };
+        let llvm_data_layout =
+            str::from_utf8(unsafe { CStr::from_ptr(llvm_data_layout) }.to_bytes())
+                .expect("got a non-UTF8 data-layout from LLVM");
 
         if target_data_layout != llvm_data_layout {
             tcx.dcx().emit_err(crate::errors::MismatchedDataLayout {
@@ -170,20 +173,28 @@ pub unsafe fn create_module<'ll>(
     }
 
     let data_layout = SmallCStr::new(&target_data_layout);
-    llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
+    unsafe {
+        llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
+    }
 
     let llvm_target = SmallCStr::new(&sess.target.llvm_target);
-    llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
+    unsafe {
+        llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
+    }
 
     let reloc_model = sess.relocation_model();
     if matches!(reloc_model, RelocModel::Pic | RelocModel::Pie) {
-        llvm::LLVMRustSetModulePICLevel(llmod);
+        unsafe {
+            llvm::LLVMRustSetModulePICLevel(llmod);
+        }
         // PIE is potentially more effective than PIC, but can only be used in executables.
         // If all our outputs are executables, then we can relax PIC to PIE.
         if reloc_model == RelocModel::Pie
             || tcx.crate_types().iter().all(|ty| *ty == CrateType::Executable)
         {
-            llvm::LLVMRustSetModulePIELevel(llmod);
+            unsafe {
+                llvm::LLVMRustSetModulePIELevel(llmod);
+            }
         }
     }
 
@@ -192,95 +203,109 @@ pub unsafe fn create_module<'ll>(
     // longer jumps) if a larger code model is used with a smaller one.
     //
     // See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323.
-    llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model()));
+    unsafe {
+        llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model()));
+    }
 
     // If skipping the PLT is enabled, we need to add some module metadata
     // to ensure intrinsic calls don't use it.
     if !sess.needs_plt() {
         let avoid_plt = c"RtLibUseGOT".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1);
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1);
+        }
     }
 
     // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.)
     if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() {
         let canonical_jump_tables = c"CFI Canonical Jump Tables".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Override,
-            canonical_jump_tables,
-            1,
-        );
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Override,
+                canonical_jump_tables,
+                1,
+            );
+        }
     }
 
     // Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
     if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
         let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Override,
-            enable_split_lto_unit,
-            1,
-        );
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Override,
+                enable_split_lto_unit,
+                1,
+            );
+        }
     }
 
     // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.)
     if sess.is_sanitizer_kcfi_enabled() {
         let kcfi = c"kcfi".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
+        }
     }
 
     // Control Flow Guard is currently only supported by the MSVC linker on Windows.
     if sess.target.is_like_msvc {
-        match sess.opts.cg.control_flow_guard {
-            CFGuard::Disabled => {}
-            CFGuard::NoChecks => {
-                // Set `cfguard=1` module flag to emit metadata only.
-                llvm::LLVMRustAddModuleFlagU32(
-                    llmod,
-                    llvm::LLVMModFlagBehavior::Warning,
-                    c"cfguard".as_ptr() as *const _,
-                    1,
-                )
-            }
-            CFGuard::Checks => {
-                // Set `cfguard=2` module flag to emit metadata and checks.
-                llvm::LLVMRustAddModuleFlagU32(
-                    llmod,
-                    llvm::LLVMModFlagBehavior::Warning,
-                    c"cfguard".as_ptr() as *const _,
-                    2,
-                )
+        unsafe {
+            match sess.opts.cg.control_flow_guard {
+                CFGuard::Disabled => {}
+                CFGuard::NoChecks => {
+                    // Set `cfguard=1` module flag to emit metadata only.
+                    llvm::LLVMRustAddModuleFlagU32(
+                        llmod,
+                        llvm::LLVMModFlagBehavior::Warning,
+                        c"cfguard".as_ptr() as *const _,
+                        1,
+                    )
+                }
+                CFGuard::Checks => {
+                    // Set `cfguard=2` module flag to emit metadata and checks.
+                    llvm::LLVMRustAddModuleFlagU32(
+                        llmod,
+                        llvm::LLVMModFlagBehavior::Warning,
+                        c"cfguard".as_ptr() as *const _,
+                        2,
+                    )
+                }
             }
         }
     }
 
     if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection {
         if sess.target.arch == "aarch64" {
-            llvm::LLVMRustAddModuleFlagU32(
-                llmod,
-                llvm::LLVMModFlagBehavior::Min,
-                c"branch-target-enforcement".as_ptr().cast(),
-                bti.into(),
-            );
-            llvm::LLVMRustAddModuleFlagU32(
-                llmod,
-                llvm::LLVMModFlagBehavior::Min,
-                c"sign-return-address".as_ptr().cast(),
-                pac_ret.is_some().into(),
-            );
-            let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
-            llvm::LLVMRustAddModuleFlagU32(
-                llmod,
-                llvm::LLVMModFlagBehavior::Min,
-                c"sign-return-address-all".as_ptr().cast(),
-                pac_opts.leaf.into(),
-            );
-            llvm::LLVMRustAddModuleFlagU32(
-                llmod,
-                llvm::LLVMModFlagBehavior::Min,
-                c"sign-return-address-with-bkey".as_ptr().cast(),
-                u32::from(pac_opts.key == PAuthKey::B),
-            );
+            unsafe {
+                llvm::LLVMRustAddModuleFlagU32(
+                    llmod,
+                    llvm::LLVMModFlagBehavior::Min,
+                    c"branch-target-enforcement".as_ptr().cast(),
+                    bti.into(),
+                );
+                llvm::LLVMRustAddModuleFlagU32(
+                    llmod,
+                    llvm::LLVMModFlagBehavior::Min,
+                    c"sign-return-address".as_ptr().cast(),
+                    pac_ret.is_some().into(),
+                );
+                let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
+                llvm::LLVMRustAddModuleFlagU32(
+                    llmod,
+                    llvm::LLVMModFlagBehavior::Min,
+                    c"sign-return-address-all".as_ptr().cast(),
+                    pac_opts.leaf.into(),
+                );
+                llvm::LLVMRustAddModuleFlagU32(
+                    llmod,
+                    llvm::LLVMModFlagBehavior::Min,
+                    c"sign-return-address-with-bkey".as_ptr().cast(),
+                    u32::from(pac_opts.key == PAuthKey::B),
+                );
+            }
         } else {
             bug!(
                 "branch-protection used on non-AArch64 target; \
@@ -291,39 +316,47 @@ pub unsafe fn create_module<'ll>(
 
     // Pass on the control-flow protection flags to LLVM (equivalent to `-fcf-protection` in Clang).
     if let CFProtection::Branch | CFProtection::Full = sess.opts.unstable_opts.cf_protection {
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Override,
-            c"cf-protection-branch".as_ptr().cast(),
-            1,
-        )
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Override,
+                c"cf-protection-branch".as_ptr().cast(),
+                1,
+            );
+        }
     }
     if let CFProtection::Return | CFProtection::Full = sess.opts.unstable_opts.cf_protection {
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Override,
-            c"cf-protection-return".as_ptr().cast(),
-            1,
-        )
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Override,
+                c"cf-protection-return".as_ptr().cast(),
+                1,
+            );
+        }
     }
 
     if sess.opts.unstable_opts.virtual_function_elimination {
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Error,
-            c"Virtual Function Elim".as_ptr().cast(),
-            1,
-        );
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Error,
+                c"Virtual Function Elim".as_ptr().cast(),
+                1,
+            );
+        }
     }
 
     // Set module flag to enable Windows EHCont Guard (/guard:ehcont).
     if sess.opts.unstable_opts.ehcont_guard {
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Warning,
-            c"ehcontguard".as_ptr() as *const _,
-            1,
-        )
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Warning,
+                c"ehcontguard".as_ptr() as *const _,
+                1,
+            )
+        }
     }
 
     // Insert `llvm.ident` metadata.
@@ -333,16 +366,20 @@ pub unsafe fn create_module<'ll>(
     #[allow(clippy::option_env_unwrap)]
     let rustc_producer =
         format!("rustc version {}", option_env!("CFG_VERSION").expect("CFG_VERSION"));
-    let name_metadata = llvm::LLVMMDStringInContext(
-        llcx,
-        rustc_producer.as_ptr().cast(),
-        rustc_producer.as_bytes().len() as c_uint,
-    );
-    llvm::LLVMAddNamedMetadataOperand(
-        llmod,
-        c"llvm.ident".as_ptr(),
-        llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1),
-    );
+    let name_metadata = unsafe {
+        llvm::LLVMMDStringInContext(
+            llcx,
+            rustc_producer.as_ptr().cast(),
+            rustc_producer.as_bytes().len() as c_uint,
+        )
+    };
+    unsafe {
+        llvm::LLVMAddNamedMetadataOperand(
+            llmod,
+            c"llvm.ident".as_ptr(),
+            llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1),
+        );
+    }
 
     // Emit RISC-V specific target-abi metadata
     // to workaround lld as the LTO plugin not
@@ -351,13 +388,15 @@ pub unsafe fn create_module<'ll>(
     // If llvm_abiname is empty, emit nothing.
     let llvm_abiname = &sess.target.options.llvm_abiname;
     if matches!(sess.target.arch.as_ref(), "riscv32" | "riscv64") && !llvm_abiname.is_empty() {
-        llvm::LLVMRustAddModuleFlagString(
-            llmod,
-            llvm::LLVMModFlagBehavior::Error,
-            c"target-abi".as_ptr(),
-            llvm_abiname.as_ptr().cast(),
-            llvm_abiname.len(),
-        );
+        unsafe {
+            llvm::LLVMRustAddModuleFlagString(
+                llmod,
+                llvm::LLVMModFlagBehavior::Error,
+                c"target-abi".as_ptr(),
+                llvm_abiname.as_ptr().cast(),
+                llvm_abiname.len(),
+            );
+        }
     }
 
     // Add module flags specified via -Z llvm_module_flag
@@ -375,7 +414,7 @@ pub unsafe fn create_module<'ll>(
             // We already checked this during option parsing
             _ => unreachable!(),
         };
-        llvm::LLVMRustAddModuleFlagU32(llmod, behavior, key.as_ptr().cast(), *value)
+        unsafe { llvm::LLVMRustAddModuleFlagU32(llmod, behavior, key.as_ptr().cast(), *value) }
     }
 
     llmod