Skip to content

transpile: Type mismatch with pointer arithmetic where one of the pointees is size_t #1836

Description

@Rua
#include <stddef.h>

void ptr_offset(void) {
    unsigned long *ulp = NULL;
    size_t *sp = ulp + 1;
}

void ptr_diff(void) {
    unsigned long *ulp = NULL;
    size_t *sp = NULL;
    ptrdiff_t diff = ulp - sp;
}

Result:

pub type ptrdiff_t = isize;
pub type size_t = usize;
pub const NULL: *mut ::core::ffi::c_void = ::core::ptr::null_mut::<
    ::core::ffi::c_void,
>();
#[no_mangle]
pub unsafe extern "C" fn ptr_offset() {
    let mut ulp: *mut ::core::ffi::c_ulong = ::core::ptr::null_mut::<
        ::core::ffi::c_ulong,
    >();
    let mut sp: *mut size_t = ulp.offset(1 as ::core::ffi::c_int as isize);
}
#[no_mangle]
pub unsafe extern "C" fn ptr_diff() {
    let mut ulp: *mut ::core::ffi::c_ulong = ::core::ptr::null_mut::<
        ::core::ffi::c_ulong,
    >();
    let mut sp: *mut size_t = ::core::ptr::null_mut::<size_t>();
    let mut diff: ptrdiff_t = ulp.offset_from(sp) as ptrdiff_t;
}

In the first function, a pointer offset is calculated, which then gets assigned to a variable of a different type, resulting in an error. In the second, pointers of different types are diffed, with the same result. In both cases, the C AST does not include a cast, because from C's point of view size_t and unsigned long are the same type. So c2rust must insert a cast itself in this case.

It's an open question which of the two pointer types should prevail in the ptr_diff case. Clang simply errors out if the two pointers have different types, but of course not here. Should c2rust error out instead?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions