Fixture 168

rust enum niche

Rust · 9 functions · 2 lanes · 10 of 18 function-lanes behave identically

2 of 2 lanes have a function that returns a different result after decompilation: rustc-O0 (4/9), rustc-O2 (6/9).

tests/decompiler_fixtures/src/168_rust_enum_niche.rs source
// 168_rust_enum_niche.rs
//
// Rust enum layout, including the niche optimizations that make a Rust enum
// unrecognisable as a tagged union.
//
// Three distinct layouts appear here:
//
//   * `Shape` — a data-carrying enum with variants of different sizes. Laid out
//     as an explicit discriminant plus a union-like payload area; the payload
//     offset is chosen by the compiler and is NOT stable across variants, so
//     reading `Pair.0` and `Tagged.id` may or may not be the same load.
//
//   * `Option<&i32>` — the NULL POINTER OPTIMIZATION. `size_of::<Option<&i32>>()
//     == size_of::<&i32>() == 8`. There is no discriminant at all: `None` IS the
//     null pointer. A `match` on it decompiles to a null test, which looks
//     exactly like a C null check and gives no hint that an enum existed.
//
//   * `Option<NonZeroU32>` — the same trick at 4 bytes, folded into a payload
//     that is documented never to be zero. `None` IS `0u32`.
//
//   * `Option<Option<NonZeroU32>>` — the niche is EXHAUSTED. `Option<NonZeroU32>`
//     already spends the only forbidden value (0) on its own `None`, so every
//     u32 bit pattern is now valid and the outer `Option` has to grow a real tag:
//     8 bytes, not 4. Verified at runtime by `rust_niche_sizes`. The lesson for a
//     decompiler is that niche folding is NOT compositional — the same source
//     shape one level deeper has a completely different layout.
//
// Exposure: every driver is `#[no_mangle] pub extern "C" fn` over plain i32/u32
// scalars and caller-owned `*const i32` / `*mut i32` buffers. Discriminant
// selectors are taken modulo the variant count, indices are masked to <= 15,
// pointers are null-checked (and the null case is a legitimate `None`), and all
// arithmetic is `wrapping_*`. No input the harness can pass can panic.
//
// Deterministic: `rust_niche_sizes` returns compile-time constants; nothing else
// observes an address.

use core::num::NonZeroU32;

/// A data-carrying enum: differing payload sizes force a real discriminant.
enum Shape {
    Unit,
    Pair(i32, i32),
    Tagged { id: i32, v: i32 },
    Wide(i64),
    Byte(i8),
}

/// Total over all inputs: `kind` is reduced modulo the variant count.
#[inline(never)]
fn make(kind: u32, a: i32, b: i32) -> Shape {
    match kind % 5 {
        0 => Shape::Unit,
        1 => Shape::Pair(a, b),
        2 => Shape::Tagged { id: a, v: b },
        3 => Shape::Wide((a as i64).wrapping_mul(0x1_0000_0001).wrapping_add(b as i64)),
        _ => Shape::Byte(a as i8),
    }
}

/// The discriminant read plus five payload decodings. Each arm produces a value
/// in its own decade, so a mis-recovered discriminant lands in the wrong decade
/// and the differential catches it.
#[inline(never)]
fn eval(s: &Shape) -> i32 {
    match s {
        Shape::Unit => 1,
        Shape::Pair(x, y) => 100i32.wrapping_add(x.wrapping_mul(3)).wrapping_add(*y),
        Shape::Tagged { id, v } => 200i32.wrapping_add(id.wrapping_sub(*v)),
        Shape::Wide(w) => 300i32.wrapping_add((*w as i32) ^ ((*w >> 32) as i32)),
        Shape::Byte(b) => 400i32.wrapping_add(*b as i32),
    }
}

#[no_mangle]
pub extern "C" fn rust_enum_eval(kind: u32, a: i32, b: i32) -> i32 {
    eval(&make(kind, a, b))
}

/// The enum crosses a function boundary BY VALUE, so its ABI layout (how many
/// registers, which halves carry the discriminant) is exercised rather than just
/// its in-memory form.
#[inline(never)]
fn combine(x: Shape, y: Shape) -> i32 {
    eval(&x).wrapping_mul(31).wrapping_add(eval(&y))
}

