From dba48c94946c4cdb229afafb68785b6a48b5c069 Mon Sep 17 00:00:00 2001 From: Ramon de C Valle Date: Wed, 23 Aug 2023 16:02:25 -0700 Subject: [PATCH] Fix CFI: f32 and f64 are encoded incorrectly for c Fix #115150 by encoding f32 and f64 correctly for cross-language CFI. I missed changing the encoding for f32 and f64 when I introduced the integer normalization option in #105452 as integer normalization does not include floating point. `f32` and `f64` should be always encoded as `f` and `d` since they are both FFI safe when their representation are the same (i.e., IEEE 754) for both the Rust compiler and Clang. --- .../src/typeid/typeid_itanium_cxx_abi.rs | 17 +++++++++++++---- ...cfi-emit-type-metadata-id-itanium-cxx-abi.rs | 12 ++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index d345368d552b8..77457c8daaa1f 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -447,7 +447,7 @@ fn encode_ty<'tcx>( typeid.push('b'); } - ty::Int(..) | ty::Uint(..) | ty::Float(..) => { + ty::Int(..) | ty::Uint(..) => { // u as vendor extended type let mut s = String::from(match ty.kind() { ty::Int(IntTy::I8) => "u2i8", @@ -462,14 +462,23 @@ fn encode_ty<'tcx>( ty::Uint(UintTy::U64) => "u3u64", ty::Uint(UintTy::U128) => "u4u128", ty::Uint(UintTy::Usize) => "u5usize", - ty::Float(FloatTy::F32) => "u3f32", - ty::Float(FloatTy::F64) => "u3f64", - _ => "", + _ => bug!("encode_ty: unexpected `{:?}`", ty.kind()), }); compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); typeid.push_str(&s); } + // Rust's f32 and f64 single (32-bit) and double (64-bit) precision floating-point types + // have IEEE-754 binary32 and binary64 floating-point layouts, respectively. + // + // (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#fixed-width-floating-point-types.) + ty::Float(float_ty) => { + typeid.push(match float_ty { + FloatTy::F32 => 'f', + FloatTy::F64 => 'd', + }); + } + ty::Char => { // u4char as vendor extended type let mut s = String::from("u4char"); diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs index da608e180c536..2d8b13e2080ef 100644 --- a/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs +++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs @@ -500,12 +500,12 @@ pub fn foo149(_: Type14, _: Type14, _: Type14) { } // CHECK: ![[TYPE45]] = !{i64 0, !"_ZTSFvu5usizeE"} // CHECK: ![[TYPE46]] = !{i64 0, !"_ZTSFvu5usizeS_E"} // CHECK: ![[TYPE47]] = !{i64 0, !"_ZTSFvu5usizeS_S_E"} -// CHECK: ![[TYPE48]] = !{i64 0, !"_ZTSFvu3f32E"} -// CHECK: ![[TYPE49]] = !{i64 0, !"_ZTSFvu3f32S_E"} -// CHECK: ![[TYPE50]] = !{i64 0, !"_ZTSFvu3f32S_S_E"} -// CHECK: ![[TYPE51]] = !{i64 0, !"_ZTSFvu3f64E"} -// CHECK: ![[TYPE52]] = !{i64 0, !"_ZTSFvu3f64S_E"} -// CHECK: ![[TYPE53]] = !{i64 0, !"_ZTSFvu3f64S_S_E"} +// CHECK: ![[TYPE48]] = !{i64 0, !"_ZTSFvfE"} +// CHECK: ![[TYPE49]] = !{i64 0, !"_ZTSFvffE"} +// CHECK: ![[TYPE50]] = !{i64 0, !"_ZTSFvfffE"} +// CHECK: ![[TYPE51]] = !{i64 0, !"_ZTSFvdE"} +// CHECK: ![[TYPE52]] = !{i64 0, !"_ZTSFvddE"} +// CHECK: ![[TYPE53]] = !{i64 0, !"_ZTSFvdddE"} // CHECK: ![[TYPE54]] = !{i64 0, !"_ZTSFvu4charE"} // CHECK: ![[TYPE55]] = !{i64 0, !"_ZTSFvu4charS_E"} // CHECK: ![[TYPE56]] = !{i64 0, !"_ZTSFvu4charS_S_E"}