Skip to content

Commit 0720b33

Browse files
authored
Unrolled build for rust-lang#132260
Rollup merge of rust-lang#132260 - Zalathar:type-safe-cast, r=compiler-errors cg_llvm: Use a type-safe helper to cast `&str` and `&[u8]` to `*const c_char` In `rustc_codegen_llvm` there are many uses of `.as_ptr().cast()` to convert a string or byte-slice to `*const c_char`, which then gets passed through FFI. This works, but is fragile, because there's nothing constraining the pointer cast to actually be from `u8` to `c_char`. If the original value changes to something else that has an `as_ptr` method, or the context changes to expect something other than `c_char`, the cast will silently do the wrong thing. By making the cast more explicit via a helper method, we can be sure that it will either perform the intended cast, or fail at compile time.
2 parents a9d1762 + 4bd84b2 commit 0720b33

File tree

17 files changed

+110
-87
lines changed

17 files changed

+110
-87
lines changed

compiler/rustc_codegen_llvm/src/allocator.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_middle::bug;
77
use rustc_middle::ty::TyCtxt;
88
use rustc_session::config::{DebugInfo, OomStrategy};
99

10+
use crate::common::AsCCharPtr;
1011
use crate::llvm::{self, Context, False, Module, True, Type};
1112
use crate::{ModuleLlvm, attributes, debuginfo};
1213

@@ -76,14 +77,14 @@ pub(crate) unsafe fn codegen(
7677
unsafe {
7778
// __rust_alloc_error_handler_should_panic
7879
let name = OomStrategy::SYMBOL;
79-
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
80+
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_c_char_ptr(), name.len(), i8);
8081
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
8182
let val = tcx.sess.opts.unstable_opts.oom.should_panic();
8283
let llval = llvm::LLVMConstInt(i8, val as u64, False);
8384
llvm::LLVMSetInitializer(ll_g, llval);
8485

8586
let name = NO_ALLOC_SHIM_IS_UNSTABLE;
86-
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
87+
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_c_char_ptr(), name.len(), i8);
8788
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
8889
let llval = llvm::LLVMConstInt(i8, 0, False);
8990
llvm::LLVMSetInitializer(ll_g, llval);
@@ -115,7 +116,7 @@ fn create_wrapper_function(
115116
);
116117
let llfn = llvm::LLVMRustGetOrInsertFunction(
117118
llmod,
118-
from_name.as_ptr().cast(),
119+
from_name.as_c_char_ptr(),
119120
from_name.len(),
120121
ty,
121122
);
@@ -137,7 +138,7 @@ fn create_wrapper_function(
137138
}
138139

139140
let callee =
140-
llvm::LLVMRustGetOrInsertFunction(llmod, to_name.as_ptr().cast(), to_name.len(), ty);
141+
llvm::LLVMRustGetOrInsertFunction(llmod, to_name.as_c_char_ptr(), to_name.len(), ty);
141142
if let Some(no_return) = no_return {
142143
// -> ! DIFlagNoReturn
143144
attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);

compiler/rustc_codegen_llvm/src/asm.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use smallvec::SmallVec;
1515
use tracing::debug;
1616