#[no_mangle]
pub extern "C" fn rust_enum_by_value(k1: u32, k2: u32, a: i32, b: i32) -> i32 {
    combine(make(k1, a, b), make(k2, b, a))
}

/// Only the discriminant, with no payload use: the compiler is free to emit a
/// bare tag load and a jump table.
#[no_mangle]
pub extern "C" fn rust_enum_discriminant(kind: u32, a: i32, b: i32) -> i32 {
    match make(kind, a, b) {
        Shape::Unit => 0,
        Shape::Pair(..) => 1,
        Shape::Tagged { .. } => 2,
        Shape::Wide(_) => 3,
        Shape::Byte(_) => 4,
    }
}

// --- niche optimization: Option<&T> is a nullable pointer ------------------

/// `Option<&i32>` built from a raw pointer. `as_ref()` performs the null test;
/// the resulting `Option` has NO tag — the pointer value IS the tag.
///
/// `p` may legitimately be null (the harness never passes null, but the code is
/// total either way); `idx` is masked to the 16-element buffer.
#[no_mangle]
pub extern "C" fn rust_option_ref(p: *const i32, idx: u32) -> i32 {
    let off = (idx & 15) as usize;
    // SAFETY: when non-null the caller owns at least 16 i32s at `p`, and
    // `off <= 15`. `as_ref` itself performs the null check.
    let opt: Option<&i32> = unsafe { p.add(off).as_ref() };
    match opt {
        Some(v) => v.wrapping_add(1000),
        None => -1,
    }
}

/// The same niche used as a RETURN value: the function returns one pointer-sized
/// register that is either a valid address or zero.
#[inline(never)]
fn first_positive(buf: &[i32]) -> Option<&i32> {
    for v in buf {
        if *v > 0 {
            return Some(v);
        }
    }
    None
}

#[no_mangle]
pub extern "C" fn rust_option_ref_find(p: *const i32, n: u32) -> i32 {
    if p.is_null() {
        return -2;
    }
    let len = if n > 16 { 16 } else { n } as usize;
    // SAFETY: caller owns >= 16 i32s at `p`; `len <= 16`.
    let buf: &[i32] = unsafe { core::slice::from_raw_parts(p, len) };
    match first_positive(buf) {
        Some(v) => *v,
        None => -1,
    }
}

// --- niche optimization: Option<NonZeroU32> is a u32 with 0 == None ---------

/// `NonZeroU32::new` is the niche construction: it is a compare against zero,
/// and the `Option` it returns is bit-identical to its argument.
#[no_mangle]
pub extern "C" fn rust_option_nonzero(v: u32) -> u32 {
    match NonZeroU32::new(v) {
        Some(nz) => nz.get().wrapping_mul(3) ^ 0x5a,
        None => 0xFFFF_FFFF,
    }
}

/// Nested `Option`s where the niche has run out: the outer layer carries an
/// explicit discriminant word beside the u32 payload (8 bytes total), so three
/// distinct results — outer `None`, inner `None`, and a payload — come from two
/// different mechanisms in one match.
#[no_mangle]
pub extern "C" fn rust_option_nested(v: u32, sel: u32) -> u32 {
    let inner: Option<NonZeroU32> = NonZeroU32::new(v);
    let outer: Option<Option<NonZeroU32>> = if sel & 1 == 0 { None } else { Some(inner) };
    match outer {
        None => 7,
        Some(None) => 8,
        Some(Some(nz)) => nz.get().wrapping_add(9),
    }
}

/// The niche flowing through a caller-owned buffer: each element is interpreted
/// as an `Option<NonZeroU32>` and rewritten, so both the `None` encoding and the
/// payload encoding are visible as memory.
#[no_mangle]
pub extern "C" fn rust_option_niche_fill(out: *mut i32, n: u32) -> i32 {
    if out.is_null() {
        return -1;
    }
    let len = if n > 16 { 16 } else { n } as usize;
    // SAFETY: caller owns >= 16 i32s at `out`; `len <= 16`.
    let dst: &mut [i32] = unsafe { core::slice::from_raw_parts_mut(out, len) };
    let mut count: i32 = 0;
    for slot in dst.iter_mut() {
        let o = NonZeroU32::new(*slot as u32);
        *slot = match o {
            Some(nz) => {
                count = count.wrapping_add(1);
                nz.get().wrapping_add(1) as i32
            }
            None => -5,
        };
    }
    count
}

