Skip to content

Another UB found using rustlantis #691

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
FractalFir opened this issue May 31, 2025 · 5 comments
Open

Another UB found using rustlantis #691

FractalFir opened this issue May 31, 2025 · 5 comments
Labels
bug Something isn't working

Comments

@FractalFir
Copy link
Contributor

FractalFir commented May 31, 2025

This program has a different result under GCC debug and GCC release.

2 1 //debug
2 -1 // release
fn dump_var(var2: usize, val2: usize, var3: usize) {
    println!("val2:{val2}")
}
#[inline(never)]
fn dump_var2(var2: usize, val2: usize, var3: usize) {
    println!("val2:{val2}")
}
fn fn6(arg: bool, arg2: usize) -> bool {
    dump_var(0, arg2, 0);
    dump_var2(0, !arg as usize, 0);
    true
}
fn main() {
    let mut _1 = false;
    let mut _3 = 2;
    let mut _4 = (&1, 1);
    loop {
        if _4.1 == 0 {
            if _4.1 == 1 {
                _1 = true;
            } else {
                _1 = false;
            }
        } else if fn6(_1, _3) {
            loop {
                _3 = _4.1;
                let mut _6 = 0;
                _6 = 0;
                let tmp2 = _6;
                if tmp2 == 1 {
                    _4.0 = &_4.1
                } else if tmp2 == 0 {
                    return;
                } else {
                    break;
                }
            }
        }
    }
}

It looks like the cast of val as i128 is nonsensical. Since val is a boolean value, one would expect it to be either 1 or 0, and not -1.

@antoyo antoyo added the bug Something isn't working label May 31, 2025
@FractalFir
Copy link
Contributor Author

FractalFir commented Jun 1, 2025

This issue is even weirder than I expected. For example, setting #[unsafe(no_mangle)] on fn6 makes the problem go away.

This does not change the generated GIMPLE in any way, besides just changing the function name.

@antoyo does setting no_mangle change anything else(ie. set some kind of GCC-side attribute that I can't see in the GIMPLE dump)?

@antoyo
Copy link
Contributor

antoyo commented Jun 1, 2025

I do not think cg_gcc does anything in this case.
But the Rust doc mentions this:

Additionally, the item will be publicly exported from the produced library or object file, similar to the used attribute.

which might be the source of the "fix".

@FractalFir
Copy link
Contributor Author

The "visibility" seems to stay the same, tough.

The main problem I have here is replicating the issue in C. If something not present in GIMPLE is needed for the issue to occur, I have no way of turning that GIMPLE into C(tried once, and the issue just was not there).

@antoyo
Copy link
Contributor

antoyo commented Jun 1, 2025

Would the representation dumped by setting CG_GCCJIT_DUMP_TO_FILE=1 help here?

@FractalFir
Copy link
Contributor Author

Oh, there is a difference now.

diff mangle.c no_mangle.c
320,321c320,321
< static bool
< _ZN6fp_bug3fn617h3865bc436d14d647E (bool param0, __uint64_t  __attribute__((aligned(8))) param1, restrict __int64_t  __attribute__((aligned(8))) * param2)
---
> extern bool
> fn6 (bool param0, __uint64_t  __attribute__((aligned(8))) param1, restrict __int64_t  __attribute__((aligned(8))) * param2)
398c398
<   ptrReturnValue3 = (_ZN6fp_bug3fn617h3865bc436d14d647E) (((bool)loadedValue1), ((__uint64_t  __attribute__((aligned(8))))loadedValue2), ((restrict __int64_t  __attribute__((aligned(8))) *)&stack_var_4));
---
>   ptrReturnValue3 = (fn6) (((bool)loadedValue1), ((__uint64_t  __attribute__((aligned(8))))loadedValue2), ((restrict __int64_t  __attribute__((aligned(8))) *)&stack_var_4));

I guess that no_mangle marks the function as extern(not static) and that allows GCC some more optimizations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants