@@ -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
491501pub ( 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
709717pub ( 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}
0 commit comments