/// The layout facts themselves, as compile-time constants: (Option<&i32>,
/// Option<NonZeroU32>, Option<u32>, Option<Option<NonZeroU32>>) sizes packed
/// into one i32. Observed value on x86-64: 8_04_08_08, i.e. 8 / 4 / 8 / 8 —
/// `Option<u32>` and `Option<Option<NonZeroU32>>` have no niche left and pay for
/// a tag, which is the contrast that proves the other two are niche-optimized.
#[no_mangle]
pub extern "C" fn rust_niche_sizes() -> i32 {
    let a = core::mem::size_of::<Option<&i32>>() as i32; // 8 (NPO)
    let b = core::mem::size_of::<Option<NonZeroU32>>() as i32; // 4 (niche)
    let c = core::mem::size_of::<Option<u32>>() as i32; // 8 (no niche)
    let d = core::mem::size_of::<Option<Option<NonZeroU32>>>() as i32; // 8 (niche exhausted)
    a.wrapping_mul(1_000_000)
        .wrapping_add(b.wrapping_mul(10_000))
        .wrapping_add(c.wrapping_mul(100))
        .wrapping_add(d)
}

Recovered C

Generated by glaurung decompile --style decbench at b47f6b43. baseline.json records the result after recompiling the C and calling it beside the original with seeded inputs.

rustc -O0

