Fixture 139

cpp object lifetime

C++ · 3 functions · 4 lanes · 6 of 12 function-lanes behave identically

3 of 4 lanes have a function that returns a different result after decompilation: gcc-O0 (0/3), clang-O0 (1/3), gcc-O2 (2/3).

Destructor ordering is fully specified: reverse of construction, per scope, on every exit path including early returns. Arrays destroy back to front, and a partially constructed array destroys only the elements that finished. Each of those is a generated loop with no source-level counterpart.

tests/decompiler_fixtures/src/139_cpp_object_lifetime.cpp source
/* 139_cpp_object_lifetime.cpp
 *
 * Destructor ordering is fully specified: reverse of construction, per scope,
 * on every exit path including early returns. Arrays destroy back to front, and
 * a partially constructed array destroys only the elements that finished. Each
 * of those is a generated loop with no source-level counterpart.
 */
#include <stdint.h>

namespace {

struct Recorder {
    int32_t *log;
    int32_t *cursor;
    int32_t id;
    Recorder(int32_t *l, int32_t *c, int32_t identifier)
        : log(l), cursor(c), id(identifier) {}
    ~Recorder() {
        if (*cursor < 8) {
            log[*cursor] = id;
            *cursor += 1;
        }
    }
};

struct Counted {
    static int32_t live;
    int32_t id;
    Counted() : id(0) { live += 1; }
    ~Counted() { live -= 1; }
};

int32_t Counted::live = 0;

}  // namespace

extern "C" int32_t cpp_destruction_order(int32_t *log, int32_t which) {
    int32_t cursor = 0;
    if (log == 0) {
        return -1;
    }
    for (int32_t index = 0; index < 8; ++index) {
        log[index] = -1;
    }
    {
        Recorder first(log, &cursor, 1);
        Recorder second(log, &cursor, 2);
        if (which & 1) {
            Recorder conditional(log, &cursor, 3);
            /* Early return still destroys all three, innermost first. */
            return cursor * 1000 + log[0] * 100;
        }
        Recorder third(log, &cursor, 4);
    }
    /* Destroyed 4, 2, 1 in that order. */
    return log[0] * 100 + log[1] * 10 + log[2];
}

extern "C" int32_t cpp_array_destruction(int32_t *log, int32_t count) {
    int32_t cursor = 0;
    if (log == 0 || count < 0 || count > 4) {
        return -1;
    }
    for (int32_t index = 0; index < 8; ++index) {
        log[index] = -1;
    }
    {
        /* Constructed front to back, destroyed back to front. */
        Recorder recorders[3] = {Recorder(log, &cursor, 10),
                                 Recorder(log, &cursor, 20),
                                 Recorder(log, &cursor, 30)};
        (void)recorders;
    }
    return log[0] * 100 + log[1] * 10 + log[2];
}

extern "C" int32_t cpp_live_object_count(int32_t depth) {
    if (depth < 0 || depth > 4) {
        return -1;
    }
    {
        Counted outer;
        (void)outer;
        if (depth > 0) {
            Counted inner;
            (void)inner;
            if (depth > 1) {
                Counted deepest;
                (void)deepest;
                return Counted::live;
            }
            return Counted::live;
        }
        return Counted::live;
    }
}

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.

gcc -O0

