Skip to content

Commit c642e39

Browse files
committed
Use a dedicated safe wrapper for LLVMRustGetHostCPUName
1 parent a2ccd97 commit c642e39

File tree

3 files changed

+25
-17
lines changed

3 files changed

+25
-17
lines changed

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2204,7 +2204,7 @@ unsafe extern "C" {
22042204
Desc: &mut *const c_char,
22052205
);
22062206

2207-
pub fn LLVMRustGetHostCPUName(len: *mut usize) -> *const c_char;
2207+
pub fn LLVMRustGetHostCPUName(LenOut: &mut size_t) -> *const u8;
22082208

22092209
// This function makes copies of pointed to data, so the data's lifetime may end after this
22102210
// function returns.

compiler/rustc_codegen_llvm/src/llvm_util.rs

+22-14
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ pub(crate) fn print(req: &PrintRequest, mut out: &mut String, sess: &Session) {
455455
// SAFETY generate a C compatible string from a byte slice to pass
456456
// the target CPU name into LLVM, the lifetime of the reference is
457457
// at least as long as the C function
458-
let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref()))
458+
let cpu_cstring = CString::new(resolve_native_cpu(sess.target.cpu.as_ref()))
459459
.unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e));
460460
unsafe extern "C" fn callback(out: *mut c_void, string: *const c_char, len: usize) {
461461
let out = unsafe { &mut *(out as *mut &mut String) };
@@ -476,23 +476,31 @@ pub(crate) fn print(req: &PrintRequest, mut out: &mut String, sess: &Session) {
476476
}
477477
}
478478

479-
fn handle_native(name: &str) -> &str {
480-
if name != "native" {
481-
return name;
482-
}
483-
484-
unsafe {
485-
let mut len = 0;
479+
#[track_caller]
480+
fn get_host_cpu_name() -> &'static str {
481+
let mut len = 0;
482+
// SAFETY: The underlying C++ global function returns a `StringRef` that
483+
// isn't tied to any particular backing buffer, so it must be 'static.
484+
let slice: &'static [u8] = unsafe {
486485
let ptr = llvm::LLVMRustGetHostCPUName(&mut len);
487-
str::from_utf8(slice::from_raw_parts(ptr as *const u8, len)).unwrap()
486+
assert!(!ptr.is_null());
487+
slice::from_raw_parts(ptr, len)
488+
};
489+
str::from_utf8(slice).expect("host CPU name should be UTF-8")
490+
}
491+
492+
/// If the given string is `"native"`, returns the host CPU name according to
493+
/// LLVM. Otherwise, the string is returned as-is.
494+
fn resolve_native_cpu(cpu_name: &str) -> &str {
495+
match cpu_name {
496+
"native" => get_host_cpu_name(),
497+
_ => cpu_name,
488498
}
489499
}
490500

491501
pub(crate) fn target_cpu(sess: &Session) -> &str {
492-
match sess.opts.cg.target_cpu {
493-
Some(ref name) => handle_native(name),
494-
None => handle_native(sess.target.cpu.as_ref()),
495-
}
502+
let name = sess.opts.cg.target_cpu.as_deref().unwrap_or_else(|| &sess.target.cpu);
503+
resolve_native_cpu(name)
496504
}
497505

498506
/// The list of LLVM features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
@@ -708,5 +716,5 @@ fn backend_feature_name<'a>(sess: &Session, s: &'a str) -> Option<&'a str> {
708716

709717
pub(crate) fn tune_cpu(sess: &Session) -> Option<&str> {
710718
let name = sess.opts.unstable_opts.tune_cpu.as_ref()?;
711-
Some(handle_native(name))
719+
Some(resolve_native_cpu(name))
712720
}

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,9 @@ extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index,
383383
*Desc = Feat.Desc;
384384
}
385385

386-
extern "C" const char *LLVMRustGetHostCPUName(size_t *len) {
386+
extern "C" const char *LLVMRustGetHostCPUName(size_t *OutLen) {
387387
StringRef Name = sys::getHostCPUName();
388-
*len = Name.size();
388+
*OutLen = Name.size();
389389
return Name.data();
390390
}
391391

0 commit comments

Comments
 (0)