4/9
rust_enum_by_value fail 14 lines
// glaurung: rust_enum_by_value @ 0x18a0
__attribute__((no_stack_protector)) unsigned int rust_enum_by_value(int arg0, unsigned int arg1, unsigned int arg2, unsigned int arg3) {
    extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(long *, int, unsigned int);
    extern unsigned int _ZN20_168_rust_enum_niche7combine17h31620037001fc60eE(char *, long);
    unsigned char local_30[32];
    unsigned int ret;
    long var2;
    long var5;
    arg1 = arg1;
    var2 = ((long (*)(long *))_ZN20_168_rust_enum_niche4make17h9a025a139a4752daE)((long *)(&local_30[0]));
    var5 = _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE((long *)((&local_30[0] + 16)), arg1, arg3);
    ret = _ZN20_168_rust_enum_niche7combine17h31620037001fc60eE((char *)(&local_30[0]), (long)((&local_30[0] + 16)));
    return ret;
}
rust_enum_discriminant fail 10 lines
// glaurung: rust_enum_discriminant @ 0x1900
__attribute__((no_stack_protector)) unsigned int rust_enum_discriminant(int arg0, unsigned int arg1, unsigned int arg2) {
    extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(long *, int, unsigned int);
    unsigned char local_20[20];
    long local_30;
    long var3;
    var3 = ((long (*)(long *))_ZN20_168_rust_enum_niche4make17h9a025a139a4752daE)((long *)(&local_20[0]));
    local_30 = (unsigned int)((unsigned char)(*(char *)(&local_20[0])));
    /* unrecovered indirect jump through ((long)((int)(*(int *)((0x2024 + (local_30 * 4))))) + 0x2024) */
}
rust_enum_eval fail 11 lines
// glaurung: rust_enum_eval @ 0x1830
__attribute__((no_stack_protector)) long rust_enum_eval(int arg0, unsigned int arg1, unsigned int arg2) {
    extern long _ZN20_168_rust_enum_niche4eval17habc7f91386cad0cfE(char *);
    extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(long *, int, unsigned int);
    unsigned char local_20[20];
    long ret;
    long var3;
    var3 = ((long (*)(long *))_ZN20_168_rust_enum_niche4make17h9a025a139a4752daE)((long *)(&local_20[0]));
    ret = _ZN20_168_rust_enum_niche4eval17habc7f91386cad0cfE((char *)(&local_20[0]));
    return ret;
}
rust_niche_sizes pass 36 lines
// glaurung: rust_niche_sizes @ 0x1db0
unsigned int rust_niche_sizes(void) {
    int local_10;
    int local_14;
    int local_18;
    int local_1c;
    int local_20;
    int local_24;
    int local_28;
    int local_2c;
    int local_30;
    int local_34;
    int local_38;
    int local_3c;
    int local_4;
    int local_40;
    int local_8;
    int local_c;
    local_40 = 8;
    local_3c = 4;
    local_38 = 8;
    local_34 = 8;
    local_8 = 8;
    local_4 = 0xf4240;
    local_10 = 4;
    local_c = 0x2710;
    local_20 = 0x7a1200;
    local_1c = 0x9c40;
    local_18 = 8;
    local_14 = 100;
    local_28 = 0x7aae40;
    local_24 = 800;
    local_30 = 0x7ab160;
    local_2c = 8;
    return 0x7ab168;
}
rust_option_nested pass 36 lines
// glaurung: rust_option_nested @ 0x1ba0
unsigned int rust_option_nested(int arg0, unsigned int arg1) {
    extern long _ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE(int);
    extern unsigned int _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E(int);
    int local_10;
    int local_1c;
    int local_20;
    int local_28;
    int local_4;
    int local_8;
    int local_c;
    unsigned int var0;
    long var12;
    var0 = _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E(arg0);
    local_28 = var0;
    local_10 = var0;
    if (((unsigned long)((unsigned int)((arg1 & 1))) != 0)) {
        local_1c = local_28;
        local_20 = 1;
    } else {
        local_20 = 0;
    }
    if (((unsigned long)((unsigned int)(local_20)) != 0)) {
        if (((((unsigned long)((unsigned int)(local_1c)) == 0) ? 0 : 1) == 0)) {
            return 8;
        } else {
            local_c = local_1c;
            var12 = ((long (*)(void))_ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE)();
            local_8 = var12;
            local_4 = 9;
            return (unsigned int)((var12 + 9));
        }
    } else {
        return 7;
    }
}
rust_option_niche_fill fail 80 lines
// glaurung: rust_option_niche_fill @ 0x1c50
__attribute__((no_stack_protector)) unsigned int rust_option_niche_fill(char * arg0, unsigned int arg1) {
    extern long _ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE(int);
    extern unsigned int _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E(int);
    extern int _ZN4core3ptr7mut_ptr31__LT_impl_u20__BP_mut_u20_T_GT_7is_null17h6aa1216baf4d5916E(char *);
    extern long _ZN4core5slice29__LT_impl_u20__u5b_T_u5d__GT_8iter_mut17hd159003656df9d18E(long);
    extern long _ZN4core5slice3raw18from_raw_parts_mut17h12e5279671aabd10E(char *, long);
    extern long _ZN63__LT_I_u20_as_u20_core__iter__traits__collect__IntoIterator_GT_9into_iter17ha82f13d10d68680dE(long);
    extern long _ZN94__LT_core__slice__iter__IterMut_LT_T_GT__u20_as_u20_core__iter__traits__iterator__Iterator_GT_4next17h830345d9a7e0ca4eE(char *);
    int local_10;
    int local_14;
    long local_20;
    long local_28;
    long local_30;
    long local_38;
    int local_4;
    int local_4c;
    int local_50;
    long local_58;
    long local_60;
    unsigned char local_68[8];
    int local_8;
    unsigned char local_88[32];
    int local_c;
    int var0;
    long var10;
    long var11;
    long var14;
    long var19;
    unsigned int var27;
    long var34;
    long var37;
    long var6;
    var0 = _ZN4core3ptr7mut_ptr31__LT_impl_u20__BP_mut_u20_T_GT_7is_null17h6aa1216baf4d5916E(arg0);
    if (((unsigned long)((unsigned char)((var0 & 1))) != 0)) {
        *(int *)((&local_88[0] + 20)) = -1;
    } else {
        if (((unsigned long)(16) < (unsigned long)(arg1))) {
            *(int *)((&local_88[0] + 24)) = 16;
        } else {
            *(int *)((&local_88[0] + 24)) = arg1;
        }
        local_38 = (unsigned int)(*(int *)((&local_88[0] + 24)));
        var6 = ((long (*)(char *))_ZN4core5slice3raw18from_raw_parts_mut17h12e5279671aabd10E)(arg0);
        local_30 = var6;
        local_28 = var10;
        *(int *)((&local_88[0] + 28)) = 0;
        var11 = ((long (*)(void))_ZN4core5slice29__LT_impl_u20__u5b_T_u5d__GT_8iter_mut17hd159003656df9d18E)();
        var14 = _ZN63__LT_I_u20_as_u20_core__iter__traits__collect__IntoIterator_GT_9into_iter17ha82f13d10d68680dE(var11);
        *(long *)(&local_68[0]) = var14;
        local_60 = var10;
        while (1) {
            var19 = _ZN94__LT_core__slice__iter__IterMut_LT_T_GT__u20_as_u20_core__iter__traits__iterator__Iterator_GT_4next17h830345d9a7e0ca4eE((char *)(&local_68[0]));
            local_58 = var19;
            if ((((local_58 == 0) ? 0 : 1) == 0)) {
                break;
            }
            *(long *)(&local_88[0]) = local_58;
            local_20 = local_58;
            var27 = _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E((unsigned long)((unsigned int)(*(int *)(local_58))));
            local_50 = var27;
            if (((((unsigned long)((unsigned int)(local_50)) == 0) ? 0 : 1) == 0)) {
                local_4c = -5;
            } else {
                local_14 = local_50;
                var34 = (unsigned long)((unsigned int)(*(int *)((&local_88[0] + 28))));
                local_10 = var34;
                local_c = 1;
                *(int *)((&local_88[0] + 28)) = (var34 + 1);
                var37 = ((long (*)(void))_ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE)();
                local_8 = var37;
                local_4 = 1;
                local_4c = (var37 + 1);
            }
            *(int *)(*(long *)(&local_88[0])) = local_4c;
        }
        *(int *)((&local_88[0] + 20)) = *(int *)((&local_88[0] + 28));
    }
    return (unsigned int)(*(int *)((&local_88[0] + 20)));
}
rust_option_nonzero pass 21 lines
// glaurung: rust_option_nonzero @ 0x1b40
__attribute__((no_stack_protector)) unsigned int rust_option_nonzero(int arg0) {
    extern long _ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE(int);
    extern unsigned int _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E(int);
    unsigned char local_18[24];
    unsigned int var0;
    long var7;
    *(int *)((&local_18[0] + 8)) = arg0;
    var0 = _ZN4core3num7nonzero10NonZeroU323new17h3c4ed299db95b8a4E(arg0);
    *(int *)((&local_18[0] + 4)) = var0;
    if (((((unsigned long)((unsigned int)(*(int *)((&local_18[0] + 4)))) == 0) ? 0 : 1) != 0)) {
        *(int *)((&local_18[0] + 12)) = *(int *)((&local_18[0] + 4));
        var7 = ((long (*)(void))_ZN4core3num7nonzero10NonZeroU323get17hbd59da5b5a8e9c9dE)();
        *(int *)((&local_18[0] + 16)) = var7;
        *(int *)((&local_18[0] + 20)) = 3;
        *(int *)(&local_18[0]) = ((var7 * 3) ^ 90);
    } else {
        *(int *)(&local_18[0]) = -1;
    }
    return (unsigned int)(*(int *)(&local_18[0]));
}
rust_option_ref pass 27 lines
// glaurung: rust_option_ref @ 0x1980
unsigned int rust_option_ref(char * arg0, unsigned int arg1) {
    extern long _ZN4core3ptr9const_ptr33__LT_impl_u20__BP_const_u20_T_GT_6as_ref17h7fa8fe4eb09ecef0E(char *);
    int local_14;
    int local_18;
    long local_20;
    long local_28;
    long local_40;
    long local_8;
    long var12;
    long var2;
    long var4;
    var2 = (unsigned long)((unsigned int)((arg1 & 15)));
    local_28 = var2;
    local_8 = var2;
    var4 = _ZN4core3ptr9const_ptr33__LT_impl_u20__BP_const_u20_T_GT_6as_ref17h7fa8fe4eb09ecef0E((char *)(((long)arg0 + (var2 << 2))));
    local_40 = var4;
    if ((((local_40 == 0) ? 0 : 1) != 0)) {
        local_20 = local_40;
        var12 = (unsigned long)((unsigned int)(*(int *)(local_40)));
        local_18 = var12;
        local_14 = 1000;
        return (unsigned int)((var12 + 1000));
    } else {
        return (unsigned int)(-1);
    }
}
rust_option_ref_find fail 34 lines
// glaurung: rust_option_ref_find @ 0x1a80
unsigned int rust_option_ref_find(char * arg0, unsigned int arg1) {
    extern long _ZN20_168_rust_enum_niche14first_positive17h11d53ca900de4405E(long);
    extern int _ZN4core3ptr9const_ptr33__LT_impl_u20__BP_const_u20_T_GT_7is_null17ha91e1c541d7185f3E(char *);
    extern long _ZN4core5slice3raw14from_raw_parts17hcb69f8e0bbc46596E(char *, long);
    long local_10;
    long local_18;
    long local_20;
    long local_38;
    int local_3c;
    long local_8;
    int var0;
    long var10;
    long var11;
    long var6;
    var0 = _ZN4core3ptr9const_ptr33__LT_impl_u20__BP_const_u20_T_GT_7is_null17ha91e1c541d7185f3E(arg0);
    if (((unsigned long)((unsigned char)((var0 & 1))) != 0)) {
        return (unsigned int)(-2);
    } else {
        local_3c = (((unsigned long)(16) < (unsigned long)(arg1)) ? 16 : (unsigned long)(arg1));
        local_20 = (unsigned int)(local_3c);
        var6 = ((long (*)(char *))_ZN4core5slice3raw14from_raw_parts17hcb69f8e0bbc46596E)(arg0);
        local_18 = var6;
        local_10 = var10;
        var11 = ((long (*)(void))_ZN20_168_rust_enum_niche14first_positive17h11d53ca900de4405E)();
        local_38 = var11;
        if ((((local_38 == 0) ? 0 : 1) != 0)) {
            local_8 = local_38;
            return (unsigned int)(*(int *)(local_38));
        } else {
            return (unsigned int)(-1);
        }
    }
}

