Skip to content

Commit f9de84e

Browse files
committed
core: Add core::ffi::c_intptr_t and core::ffi::c_uintptr_t
Tracking issue: #88345 Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
1 parent d7f14d3 commit f9de84e

4 files changed

Lines changed: 59 additions & 1 deletion

File tree

library/core/src/ffi/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub use self::primitives::{
3838
c_ulong, c_ulonglong, c_ushort,
3939
};
4040
#[unstable(feature = "c_size_t", issue = "88345")]
41-
pub use self::primitives::{c_ptrdiff_t, c_size_t, c_ssize_t};
41+
pub use self::primitives::{c_intptr_t, c_ptrdiff_t, c_size_t, c_ssize_t, c_uintptr_t};
4242

4343
// N.B., for LLVM to recognize the void pointer type and by extension
4444
// functions like malloc(), we need to have it represented as i8* in

library/core/src/ffi/primitives.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,22 @@ pub type c_ptrdiff_t = isize;
174174
#[unstable(feature = "c_size_t", issue = "88345")]
175175
pub type c_ssize_t = isize;
176176

177+
/// Equivalent to C's `intptr_t` type.
178+
///
179+
/// This type have the same size with a pointer. The C standard technically only
180+
/// requires that this type be a signed integer type just capable of holding a
181+
/// pointer.
182+
#[unstable(feature = "c_size_t", issue = "88345")]
183+
pub type c_intptr_t = c_intptr_definition::c_intptr_t;
184+
185+
/// Equivalent to C's `uintptr_t` type.
186+
///
187+
/// This type have the same size with a pointer. The C standard technically only
188+
/// requires that this type be an unsigned integer type just capable of holding
189+
/// a pointer.
190+
#[unstable(feature = "c_size_t", issue = "88345")]
191+
pub type c_uintptr_t = c_intptr_definition::c_uintptr_t;
192+
177193
mod c_int_definition {
178194
crate::cfg_select! {
179195
any(target_arch = "avr", target_arch = "msp430") => {
@@ -187,6 +203,31 @@ mod c_int_definition {
187203
}
188204
}
189205

206+
mod c_intptr_definition {
207+
crate::cfg_select! {
208+
target_pointer_width = "16" => {
209+
pub(super) type c_intptr_t = i16;
210+
pub(super) type c_uintptr_t = u16;
211+
}
212+
target_pointer_width = "32" => {
213+
pub(super) type c_intptr_t = i32;
214+
pub(super) type c_uintptr_t = u32;
215+
}
216+
target_pointer_width = "64" => {
217+
pub(super) type c_intptr_t = i64;
218+
pub(super) type c_uintptr_t = u64;
219+
}
220+
_ => {
221+
/// 128-bit width pointer.
222+
///
223+
/// The C standard only requires that these types be large enough to hold a pointer,
224+
/// so we'll use the i128/u128 integer types in Rust.
225+
pub(super) type c_intptr_t = i128;
226+
pub(super) type c_uintptr_t = u128;
227+
}
228+
}
229+
}
230+
190231
mod c_double_definition {
191232
crate::cfg_select! {
192233
target_arch = "avr" => {

library/coretests/tests/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
mod cstr;
2+
mod intptr;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(strict_provenance_lints)]
2+
#![deny(fuzzy_provenance_casts)]
3+
#![deny(lossy_provenance_casts)]
4+
5+
use crate::ffi::{c_intptr_t, c_uintptr_t};
6+
7+
#[test]
8+
fn test_intptr_unitptr() {
9+
10+
// These types should have the same size as a pointer.
11+
assert_eq!(core::mem::size_of::<c_intptr_t>(), core::mem::size_of::<*const ()>());
12+
assert_eq!(core::mem::size_of::<c_uintptr_t>(), core::mem::size_of::<*const ()>());
13+
let ptr = 1_u8 as c_intptr_t as *const ();
14+
let ptr_unsigned = ptr as *const ();
15+
assert_eq!(ptr_unsigned, 1_u8 as c_uintptr_t);
16+
}

0 commit comments

Comments
 (0)