Skip to content

Miscompilation with enums #121996

Description

@cbeuw

Fuzzer generated custom MIR

#![feature(custom_mir, core_intrinsics)]
extern crate core;
use core::intrinsics::mir::*;

#[custom_mir(dialect = "runtime", phase = "initial")]
fn fn6() {
    mir! {
    let _10: (Adt19,);
    let arr: [u32;8];
    let _23: *mut (Adt19,);
    let _29: i128;
    let _57: (u64, i128, char, isize);
    let _72: isize;
    let _90: Adt19;
    let _91: [char; 2];
    let _92: Adt19;
    let _93: Adt19;
    let _102: ();
    {
    _57 = (0, 0, 'A', 0);
    place!(Field::<(u64, i128, char, isize)>(Variant(_10.0, 3), 1)) = _57;
    _93 = Adt19::Variant3 { fld0: false,fld1: Field::<(u64, i128, char, isize)>(Variant(_10.0, 3), 1),fld2: 0,fld3: 0.,fld4: 0.,fld5: 0,fld6: 0};
    place!(Field::<(u64, i128, char, isize)>(Variant(_93, 3), 1)).2 = 'A';
    _23 = core::ptr::addr_of_mut!(_10);
    _29 = Field::<(u64, i128, char, isize)>(Variant(_93, 3), 1).1;
    _23 = core::ptr::addr_of_mut!(_10);
    place!(Field::<(u64, i128, char, isize)>(Variant(_93, 1), 2)) = (0, 0, 'A', 0);
    place!(Field::<(u64, i128, char, isize)>(Variant(_10.0, 3), 1)) = Field::<(u64, i128, char, isize)>(Variant(_93, 1), 2);
    arr = [0;8];
    _93 = Adt19::Variant2 { fld0: 0,fld1: 0,fld2: 0.,fld3: 0,fld4: arr,fld5: _57 };
    (*_23) = (_93,);
    _92 = _10.0;
    place!(Field::<(u64, i128, char, isize)>(Variant((*_23).0, 2), 5)) = (Field::<(u64, i128, char, isize)>(Variant(_92, 2), 5).0, 0, 'A', 0);
    _72 = Field::<(u64, i128, char, isize)>(Variant(_92, 2), 5).3;
    _90 = Adt19::Variant3 { fld0: false,fld1: Field::<(u64, i128, char, isize)>(Variant(_10.0, 2), 5),fld2: Field::<(u64, i128, char, isize)>(Variant(_10.0, 2), 5).3,fld3: 0.,fld4: 0.,fld5: 0,fld6: 0 };
    _10.0 = Adt19::Variant1 { fld0: 0.,fld1: 0,fld2: Field::<(u64, i128, char, isize)>(Variant(_90, 3), 1),fld3: 0};
    _91 = [Field::<(u64, i128, char, isize)>(Variant((*_23).0, 1), 2).2,'A'];
    Goto(bb53)
    }
    bb53 = {
    Call(_102 = p(_91), ReturnTo(bb56), UnwindUnreachable())
    }
    bb56 = {
    Call(_102 = black_box(Move(_57)), ReturnTo(bb57), UnwindUnreachable())
    }
    bb57 = {
    Return()
    }
    }
}
pub fn main() {
    fn6();
}
#[derive(Debug, Copy, Clone)]
pub enum Adt19 {
    Variant0 {},
    Variant1 {
        fld0: f32,
        fld1: u8,
        fld2: (u64, i128, char, isize),
        fld3: i128,
    },
    Variant2 {
        fld0: u32,
        fld1: u8,
        fld2: f64,
        fld3: u16,
        fld4: [u32; 8],
        fld5: (u64, i128, char, isize),
    },
    Variant3 {
        fld0: bool,
        fld1: (u64, i128, char, isize),
        fld2: isize,
        fld3: f32,
        fld4: f64,
        fld5: usize,
        fld6: i64,
    },
}
fn black_box(x: (u64, i128, char, isize)) {
    core::hint::black_box(x);
}

#[cfg(not(miri))]
fn print_u32(x: u32) {
    extern "C" {
        fn printf(fmt: *const core::ffi::c_char, ...) -> core::ffi::c_int;
    }

    unsafe {
        printf(b"%d\n\0".as_ptr().cast(), x);
    }
}

#[cfg(miri)]
fn print_u32(x: u32) {
    println!("{x}");
}
#[inline(never)]
fn p(x: [char; 2]) {
    print_u32(x[0] as u32)
}

This code has UB under Stacked Borrows, but UB-free under Tree Borrows.

Right:

$ rustc -Zmir-opt-level=0 -Copt-level=0 3440904-debug.rs && ./3440904-debug 
65

Wrong:

$ rustc -Zmir-opt-level=0 -Copt-level=1 3440904-debug.rs && ./3440904-debug 
0

While it looks like an LLVM issue, I couldn't get an IR-only reproduction. It's possible that rustc is producing IR with UBs

On latest nightly

rustc 1.78.0-nightly (516b6162a 2024-03-03)
binary: rustc
commit-hash: 516b6162a2ea8e66678c09e8243ebd83e4b8eeea
commit-date: 2024-03-03
host: x86_64-unknown-linux-gnu
release: 1.78.0-nightly
LLVM version: 18.1.0

cc @RalfJung

Metadata

Metadata

Assignees

Labels

A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlA-codegenArea: Code generationA-rustlantisArea: A miscompilation found by RustlantisC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.llvm-fixed-upstreamIssue expected to be fixed by the next major LLVM upgrade, or backported fixes

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions