https://gcc.gnu.org/g:3396da354e52f17b8dfd2bf13b06e30b2ac2176b

commit r15-8575-g3396da354e52f17b8dfd2bf13b06e30b2ac2176b
Author: Nobel <nobel2...@gmail.com>
Date:   Mon Dec 23 04:04:44 2024 +0545

    gccrs: add ptr to int and int to ptr type cast rules
    
    Added rules to allow type casting pointer as integer types (u*,i*)
    and integer types to be casted as pointer.
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-casts.cc (TypeCastRules::cast_rules): Add rule.
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/ptr_int_cast.rs: New test.
    
    Signed-off-by: Nobel Singh <nobel2...@gmail.com>

Diff:
---
 gcc/rust/typecheck/rust-casts.cc           | 27 +++++++++++++++++++++++++--
 gcc/testsuite/rust/compile/ptr_int_cast.rs | 18 ++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/typecheck/rust-casts.cc b/gcc/rust/typecheck/rust-casts.cc
index cf4de4b33205..694cbaa5db60 100644
--- a/gcc/rust/typecheck/rust-casts.cc
+++ b/gcc/rust/typecheck/rust-casts.cc
@@ -210,6 +210,16 @@ TypeCastRules::cast_rules ()
          }
          break;
 
+         case TyTy::TypeKind::POINTER: {
+           // char can't be casted as a ptr
+           bool from_char
+             = from.get_ty ()->get_kind () == TyTy::TypeKind::CHAR;
+           if (!from_char)
+             return TypeCoercionRules::CoercionResult{{},
+                                                      to.get_ty ()->clone ()};
+         }
+         break;
+
        case TyTy::TypeKind::INFER:
        case TyTy::TypeKind::USIZE:
        case TyTy::TypeKind::ISIZE:
@@ -254,12 +264,25 @@ TypeCastRules::cast_rules ()
     case TyTy::TypeKind::POINTER:
       switch (to.get_ty ()->get_kind ())
        {
+       case TyTy::TypeKind::USIZE:
+       case TyTy::TypeKind::ISIZE:
+       case TyTy::TypeKind::UINT:
+         case TyTy::TypeKind::INT: {
+           // refs should not cast to numeric type
+           bool from_ptr
+             = from.get_ty ()->get_kind () == TyTy::TypeKind::POINTER;
+           if (from_ptr)
+             {
+               return TypeCoercionRules::CoercionResult{
+                 {}, to.get_ty ()->clone ()};
+             }
+         }
+         break;
+
        case TyTy::TypeKind::REF:
        case TyTy::TypeKind::POINTER:
          return check_ptr_ptr_cast ();
 
-         // FIXME can you cast a pointer to a integral type?
-
        default:
          return TypeCoercionRules::CoercionResult::get_error ();
        }
diff --git a/gcc/testsuite/rust/compile/ptr_int_cast.rs 
b/gcc/testsuite/rust/compile/ptr_int_cast.rs
new file mode 100644
index 000000000000..3a2a5d563d60
--- /dev/null
+++ b/gcc/testsuite/rust/compile/ptr_int_cast.rs
@@ -0,0 +1,18 @@
+fn main(){
+    let foo = 1337;
+    let bar_ptr = &foo as *const i32;
+
+    let bar_ptr_usize = bar_ptr as usize;
+    let bar_ptr_isize = bar_ptr as isize;
+    let bar_ptr_u64 = bar_ptr as u64;
+    let bar_ptr_i64 = bar_ptr as i64;
+    let bar_ptr_i8 = bar_ptr as i8;
+    let bar_ptr_u8 = bar_ptr as u8;
+
+    let _ = bar_ptr_usize as *const i32;
+    let _ = bar_ptr_isize as *const i32;
+    let _ = bar_ptr_u64 as *const i32;
+    let _ = bar_ptr_i64 as *const i32;
+    let _ = bar_ptr_i8 as *const i32;
+    let _ = bar_ptr_u8 as *const i32;
+}

Reply via email to