Skip to content

Commit

Permalink
Use a dedicated safe wrapper for LLVMRustGetHostCPUName
Browse files Browse the repository at this point in the history
  • Loading branch information
Zalathar committed Nov 2, 2024
1 parent 36040aa commit 0fa86f9
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 15 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2204,7 +2204,7 @@ unsafe extern "C" {
Desc: &mut *const c_char,
);

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

// This function makes copies of pointed to data, so the data's lifetime may end after this
// function returns.
Expand Down
32 changes: 20 additions & 12 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,23 +476,31 @@ pub(crate) fn print(req: &PrintRequest, mut out: &mut String, sess: &Session) {
}
}

fn handle_native(name: &str) -> &str {
if name != "native" {
return name;
}

unsafe {
let mut len = 0;
/// Returns the host CPU name, according to LLVM.
fn get_host_cpu_name() -> &'static str {
let mut len = 0;
// SAFETY: The underlying C++ global function returns a `StringRef` that
// isn't tied to any particular backing buffer, so it must be 'static.
let slice: &'static [u8] = unsafe {
let ptr = llvm::LLVMRustGetHostCPUName(&mut len);
str::from_utf8(slice::from_raw_parts(ptr as *const u8, len)).unwrap()
assert!(!ptr.is_null());
slice::from_raw_parts(ptr, len)
};
str::from_utf8(slice).expect("host CPU name should be UTF-8")
}

/// If the given string is `"native"`, returns the host CPU name according to
/// LLVM. Otherwise, the string is returned as-is.
fn handle_native(cpu_name: &str) -> &str {
match cpu_name {
"native" => get_host_cpu_name(),
_ => cpu_name,
}
}

pub(crate) fn target_cpu(sess: &Session) -> &str {
match sess.opts.cg.target_cpu {
Some(ref name) => handle_native(name),
None => handle_native(sess.target.cpu.as_ref()),
}
let cpu_name = sess.opts.cg.target_cpu.as_deref().unwrap_or_else(|| &sess.target.cpu);
handle_native(cpu_name)
}

/// The list of LLVM features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,9 @@ extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index,
*Desc = Feat.Desc;
}

extern "C" const char *LLVMRustGetHostCPUName(size_t *len) {
extern "C" const char *LLVMRustGetHostCPUName(size_t *OutLen) {
StringRef Name = sys::getHostCPUName();
*len = Name.size();
*OutLen = Name.size();
return Name.data();
}

Expand Down

0 comments on commit 0fa86f9

Please sign in to comment.