rustc -O2

6/9
rust_enum_by_value fail 18 lines
// glaurung: rust_enum_by_value @ 0x1230
__attribute__((no_stack_protector)) unsigned int rust_enum_by_value(int arg0, unsigned int arg1, long arg2, unsigned int arg3) {
    extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(void *, unsigned int, long);
    extern unsigned int _ZN20_168_rust_enum_niche7combine17h31620037001fc60eE(char *, char *);
    unsigned char local_48[32];
    unsigned int ret;
    long var0;
    long var2;
    long var4;
    long var8;
    var0 = (unsigned long)(arg3);
    var2 = (unsigned long)(arg1);
    var4 = ((long (*)(void *, unsigned int))_ZN20_168_rust_enum_niche4make17h9a025a139a4752daE)(&local_48[0], (unsigned long)((unsigned int)(arg0)));
    var8 = _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE((void *)((&local_48[0] + 16)), (unsigned long)((unsigned int)(var2)), (unsigned long)((unsigned int)(var0)));
    ret = _ZN20_168_rust_enum_niche7combine17h31620037001fc60eE((char *)(&local_48[0]), (char *)((&local_48[0] + 16)));
    // x86-64 epilogue: tear down frame
    return ret;
}
rust_enum_discriminant pass 8 lines
// glaurung: rust_enum_discriminant @ 0x1280
__attribute__((no_stack_protector)) unsigned int rust_enum_discriminant(int arg0, unsigned int arg1, unsigned int arg2) {
    extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(void *, unsigned int, long);
    unsigned char local_10[16];
    long var1;
    var1 = _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(&local_10[0], (unsigned long)((unsigned int)(arg0)), arg1);
    return (unsigned int)((unsigned char)(*(char *)(&local_10[0])));
}
rust_enum_eval fail 12 lines
// glaurung: rust_enum_eval @ 0x11d0
__attribute__((no_stack_protector)) long rust_enum_eval(int arg0, unsigned int arg1, unsigned int arg2) {
    extern long _ZN20_168_rust_enum_niche4eval17habc7f91386cad0cfE(char *);
    extern long _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(void *, unsigned int, long);
    unsigned char local_18[16];
    long ret;
    long var2;
    var2 = _ZN20_168_rust_enum_niche4make17h9a025a139a4752daE(&local_18[0], (unsigned long)((unsigned int)(arg0)), arg1);
    ret = _ZN20_168_rust_enum_niche4eval17habc7f91386cad0cfE((char *)(&local_18[0]));
    // x86-64 epilogue: tear down frame
    return ret;
}
rust_niche_sizes pass 4 lines
// glaurung: rust_niche_sizes @ 0x14a0
int rust_niche_sizes(void) {
    return 0x7ab168;
}
rust_option_nested pass 4 lines
// glaurung: rust_option_nested @ 0x1340
unsigned int rust_option_nested(long arg0, long arg1) {
    return (((unsigned long)((unsigned char)((arg1 & 1))) != 0) ? (((unsigned long)((unsigned int)(arg0)) != 0) ? (unsigned long)((unsigned int)((arg0 + 9))) : 8) : 7);
}
rust_option_niche_fill pass 145 lines
// glaurung: rust_option_niche_fill @ 0x1360
int rust_option_niche_fill(char * arg0, long arg1) {
    long ret;
    long var1;
    long var10;
    long var12;
    long var13;
    int var14;
    long var140;
    long var141;
    long var142;
    long var145;
    int var15;
    long var150;
    int var152;
    int var16;
    int var17;
    long var19;
    int var20;
    int var21;
    int var22;
    int var23;
    int var24;
    int var25;
    int var26;
    int var27;
    int var29;
    int var30;
    int var31;
    int var32;
    int var34;
    int var35;
    int var36;
    int var37;
    int var38;
    int var39;
    long var4;
    int var40;
    int var41;
    int var43;
    int var44;
    int var45;
    int var46;
    int var66;
    int var67;
    int var68;
    int var69;
    int var71;
    int var72;
    int var73;
    int var74;
    long var8;
    long var9;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    var1 = (((unsigned long)((unsigned long)((unsigned int)(arg1))) < (unsigned long)(16)) ? arg1 : 16);
    if (((unsigned long)((unsigned int)(var1)) == 0)) {
        return 0;
    }
    var4 = (0x3fffffffffffffff & (var1 - 1));
    var8 = 0;
    var9 = (long)arg0;
    if (((unsigned long)(7) <= (unsigned long)(var4))) {
        var10 = (var4 + 1);
        var12 = (var10 & -8);
        var13 = (long)(((long)arg0 + (var12 * 4)));
        ret = 0;
        var14 = 0;
        var15 = 0;
        var16 = 0;
        var17 = 0;
        var19 = 0;
        var20 = -1;
        var21 = -1;
        var22 = -1;
        var23 = -1;
        var24 = 0xfffffffb;
        var25 = 0xfffffffb;
        var26 = 0xfffffffb;
        var27 = 0xfffffffb;
        var29 = 0;
        var30 = 0;
        var31 = 0;
        var32 = 0;
        var34 = 0;
        var35 = 0;
        var36 = 0;
        var37 = 0;
        do {
            var38 = *(int *)(((long)arg0 + var19 * 4));
            var39 = *(int *)(((long)arg0 + var19 * 4 + 0x4));
            var40 = *(int *)(((long)arg0 + var19 * 4 + 0x8));
            var41 = *(int *)(((long)arg0 + var19 * 4 + 0xc));
            var43 = *(int *)(((long)arg0 + var19 * 4 + 0x10));
            var44 = *(int *)(((long)arg0 + var19 * 4 + 0x14));
            var45 = *(int *)(((long)arg0 + var19 * 4 + 0x18));
            var46 = *(int *)(((long)arg0 + var19 * 4 + 0x1c));
            var66 = (-(var38 == var14));
            var67 = (-(var39 == var15));
            var68 = (-(var40 == var16));
            var69 = (-(var41 == var17));
            var71 = (-(var43 == var14));
            var72 = (-(var44 == var15));
            var73 = (-(var45 == var16));
            var74 = (-(var46 == var17));
            var29 = ((var29 + var66) - var20);
            var30 = ((var30 + var67) - var21);
            var31 = ((var31 + var68) - var22);
            var32 = ((var32 + var69) - var23);
            var34 = ((var34 + var71) - var20);
            var35 = ((var35 + var72) - var21);
            var36 = ((var36 + var73) - var22);
            var37 = ((var37 + var74) - var23);
            *(int *)(((long)arg0 + var19 * 4)) = ((var66 & var24) | ((~var66) & (var38 - var20)));
            *(int *)(((long)arg0 + var19 * 4 + 0x4)) = ((var67 & var25) | ((~var67) & (var39 - var21)));
            *(int *)(((long)arg0 + var19 * 4 + 0x8)) = ((var68 & var26) | ((~var68) & (var40 - var22)));
            *(int *)(((long)arg0 + var19 * 4 + 0xc)) = ((var69 & var27) | ((~var69) & (var41 - var23)));
            *(int *)(((long)arg0 + var19 * 4 + 0x10)) = ((var71 & var24) | ((~var71) & (var43 - var20)));
            *(int *)(((long)arg0 + var19 * 4 + 0x14)) = ((var72 & var25) | ((~var72) & (var44 - var21)));
            *(int *)(((long)arg0 + var19 * 4 + 0x18)) = ((var73 & var26) | ((~var73) & (var45 - var22)));
            *(int *)(((long)arg0 + var19 * 4 + 0x1c)) = ((var74 & var27) | ((~var74) & (var46 - var23)));
            var19 = (var19 + 8);
        } while ((var12 != var19));
        var140 = (unsigned long)((unsigned int)((((var37 + var32) + (var35 + var30)) + ((var36 + var31) + (var34 + var29)))));
        var8 = var140;
        var9 = var13;
        ret = var140;
        if ((var10 == var12)) {
            return ret;
        }
    }
    var141 = (long)(((long)arg0 + (var1 * 4)));
    var142 = 0xfffffffb;
    do {
        var145 = (unsigned long)((unsigned int)(*(int *)((var9))));
        *(int *)((var9)) = (((unsigned long)((unsigned int)(var145)) == 0) ? var142 : (unsigned long)((unsigned int)((var145 + 1))));
        var150 = (var9 + 4);
        var152 = (var8 + ((unsigned long)((unsigned int)(var145)) != 0));
        var8 = (unsigned long)((unsigned int)(var152));
        var9 = var150;
        ret = (unsigned long)((unsigned int)(var152));
    } while ((var150 != var141));
    return ret;
}
rust_option_nonzero pass 4 lines
// glaurung: rust_option_nonzero @ 0x1330
unsigned int rust_option_nonzero(long arg0) {
    return (unsigned int)(((unsigned int)((0 - ((unsigned long)((unsigned long)((unsigned int)(arg0))) < (unsigned long)(1)))) | (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + (arg0 * 2)))) ^ 90)))));
}
rust_option_ref pass 7 lines
// glaurung: rust_option_ref @ 0x12a0
int rust_option_ref(char * arg0, unsigned int arg1) {
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    return (unsigned int)((1000 + *(int *)(((long)arg0 + ((unsigned long)((unsigned int)((arg1 & 15))) * 4)))));
}
rust_option_ref_find fail 16 lines
// glaurung: rust_option_ref_find @ 0x12f0
int rust_option_ref_find(int * arg0, int arg1) {
    extern unsigned int _ZN20_168_rust_enum_niche14first_positive17h11d53ca900de4405E(int *);
    long local_8;
    long ret;
    unsigned int var3;
    if ((arg0 == 0)) {
        return 0xfffffffe;
    }
    local_8 = ret;
    var3 = _ZN20_168_rust_enum_niche14first_positive17h11d53ca900de4405E(arg0);
    if ((var3 == 0)) {
        return 0xffffffff;
    }
    return (unsigned int)(*(int *)((var3)));
}

← 213 fixtures