Rust-GCC / Rust-GCC/gccrs

Pointer semantics are the exact same as C

Open
#2,844 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug codegen
Dominant language
C++
Stars
2.9k
Forks
231
Avg merge
19h 55m
Merged PRs (30d)
67

Description

Per a conversation I've had on Zulip: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Rust.20Has.20Provenance.20RFC/near/420422460

Translating "bad but compliant with the C standard" C code into Rust shows that we have the same pointer semantics as the C language, while rustc differs greatly and has less undefined behavior in the example below. This is the proper Rust version, re-add commented out lines for the gccrs compatible one.

// #![feature(intrinsics)]

// #[lang = "sized"]
// pub trait Sized {}

static Y: i32 = 2;
static X: i32 = 1;

extern "C" {
    fn printf(fmt: *const i8, ...);
}

// extern "rust-intrinsic" {
//     fn transmute<T, U>(_: T) -> U;
//     fn size_of<T>() -> usize;
// }

use std::mem::transmute;

fn ptr_to_usize(x: *const i32) -> usize {
    unsafe { transmute::<*const i32, usize>(x) }
}

fn usize_to_ptr(x: usize) -> *const i32 {
    unsafe { transmute::<usize, *const i32>(x) }
}

fn bugzilla_report() {
    let p: *const i32;
    p = usize_to_ptr(ptr_to_usize(&X as *const i32) + 4);

    unsafe {
        printf(
            "&X=%p  &Y=%p  p=%p\n\0" as *const str as *const i8,
            &X as *const i32,
            &Y as *const i32,
            p,
        )
    }

    let b1 = p == &Y as *const i32;

    unsafe {
        printf(
            "(p==&Y) = %d\n\0" as *const str as *const i8,
            if b1 { 1 } else { 0 },
        )
    }
}

fn godbolt_example() {
    let p2 = [42 as u8];
    let p1 = [42 as u8];

    unsafe {
        printf(
            "p1: %p, p2: %p\n\0" as *const str as *const i8,
            transmute::<_, *const char>(&p1),
            transmute::<_, *const char>(&p2),
        )
    }

    let p1_ptr = usize_to_ptr(ptr_to_usize(unsafe { transmute::<_, *const i32>(&p1) }) + 1);
    let p2_ptr = unsafe { transmute::<_, *const i32>(&p2) };

    unsafe {
        if p2_ptr == p1_ptr {
            printf("1st attempt: pointers are equal\n\0" as *const str as *const i8)
        } else {
            printf("1st attempt: pointers are not equal\n\0" as *const str as *const i8)
        }

        if ptr_to_usize(p1_ptr) == ptr_to_usize(p2_ptr) {
            printf("2nd attempt: pointers are equal\n\0" as *const str as *const i8)
        } else {
            printf("2nd attempt: pointers are not equal\n\0" as *const str as *const i8)
        }
    }
}

fn main() {
    bugzilla_report();
    godbolt_example();
}

results:

arthur@platypus ~/G/r/gccrs (master)> rustc -C opt-level=2 ub-rust.rs
arthur@platypus ~/G/r/gccrs (master)> ./ub-rust
&X=0x5555aab59004  &Y=0x5555aab59000  p=0x5555aab59008
(p==&Y) = 0
p1: 0x7fff3d4594fe, p2: 0x7fff3d4594ff
1st attempt: pointers are equal
2nd attempt: pointers are equal
arthur@platypus ~/G/r/gccrs (master)> gccrs ub-rust.rs -O2 -o ub-or-not
arthur@platypus ~/G/r/gccrs (master)> ./ub-or-not
&X=0x404020  &Y=0x404024  p=0x404024
(p==&Y) = 1
p1: 0x7ffc0434ca3e, p2: 0x7ffc0434ca3f
1st attempt: pointers are not equal
2nd attempt: pointers are equal

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the ub-rust.rs reproducer in the issue and run it with rustc and gccrs using the commands shown. Compare pointer values and equality results in bugzilla_report and godbolt_example, then determine the intended pointer semantics and what gccrs behavior should be considered correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.