1717
use crate::builder::Builder;
18-
use crate::common::Funclet;
18+
use crate::common::{AsCCharPtr, Funclet};
1919
use crate::context::CodegenCx;
2020
use crate::type_::Type;
2121
use crate::type_of::LayoutLlvmExt;
@@ -420,7 +420,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
420420
unsafe {
421421
llvm::LLVMAppendModuleInlineAsm(
422422
self.llmod,
423-
template_str.as_ptr().cast(),
423+
template_str.as_c_char_ptr(),
424424
template_str.len(),
425425
);
426426
}
@@ -458,14 +458,14 @@ pub(crate) fn inline_asm_call<'ll>(
458458
let fty = bx.cx.type_func(&argtys, output);
459459
unsafe {
460460
// Ask LLVM to verify that the constraints are well-formed.
461-
let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr().cast(), cons.len());
461+
let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_c_char_ptr(), cons.len());
462462
debug!("constraint verification result: {:?}", constraints_ok);
463463
if constraints_ok {
464464
let v = llvm::LLVMRustInlineAsm(
465465
fty,
466-
asm.as_ptr().cast(),
466+
asm.as_c_char_ptr(),
467467
asm.len(),
468-
cons.as_ptr().cast(),
468+
cons.as_c_char_ptr(),
469469
cons.len(),
470470
volatile,
471471
alignstack,

compiler/rustc_codegen_llvm/src/back/lto.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use tracing::{debug, info};
2525
use crate::back::write::{
2626
self, CodegenDiagnosticsStage, DiagnosticHandlers, bitcode_section_name, save_temp_bitcode,
2727
};
28+
use crate::common::AsCCharPtr;
2829
use crate::errors::{
2930
DynamicLinkingWithLTO, LlvmError, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib, LtoProcMacro,
3031
};
@@ -604,7 +605,7 @@ pub(crate) fn run_pass_manager(
604605
unsafe {
605606
if !llvm::LLVMRustHasModuleFlag(
606607
module.module_llvm.llmod(),
607-
"LTOPostLink".as_ptr().cast(),
608+
"LTOPostLink".as_c_char_ptr(),
608609
11,
609610
) {
610611
llvm::LLVMRustAddModuleFlagU32(

compiler/rustc_codegen_llvm/src/back/write.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use crate::back::owned_target_machine::OwnedTargetMachine;
3434
use crate::back::profiling::{
3535
LlvmSelfProfiler, selfprofile_after_pass_callback, selfprofile_before_pass_callback,
3636
};
37+
use crate::common::AsCCharPtr;
3738
use crate::errors::{
3839
CopyBitcode, FromLlvmDiag, FromLlvmOptimizationDiag, LlvmError, UnknownCompression,
3940
WithLlvmError, WriteBytecode,
@@ -596,9 +597,9 @@ pub(crate) unsafe fn llvm_optimize(
596597
llvm_selfprofiler,
597598
selfprofile_before_pass_callback,
598599
selfprofile_after_pass_callback,
599-
extra_passes.as_ptr().cast(),
600+
extra_passes.as_c_char_ptr(),
600601
extra_passes.len(),
601-
llvm_plugins.as_ptr().cast(),
602+
llvm_plugins.as_c_char_ptr(),
602603
llvm_plugins.len(),
603604
)
604605
};
@@ -1042,7 +1043,7 @@ unsafe fn embed_bitcode(
10421043
llvm::LLVMSetInitializer(llglobal, llconst);
10431044

10441045
let section = bitcode_section_name(cgcx);
1045-
llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
1046+
llvm::LLVMSetSection(llglobal, section.as_c_char_ptr());
10461047
llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage);
10471048
llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
10481049

@@ -1066,9 +1067,9 @@ unsafe fn embed_bitcode(
10661067
// We need custom section flags, so emit module-level inline assembly.
10671068
let section_flags = if cgcx.is_pe_coff { "n" } else { "e" };
10681069
let asm = create_section_with_flags_asm(".llvmbc", section_flags, bitcode);
1069-
llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
1070+
llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_c_char_ptr(), asm.len());
10701071
let asm = create_section_with_flags_asm(".llvmcmd", section_flags, cmdline.as_bytes());
1071-
llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
1072+
llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_c_char_ptr(), asm.len());
10721073
}
10731074
}
10741075
}

compiler/rustc_codegen_llvm/src/common.rs

+18
Original file line numberDiff line numberDiff line change
@@ -392,3 +392,21 @@ pub(crate) fn get_dllimport<'tcx>(
392392
tcx.native_library(id)
393393
.and_then(|lib| lib.dll_imports.iter().find(|di| di.name.as_str() == name))
394394
}
395+
396+
/// Extension trait for explicit casts to `*const c_char`.
397+
pub(crate) trait AsCCharPtr {
398+
/// Equivalent to `self.as_ptr().cast()`, but only casts to `*const c_char`.
399+
fn as_c_char_ptr(&self) -> *const c_char;
400+
}
401+
402+
impl AsCCharPtr for str {
403+
fn as_c_char_ptr(&self) -> *const c_char {
404+
self.as_ptr().cast()
405+
}
406+
}
407+
408+
impl AsCCharPtr for [u8] {
409+
fn as_c_char_ptr(&self) -> *const c_char {
410+
self.as_ptr().cast()
411+
}
412+
}

compiler/rustc_codegen_llvm/src/consts.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_target::abi::{
1919
};
2020
use tracing::{debug, instrument, trace};
2121

22-
use crate::common::CodegenCx;
22+
use crate::common::{AsCCharPtr, CodegenCx};
2323
use crate::errors::{
2424
InvalidMinimumAlignmentNotPowerOfTwo, InvalidMinimumAlignmentTooLarge, SymbolAlreadyDefined,
2525
};
@@ -400,7 +400,7 @@ impl<'ll> CodegenCx<'ll, '_> {
400400

401401
let new_g = llvm::LLVMRustGetOrInsertGlobal(
402402
self.llmod,
403-
name.as_ptr().cast(),
403+
name.as_c_char_ptr(),
404404
name.len(),
405405
val_llty,
406406
);
@@ -451,7 +451,7 @@ impl<'ll> CodegenCx<'ll, '_> {
451451
if let Some(section) = attrs.link_section {
452452
let section = llvm::LLVMMDStringInContext2(
453453
self.llcx,
454-
section.as_str().as_ptr().cast(),
454+
section.as_str().as_c_char_ptr(),
455455
section.as_str().len(),
456456
);
457457
assert!(alloc.provenance().ptrs().is_empty());
@@ -462,7 +462,7 @@ impl<'ll> CodegenCx<'ll, '_> {
462462
let bytes =
463463
alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len());
464464
let alloc =
465-
llvm::LLVMMDStringInContext2(self.llcx, bytes.as_ptr().cast(), bytes.len());
465+
llvm::LLVMMDStringInContext2(self.llcx, bytes.as_c_char_ptr(), bytes.len());
466466
let data = [section, alloc];
467467
let meta = llvm::LLVMMDNodeInContext2(self.llcx, data.as_ptr(), data.len());
468468
let val = llvm::LLVMMetadataAsValue(self.llcx, meta);

compiler/rustc_codegen_llvm/src/context.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use smallvec::SmallVec;
2929

3030
use crate::back::write::to_llvm_code_model;
3131
use crate::callee::get_fn;
32+
use crate::common::AsCCharPtr;
3233
use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
3334
use crate::llvm::{Metadata, MetadataType};
3435
use crate::type_::Type;
@@ -231,7 +232,7 @@ pub(crate) unsafe fn create_module<'ll>(
231232
// If we're normalizing integers with CFI, ensure LLVM generated functions do the same.
232233
// See https://github.com/llvm/llvm-project/pull/104826
233234
if sess.is_sanitizer_cfi_normalize_integers_enabled() {
234-
let cfi_normalize_integers = c"cfi-normalize-integers".as_ptr().cast();
235+
let cfi_normalize_integers = c"cfi-normalize-integers".as_ptr();
235236
unsafe {
236237
llvm::LLVMRustAddModuleFlagU32(
237238
llmod,
@@ -268,7 +269,7 @@ pub(crate) unsafe fn create_module<'ll>(
268269
let pfe =
269270
PatchableFunctionEntry::from_config(sess.opts.unstable_opts.patchable_function_entry);
270271
if pfe.prefix() > 0 {
271-
let kcfi_offset = c"kcfi-offset".as_ptr().cast();
272+
let kcfi_offset = c"kcfi-offset".as_ptr();
272273
unsafe {
273274
llvm::LLVMRustAddModuleFlagU32(
274275
llmod,
@@ -429,7 +430,7 @@ pub(crate) unsafe fn create_module<'ll>(
429430
let name_metadata = unsafe {
430431
llvm::LLVMMDStringInContext2(
431432
llcx,
432-
rustc_producer.as_ptr().cast(),
433+
rustc_producer.as_c_char_ptr(),
433434
rustc_producer.as_bytes().len(),
434435
)
435436
};
@@ -453,7 +454,7 @@ pub(crate) unsafe fn create_module<'ll>(
453454
llmod,
454455
llvm::LLVMModFlagBehavior::Error,
455456
c"target-abi".as_ptr(),
456-
llvm_abiname.as_ptr().cast(),
457+
llvm_abiname.as_c_char_ptr(),
457458
llvm_abiname.len(),
458459
);
459460
}
@@ -474,7 +475,7 @@ pub(crate) unsafe fn create_module<'ll>(
474475
// We already checked this during option parsing
475476
_ => unreachable!(),
476477
};
477-
unsafe { llvm::LLVMRustAddModuleFlagU32(llmod, behavior, key.as_ptr().cast(), *value) }
478+
unsafe { llvm::LLVMRustAddModuleFlagU32(llmod, behavior, key.as_c_char_ptr(), *value) }
478479
}
479480

480481
llmod

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_target::abi::Size;
1414
use tracing::{debug, instrument};
1515

1616
use crate::builder::Builder;
17-
use crate::common::CodegenCx;
17+
use crate::common::{AsCCharPtr, CodegenCx};
1818
use crate::coverageinfo::map_data::FunctionCoverageCollector;
1919
use crate::llvm;
2020

@@ -236,7 +236,7 @@ fn create_pgo_func_name_var<'ll, 'tcx>(
236236
unsafe {
237237
llvm::LLVMRustCoverageCreatePGOFuncNameVar(
238238
llfn,
239-
mangled_fn_name.as_ptr().cast(),
239+
mangled_fn_name.as_c_char_ptr(),
240240
mangled_fn_name.len(),
241241
)
242242
}
@@ -248,7 +248,7 @@ pub(crate) fn write_filenames_section_to_buffer<'a>(
248248
) {
249249
let (pointers, lengths) = filenames
250250
.into_iter()
251-
.map(|s: &str| (s.as_ptr().cast(), s.len()))
251+
.map(|s: &str| (s.as_c_char_ptr(), s.len()))
252252
.unzip::<_, _, Vec<_>, Vec<_>>();
253253

254254
unsafe {
@@ -291,7 +291,7 @@ pub(crate) fn write_mapping_to_buffer(
291291
}
292292

293293
pub(crate) fn hash_bytes(bytes: &[u8]) -> u64 {
294-
unsafe { llvm::LLVMRustCoverageHashByteArray(bytes.as_ptr().cast(), bytes.len()) }
294+
unsafe { llvm::LLVMRustCoverageHashByteArray(bytes.as_c_char_ptr(), bytes.len()) }
295295
}
296296

297297
pub(crate) fn mapping_version() -> u32 {

0 commit comments

Comments
 (0)