aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-08-05 09:33:52 +0000
committerGitHub <noreply@github.com>2022-08-05 09:33:52 +0000
commite77bc10ba13af4e193bbda5f43006d11d9bccb45 (patch)
tree16f963fce89d43f130ac9a104ff23fd60f90db0d /gcc
parentbc65cac0e79c9799fa62635df295e73b14501660 (diff)
parent7022b9dd107e534896d8383f6bc4ce70b4726cc9 (diff)
downloadgcc-e77bc10ba13af4e193bbda5f43006d11d9bccb45.zip
gcc-e77bc10ba13af4e193bbda5f43006d11d9bccb45.tar.gz
gcc-e77bc10ba13af4e193bbda5f43006d11d9bccb45.tar.bz2
Merge #1433
1433: Fix bad transmute for aggregate types r=philberty a=philberty This changes the CONVERT_EXPR to use the same ```*(foo*)&bar``` style cast from the c front-end to handle the case of: ``` int a[1]; int b = (int)a; ``` Which is converted into: ``` int b = *(int*)&a; ``` which the constant folders can turn directly into int b = a[0]; Fixes #1432 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc18
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-1432.rs72
2 files changed, 88 insertions, 2 deletions
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 65eddfa..88d7923 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -545,8 +545,22 @@ transmute_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
tree result_expr = error_mark_node;
if (AGGREGATE_TYPE_P (TREE_TYPE (convert_me_expr)))
{
- result_expr = fold_build1_loc (Location ().gcc_location (), CONVERT_EXPR,
- result_type_tree, convert_me_expr);
+ // Return *(orig_type*)&decl. */
+ // tree t = build_fold_addr_expr_loc (location.gcc_location (), this->t_);
+ // t = fold_build1_loc (location.gcc_location (), NOP_EXPR,
+ // build_pointer_type (this->orig_type_), t);
+ // return build_fold_indirect_ref_loc (location.gcc_location (), t);
+
+ // result_expr = fold_build1_loc (Location ().gcc_location (),
+ // CONVERT_EXPR,
+ // result_type_tree, convert_me_expr);
+
+ tree t = build_fold_addr_expr_loc (Location ().gcc_location (),
+ convert_me_expr);
+ t = fold_build1_loc (Location ().gcc_location (), NOP_EXPR,
+ build_pointer_type (target_type_expr), t);
+ result_expr
+ = build_fold_indirect_ref_loc (Location ().gcc_location (), t);
}
else
{
diff --git a/gcc/testsuite/rust/compile/torture/issue-1432.rs b/gcc/testsuite/rust/compile/torture/issue-1432.rs
new file mode 100644
index 0000000..2a238e1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-1432.rs
@@ -0,0 +1,72 @@
+// { dg-additional-options "-w" }
+mod intrinsics {
+ extern "rust-intrinsic" {
+ pub fn wrapping_add<T>(a: T, b: T) -> T;
+ pub fn rotate_left<T>(a: T, b: T) -> T;
+ pub fn rotate_right<T>(a: T, b: T) -> T;
+ pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+ }
+}
+
+mod mem {
+ extern "rust-intrinsic" {
+ fn transmute<T, U>(_: T) -> U;
+ fn size_of<T>() -> usize;
+ }
+}
+
+macro_rules! impl_uint {
+ ($($ty:ident = $lang:literal),*) => {
+ $(
+ impl $ty {
+ pub fn wrapping_add(self, rhs: Self) -> Self {
+ // intrinsics::wrapping_add(self, rhs)
+ self + rhs
+ }
+
+ pub fn rotate_left(self, n: u32) -> Self {
+ unsafe {
+ intrinsics::rotate_left(self, n as Self)
+ }
+ }
+
+ pub fn rotate_right(self, n: u32) -> Self {
+ unsafe {
+ intrinsics::rotate_right(self, n as Self)
+ }
+ }
+
+ pub fn to_le(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self
+ }
+ }
+
+ pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ Self::from_le(Self::from_ne_bytes(bytes))
+ }
+
+ pub const fn from_le(x: Self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ x
+ }
+ }
+
+ pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ unsafe { mem::transmute(bytes) }
+ }
+ }
+ )*
+ }
+}
+
+impl_uint!(
+ u8 = "u8",
+ u16 = "u16",
+ u32 = "u32",
+ u64 = "u64",
+ u128 = "u128",
+ usize = "usize"
+);