rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.81k stars 12.66k forks source link

AVR: Miscompilation with Trait Object in Option #74743

Closed Rahix closed 1 year ago

Rahix commented 4 years ago

While playing around with async I stumbled upon an apparent miscomplation. I've tried to reduce it as much as possible and am now left with this:

#![no_std]
#![no_main]
#![feature(llvm_asm)]

#[inline(never)]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
    loop {
        unsafe { llvm_asm!("nop" :::: "volatile") };
    }
}

fn func() -> () {
    unsafe { llvm_asm!("nop" :::: "volatile") };
}

pub struct Func<'a>(pub &'a dyn Fn());

#[no_mangle]
pub extern fn main() -> ! {
    let mut t = Some(Func(&func));

    loop {
        if let Some(t) = t.take() {
            (t.0)();
        }
    }
}

Compiling and running under simavr, I see this code panicking:

#0  core::panicking::panic (expr=...) at /home/rahix/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/panicking.rs:50
#1  0x00000244 in core::ptr::swap_nonoverlapping_one (x=0x800adf, y=0x800ae3) at src/main.rs:25
#2  core::mem::swap (x=0x800adf, y=0x800ae3) at /home/rahix/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/mem/mod.rs:690
#3  core::mem::replace (dest=0x800adf, src=...) at /home/rahix/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/mem/mod.rs:815
#4  core::mem::take (dest=0x800adf) at /home/rahix/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/mem/mod.rs:751
#5  core::option::Option<T>::take (self=0x800adf) at /home/rahix/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/option.rs:892
#6  avr_async::main () at src/main.rs:24

I should also note that while reducing the code, the error manifested itself in many different ways; it was not always panicking like shown above.

Meta

rustc --version --verbose:

rustc 1.47.0-nightly (5ef299eb9 2020-07-24)
binary: rustc
commit-hash: 5ef299eb9805b4c86b227b718b39084e8bf24454
commit-date: 2020-07-24
host: x86_64-unknown-linux-gnu
release: 1.47.0-nightly
LLVM version: 10.0

cc @dylanmckay

Rahix commented 1 year ago

I think it needs to be checked whether this bug is still present in current versions. I have the suspicion that it was fixed as part of some LLVM patches related to function pointers.

workingjubilee commented 1 year ago

We can check, but can you explain the relevance of the llvm_asm! usages? (we can probably replicate the equivalent in current inline assembly, but I'm curious if these are just being used as "black boxes"...)

Rahix commented 1 year ago

Well, essentially just as black boxes/optimization barriers. But as the issue was so unstable in what ways it manifested, I'd keep the nops using asm!().

Patryk27 commented 1 year ago

fwiw, this has been fixed a long time ago - I think this issue can be safely closed 🙂