0/3
cpp_array_destruction fail 45 lines
// glaurung: cpp_array_destruction @ 0x139c
struct Recorder;
int32_t cpp_array_destruction(int32_t * arg0, int32_t arg1) {
    extern void _ZN12_GLOBAL__N_18RecorderC2EPiS1_i(char *, int *, int *, int);
    extern void _ZN12_GLOBAL__N_18RecorderD2Ev(const struct Recorder *);
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    unsigned char cursor[4];
    int index;
    long local_18;
    unsigned char local_60[72];
    long ret;
    long var10;
    long var14;
    long var21;
    int var25;
    long var8;
    // x86-64 prologue: save rbp, frame 8 bytes
    local_18 = (long)(0x28);
    *(int *)(&cursor[0]) = 0;
    if ((((arg0 == 0) || ((long)(arg1) < 0)) || (((unsigned long)((unsigned int)(arg1)) != 4) && (4 <= (long)(arg1))))) {
        ret = 0xffffffff;
    } else {
        for (index = 0; ((((unsigned long)((unsigned int)(index)) == 7) | ((long)(index) < 7)) != 0); index++) {
            arg0[(long)(index)] = -1;
        }
        var8 = (long)(&local_60[0]);
        _ZN12_GLOBAL__N_18RecorderC2EPiS1_i((char *)(&local_60[0]), (int *)(arg0), (int *)(&cursor[0]), 10);
        var10 = (var8 + 24);
        _ZN12_GLOBAL__N_18RecorderC2EPiS1_i((char *)((&local_60[0] + 24)), (int *)(arg0), (int *)(&cursor[0]), 20);
        _ZN12_GLOBAL__N_18RecorderC2EPiS1_i((char *)((var10 + 24)), (int *)(arg0), (int *)(&cursor[0]), 30);
        var14 = (long)((&local_60[0] + 72));
        while ((var14 != &local_60[0])) {
            var14 = (var14 - 24);
            ((void (*)(char *))_ZN12_GLOBAL__N_18RecorderD2Ev)((char *)(var14));
        }
        var21 = (unsigned long)((unsigned int)(*(int *)((arg0 + 1))));
        var25 = ((unsigned int)(((unsigned long)((unsigned int)(var21)) << 2)) + var21);
        ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(*(int *)((arg0 + 2)))) + (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(*(int *)((long)arg0))) * 100) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var25)) + (unsigned long)((unsigned int)(var25)))))))))));
    }
    if ((local_18 != 0x28)) {
        __stack_chk_fail();
    }
    // x86-64 epilogue: restore rbp
    return ret;
}
cpp_destruction_order fail 72 lines
// glaurung: cpp_destruction_order @ 0x11e4
struct Recorder;
int32_t cpp_destruction_order(int32_t * arg0, int32_t arg1) {
    extern void _ZN12_GLOBAL__N_18RecorderC2EPiS1_i(char *, int *, int *, int);
    extern void _ZN12_GLOBAL__N_18RecorderD2Ev(const struct Recorder *);
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    unsigned char cursor[4];
    int index;
    long local_18;
    unsigned char local_30[24];
    unsigned char local_50[24];
    unsigned char local_70[24];
    long rbp;
    long ret;
    long rsp;
    unsigned char stack_2[24];
    long var0;
    long var1;
    int var17;
    long var18;
    int var27;
    long var34;
    int var38;
    rsp = (rsp - 8);
    *(long *)((&stack_2[0] + 16)) = rbp;
    rbp = rsp;
    rsp = (rsp - 8);
    *(long *)((&stack_2[0] + 8)) = var0;
    rsp = (rsp - 8);
    *(long *)(&stack_2[0]) = var1;
    rsp = (rsp - 128);
    local_18 = (long)(0x28);
    *(int *)(&cursor[0]) = 0;
    if ((arg0 != 0)) {
        for (index = 0; ((((unsigned long)((unsigned int)(index)) == 7) | ((long)(index) < 7)) != 0); index++) {
            arg0[(long)(index)] = -1;
        }
        _ZN12_GLOBAL__N_18RecorderC2EPiS1_i((char *)(&local_70[0]), (int *)(arg0), (int *)(&cursor[0]), 1);
        _ZN12_GLOBAL__N_18RecorderC2EPiS1_i((char *)(&local_50[0]), (int *)(arg0), (int *)(&cursor[0]), 2);
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 1))) == 0)) {
            _ZN12_GLOBAL__N_18RecorderC2EPiS1_i((char *)(&local_30[0]), (int *)(arg0), (int *)(&cursor[0]), 4);
            ((void (*)(char *))_ZN12_GLOBAL__N_18RecorderD2Ev)((char *)(&local_30[0]));
            var17 = 1;
            var18 = var1;
        } else {
            _ZN12_GLOBAL__N_18RecorderC2EPiS1_i((char *)(&local_30[0]), (int *)(arg0), (int *)(&cursor[0]), 3);
            var18 = (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(*(int *)(&cursor[0]))) * 1000) + ((unsigned long)((unsigned int)(*(int *)((long)arg0))) * 100))));
            ((void (*)(char *))_ZN12_GLOBAL__N_18RecorderD2Ev)((char *)(&local_30[0]));
            var17 = 0;
        }
        ((void (*)(char *))_ZN12_GLOBAL__N_18RecorderD2Ev)((char *)(&local_50[0]));
        var27 = (((unsigned long)((unsigned int)(var17)) != 1) ? 0 : 1);
        ((void (*)(char *))_ZN12_GLOBAL__N_18RecorderD2Ev)((char *)(&local_70[0]));
        if (((unsigned long)((unsigned int)(var27)) == 1)) {
            var34 = (unsigned long)((unsigned int)(*(int *)((arg0 + 1))));
            var38 = ((unsigned int)(((unsigned long)((unsigned int)(var34)) << 2)) + var34);
            var18 = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)((((unsigned long)((unsigned int)(*(int *)((long)arg0))) * 100) + (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(var38)) + (unsigned long)((unsigned int)(var38)))))))) + (unsigned long)((unsigned int)(*(int *)((arg0 + 2)))))));
        }
    } else {
        var18 = 0xffffffff;
    }
    ret = (unsigned long)((unsigned int)(var18));
    if ((local_18 != 0x28)) {
        __stack_chk_fail();
    }
    rsp = (rsp + 128);
    rsp = (rsp + 8);
    rsp = (rsp + 8);
    rbp = *(long *)((&stack_2[0] + 16));
    // x86-64 epilogue: tear down frame
    return ret;
}
cpp_live_object_count fail 42 lines
// glaurung: cpp_live_object_count @ 0x14c6
struct Counted;
static unsigned char glaurung_global_402c[16] __attribute__((aligned(16)));
int32_t cpp_live_object_count(int32_t arg0) {
    extern void _ZN12_GLOBAL__N_17CountedC2Ev(const struct Counted *);
    extern void _ZN12_GLOBAL__N_17CountedD2Ev(const struct Counted *);
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    extern unsigned char glaurung_global_402c[16];
    long local_18;
    unsigned char local_1c[4];
    unsigned char local_20[4];
    unsigned char local_24[4];
    long ret;
    long var3;
    // x86-64 prologue: save rbp, frame 8 bytes
    local_18 = (long)(0x28);
    if ((((long)(arg0) < 0) || (((unsigned long)((unsigned int)(arg0)) != 4) && (4 <= (long)(arg0))))) {
        var3 = 0xffffffff;
    } else {
        ((void (*)(char *))_ZN12_GLOBAL__N_17CountedC2Ev)((char *)(&local_24[0]));
        if ((((unsigned long)((unsigned int)(arg0)) == 0) | ((long)(arg0) < 0))) {
            var3 = (unsigned long)((unsigned int)(*(int *)(&glaurung_global_402c[0])));
        } else {
            ((void (*)(char *))_ZN12_GLOBAL__N_17CountedC2Ev)((char *)(&local_20[0]));
            if ((((unsigned long)((unsigned int)(arg0)) == 1) | ((long)(arg0) < 1))) {
                var3 = (unsigned long)((unsigned int)(*(int *)(&glaurung_global_402c[0])));
            } else {
                ((void (*)(char *))_ZN12_GLOBAL__N_17CountedC2Ev)((char *)(&local_1c[0]));
                var3 = (unsigned long)((unsigned int)(*(int *)(&glaurung_global_402c[0])));
                ((void (*)(char *))_ZN12_GLOBAL__N_17CountedD2Ev)((char *)(&local_1c[0]));
            }
            ((void (*)(char *))_ZN12_GLOBAL__N_17CountedD2Ev)((char *)(&local_20[0]));
        }
        ((void (*)(char *))_ZN12_GLOBAL__N_17CountedD2Ev)((char *)(&local_24[0]));
    }
    ret = (unsigned long)((unsigned int)(var3));
    if ((local_18 != 0x28)) {
        __stack_chk_fail();
    }
    // x86-64 epilogue: restore rbp
    return ret;
}

clang -O0

1/3
cpp_array_destruction fail 61 lines
// glaurung: cpp_array_destruction @ 0x1340
struct Recorder;
__attribute__((no_stack_protector)) int32_t cpp_array_destruction(int32_t * arg0, int32_t arg1) {
    extern __attribute__((noreturn)) long _Unwind_Resume(long);
    extern void _ZN12_GLOBAL__N_18RecorderC2EPiS1_i(char *, int *, int *, int);
    extern void _ZN12_GLOBAL__N_18RecorderD2Ev(struct Recorder *);
    unsigned char cursor[16];
    int index;
    unsigned char local_28[12];
    int local_4;
    unsigned char local_70[72];
    long local_78;
    long local_80;
    long local_90;
    long local_98;
    long local_a0;
    void * local_a8;
    long local_b0;
    long var10;
    long var42;
    // x86-64 prologue: save rbp, frame 208 bytes
    *(int *)(&cursor[0]) = 0;
    if ((arg0 == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((long)(arg1) < 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg1)) == 4) | ((long)(arg1) < 4)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    for (index = 0; ((long)(index) < 8); index++) {
        arg0[(long)(index)] = -1;
    }
    local_90 = (long)(&local_70[0]);
    local_78 = (long)(&local_70[0]);
    ((void (*)(void))_ZN12_GLOBAL__N_18RecorderC2EPiS1_i)();
    var10 = (local_90 + 24);
    local_98 = var10;
    local_78 = var10;
    ((void (*)(void))_ZN12_GLOBAL__N_18RecorderC2EPiS1_i)();
    local_78 = (local_98 + 24);
    ((void (*)(void))_ZN12_GLOBAL__N_18RecorderC2EPiS1_i)();
    local_a8 = &local_70[0];
    local_a0 = (long)(&local_28[0]);
    do {
        local_b0 = (local_a0 - 24);
        ((void (*)(void))_ZN12_GLOBAL__N_18RecorderD2Ev)();
        local_a0 = local_b0;
    } while ((local_b0 != local_a8));
    local_4 = ((unsigned int)(((*(int *)((long)arg0) * 100) + (*(int *)(((long)arg0 + 0x4)) * 10))) + *(int *)(((long)arg0 + 0x8)));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
    var42 = _Unwind_Resume(local_80);
}
cpp_destruction_order fail 49 lines
// glaurung: cpp_destruction_order @ 0x1110
struct Recorder;
__attribute__((no_stack_protector)) int32_t cpp_destruction_order(int32_t * arg0, int32_t arg1) {
    extern __attribute__((noreturn)) long _Unwind_Resume(long);
    extern void _ZN12_GLOBAL__N_18RecorderC2EPiS1_i(char *, int *, int *, int);
    extern void _ZN12_GLOBAL__N_18RecorderD2Ev(struct Recorder *);
    unsigned char cursor[16];
    int index;
    unsigned char local_38[24];
    int local_4;
    unsigned char local_50[24];
    long local_58;
    unsigned char local_78[24];
    int local_7c;
    unsigned char local_98[24];
    void * local_a0;
    long var31;
    // x86-64 prologue: save rbp, frame 160 bytes
    *(int *)(&cursor[0]) = 0;
    if ((arg0 != 0)) {
        for (index = 0; ((long)(index) < 8); index++) {
            arg0[(long)(index)] = -1;
        }
        local_a0 = &cursor[0];
        ((void (*)(char *, int *))_ZN12_GLOBAL__N_18RecorderC2EPiS1_i)((char *)(&local_38[0]), (int *)(arg0));
        _ZN12_GLOBAL__N_18RecorderC2EPiS1_i((char *)(&local_50[0]), (int *)(arg0), local_a0, 2);
        if (((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(arg1)) & 1))) == 0)) {
            _ZN12_GLOBAL__N_18RecorderC2EPiS1_i((char *)(&local_98[0]), (int *)(arg0), (int *)(&cursor[0]), 4);
            ((void (*)(char *))_ZN12_GLOBAL__N_18RecorderD2Ev)((char *)(&local_98[0]));
            local_7c = 0;
        } else {
            _ZN12_GLOBAL__N_18RecorderC2EPiS1_i((char *)(&local_78[0]), (int *)(arg0), (int *)(&cursor[0]), 3);
            local_4 = ((*(int *)(&cursor[0]) * 1000) + (*(int *)((long)arg0) * 100));
            local_7c = 1;
            ((void (*)(char *))_ZN12_GLOBAL__N_18RecorderD2Ev)((char *)(&local_78[0]));
        }
        ((void (*)(char *))_ZN12_GLOBAL__N_18RecorderD2Ev)((char *)(&local_50[0]));
        ((void (*)(char *))_ZN12_GLOBAL__N_18RecorderD2Ev)((char *)(&local_38[0]));
        if (((unsigned long)((unsigned int)(local_7c)) == 0)) {
            local_4 = ((unsigned int)(((*(int *)((long)arg0) * 100) + (*(int *)(((long)arg0 + 0x4)) * 10))) + *(int *)(((long)arg0 + 0x8)));
        } else {
        }
    } else {
        local_4 = -1;
    }
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
    var31 = _Unwind_Resume(local_58);
}
cpp_live_object_count pass 48 lines
// glaurung: cpp_live_object_count @ 0x1520
struct Counted;
static unsigned char glaurung_global_4034[16] __attribute__((aligned(16)));
__attribute__((no_stack_protector)) int32_t cpp_live_object_count(int32_t arg0) {
    extern __attribute__((noreturn)) long _Unwind_Resume(long);
    extern void _ZN12_GLOBAL__N_17CountedC2Ev(struct Counted *);
    extern void _ZN12_GLOBAL__N_17CountedD2Ev(struct Counted *);
    extern unsigned char glaurung_global_4034[16];
    unsigned char local_10[4];
    unsigned char local_18[4];
    long local_20;
    unsigned char local_28[4];
    int local_2c;
    int local_4;
    long var9;
    // x86-64 prologue: save rbp, frame 48 bytes
    if (((long)(arg0) < 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    if (((((unsigned long)((unsigned int)(arg0)) == 4) | ((long)(arg0) < 4)) == 0)) {
        local_4 = -1;
        // x86-64 epilogue: restore rbp
        return (unsigned int)(local_4);
    }
    ((void (*)(char *))_ZN12_GLOBAL__N_17CountedC2Ev)((char *)(&local_10[0]));
    if ((((unsigned long)((unsigned int)(arg0)) == 0) | ((long)(arg0) < 0))) {
        local_4 = *(int *)(&glaurung_global_4034[0]);
        local_2c = 1;
    } else {
        ((void (*)(char *))_ZN12_GLOBAL__N_17CountedC2Ev)((char *)(&local_18[0]));
        if ((((unsigned long)((unsigned int)(arg0)) == 1) | ((long)(arg0) < 1))) {
            local_4 = *(int *)(&glaurung_global_4034[0]);
            local_2c = 1;
        } else {
            ((void (*)(char *))_ZN12_GLOBAL__N_17CountedC2Ev)((char *)(&local_28[0]));
            local_4 = *(int *)(&glaurung_global_4034[0]);
            local_2c = 1;
            ((void (*)(char *))_ZN12_GLOBAL__N_17CountedD2Ev)((char *)(&local_28[0]));
        }
        ((void (*)(char *))_ZN12_GLOBAL__N_17CountedD2Ev)((char *)(&local_18[0]));
    }
    ((void (*)(char *))_ZN12_GLOBAL__N_17CountedD2Ev)((char *)(&local_10[0]));
    // x86-64 epilogue: restore rbp
    return (unsigned int)(local_4);
    var9 = _Unwind_Resume(local_20);
}

gcc -O2

2/3
cpp_array_destruction fail 80 lines
// glaurung: cpp_array_destruction @ 0x1180
int32_t cpp_array_destruction(int32_t * arg0, int32_t arg1) {
    extern __attribute__((noreturn)) void __stack_chk_fail(void);
    int cursor;
    long local_10;
    unsigned char local_58[72];
    long ret;
    long rsp;
    long var10;
    long var11;
    long var12;
    void * var13;
    long var14;
    long var18;
    long var3;
    rsp = (rsp - 104);
    local_10 = (long)(0x28);
    cursor = 0;
    if ((arg0 == 0)) {
        goto L_125c;
    }
    if (((unsigned long)(4) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
        goto L_125c;
    }
    var3 = (rsp + 12);
    var10 = 0;
    *(long *)(&local_58[0]) = (long)((long)arg0);
    var11 = (long)arg0;
    var12 = (long)(((&local_58[0] + 72) - 24));
    *(long *)((&local_58[0] + 24)) = (long)((long)arg0);
    *(long *)((&local_58[0] + 48)) = (long)((long)arg0);
    *(int *)(((long)arg0)) = -1;
    *(int *)(((long)arg0 + 0x4)) = -1;
    *(int *)(((long)arg0 + 0x8)) = -1;
    *(int *)(((long)arg0 + 0xc)) = -1;
    *(int *)(((long)arg0 + 0x10)) = -1;
    *(int *)(((long)arg0 + 0x14)) = -1;
    *(int *)(((long)arg0 + 0x18)) = -1;
    *(int *)(((long)arg0 + 0x1c)) = -1;
    var13 = &local_58[0];
    *(long *)((&local_58[0] + 8)) = var3;
    *(int *)((&local_58[0] + 16)) = 10;
    *(long *)((&local_58[0] + 32)) = var3;
    *(int *)((&local_58[0] + 40)) = 20;
    *(long *)((&local_58[0] + 56)) = var3;
    *(int *)((&local_58[0] + 64)) = 30;
    var14 = var12;
    if (0) {
        goto L_121e;
    }
    L_1210: ;
    *(int *)((*(long *)((var12)) + (var10 * 4))) = *(int *)((var12 + 0x10));
    *(int *)((var3)) = (*(int *)((var3)) + 1);
    var14 = var12;
    L_121e: ;
    if ((var14 != var13)) {
        do {
            var3 = *(long *)((var14 - 0x10));
            var12 = (var14 - 24);
            var10 = (long)((int)(*(int *)((var3))));
            if ((((unsigned long)((unsigned int)(var10)) == 7) | ((long)((int)(var10)) < 7))) {
                goto L_1210;
            }
            var14 = var12;
        } while ((var12 != var13));
    }
    var18 = (unsigned long)((unsigned int)(*(int *)((var11 + 0x4))));
    ret = (unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((*(int *)((var11)) * 100) + ((unsigned long)((unsigned int)((var18 + (var18 * 4)))) * 2)))) + *(int *)((var11 + 0x8)))));
    L_1247: ;
    if ((local_10 != 0x28)) {
        goto L_1263;
    }
    // x86-64 epilogue: tear down frame
    return ret;
    L_125c: ;
    ret = 0xffffffff;
    goto L_1247;
    L_1263: ;
    __stack_chk_fail();
}
cpp_destruction_order pass 23 lines
// glaurung: cpp_destruction_order @ 0x1120
int32_t cpp_destruction_order(int32_t * arg0, int32_t arg1) {
    int cursor;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    *(int *)(((long)arg0)) = -1;
    *(int *)(((long)arg0 + 0x4)) = -1;
    *(int *)(((long)arg0 + 0x8)) = -1;
    *(int *)(((long)arg0 + 0xc)) = -1;
    *(int *)(((long)arg0 + 0x10)) = -1;
    *(int *)(((long)arg0 + 0x14)) = -1;
    *(int *)(((long)arg0 + 0x18)) = -1;
    *(int *)(((long)arg0 + 0x1c)) = -1;
    if (((unsigned long)((unsigned int)((arg1 & 1))) != 0)) {
        *(int *)(((long)arg0 + 0x8)) = 1;
        *(long *)(((long)arg0)) = 0x200000003;
        return 0xffffff9c;
    }
    *(int *)(((long)arg0 + 0x8)) = 1;
    *(long *)(((long)arg0)) = 0x200000004;
    return 421;
}
cpp_live_object_count pass 17 lines
// glaurung: cpp_live_object_count @ 0x1270
static unsigned char glaurung_global_402c[16] __attribute__((aligned(16)));
int32_t cpp_live_object_count(int32_t arg0) {
    extern unsigned char glaurung_global_402c[16];
    long ret;
    long var0;
    if (((unsigned long)(4) < (unsigned long)((unsigned long)((unsigned int)(arg0))))) {
        return 0xffffffff;
    }
    var0 = (unsigned long)((unsigned int)(*(int *)(&glaurung_global_402c[0])));
    ret = (unsigned long)((unsigned int)((var0 + 1)));
    if (((unsigned long)((unsigned int)(arg0)) != 0)) {
        ret = (unsigned long)((unsigned int)(((var0 + ((unsigned long)((unsigned int)(arg0)) != 1)) + 2)));
    }
    *(int *)(&glaurung_global_402c[0]) = var0;
    return ret;
}

clang -O2

3/3
cpp_array_destruction pass 18 lines
// glaurung: cpp_array_destruction @ 0x1150
int32_t cpp_array_destruction(int32_t * arg0, int32_t arg1) {
    long ret;
    ret = 0xffffffff;
    if ((arg0 != 0)) {
        if (((unsigned long)((unsigned long)((unsigned int)(arg1))) <= (unsigned long)(4))) {
            *(int *)(((long)arg0 + 0xc)) = -1;
            *(int *)(((long)arg0 + 0x10)) = -1;
            *(int *)(((long)arg0 + 0x14)) = -1;
            *(int *)(((long)arg0 + 0x18)) = -1;
            *(int *)(((long)arg0 + 0x1c)) = -1;
            *(long *)(((long)arg0)) = 0x140000001e;
            *(int *)(((long)arg0 + 0x8)) = 10;
            ret = 3210;
        }
    }
    return ret;
}
cpp_destruction_order pass 19 lines
// glaurung: cpp_destruction_order @ 0x1100
int32_t cpp_destruction_order(int32_t * arg0, int32_t arg1) {
    long var5;
    if ((arg0 == 0)) {
        return 0xffffffff;
    }
    *(int *)(((long)arg0)) = -1;
    *(int *)(((long)arg0 + 0x4)) = -1;
    *(int *)(((long)arg0 + 0x8)) = -1;
    *(int *)(((long)arg0 + 0xc)) = -1;
    var5 = (unsigned long)((unsigned int)((arg1 & 1)));
    *(int *)(((long)arg0 + 0x10)) = -1;
    *(int *)(((long)arg0 + 0x14)) = -1;
    *(int *)(((long)arg0 + 0x18)) = -1;
    *(int *)(((long)arg0 + 0x1c)) = -1;
    *(int *)(((long)arg0)) = (4 - var5);
    *(long *)(((long)arg0 + 0x4)) = 0x100000002;
    return (((unsigned long)((unsigned int)(var5)) == 0) ? 421 : 0xffffff9c);
}
cpp_live_object_count pass 4 lines
// glaurung: cpp_live_object_count @ 0x1190
int32_t cpp_live_object_count(int32_t arg0) {
    return (((unsigned long)((unsigned long)((unsigned int)(arg0))) < (unsigned long)(5)) ? (((unsigned long)((unsigned int)(arg0)) != 0) ? (unsigned long)((unsigned int)((((unsigned long)((unsigned int)(arg0)) == 1) ^ 3))) : 1) : 0xffffffff);
}

← 213 fixtures