Fixture 218
cpp lambdas and callables
C++ · 6 functions · 4 lanes · 22 of 24 function-lanes behave identically
2 of 4 lanes have a function that returns a different result after decompilation: clang-O0 (5/6), gcc-O0 (5/6).
Lambdas and the closure objects they compile to — the most common C++ abstraction in modern code, and one this corpus does not cover at all.
WHAT A LAMBDA ACTUALLY IS. An unnamed struct holding the captures, plus an operator(). Three capture modes produce three different objects:
* capture-by-value -> the captured object is COPIED into the closure, so the closure's field is a distinct storage location from the variable it came from; * capture-by-reference -> the field is a POINTER to the enclosing frame, so reads through it must be modelled as memory, not as a copy; * no capture -> an empty object with a static-like call operator, which every compiler inlines away entirely at -O2.
A decompiler that folds the by-value copy into a direct read of the original variable produces C that is right until the original is mutated after capture — which is exactly what capture_then_mutate does. That is a silent, plausible wrong answer, and it is the reason this fixture exists.
At -O0 each closure is a real stack object with a real operator() call; at -O2 most collapse to inline arithmetic. Both are worth covering: the -O0 lane tests object recovery and the -O2 lane tests that the collapse is followed.
10_cpp_runtime_shapes covers vtables, ctors/dtors and RAII; 137_cpp_templates covers monomorphization; 138_cpp_operators covers operator overloading on a named class. None of them constructs a closure, and none exercises a capture list. std::function is deliberately NOT used here: it would pull in libstdc++ type-erasure and heap allocation, which the corpus's no-libc, no-allocation rule excludes. The hand-written callable_ref below is the same indirection with none of the runtime.
#include <stdint.h>
/* Lambdas and the closure objects they compile to — the most common C++
* abstraction in modern code, and one this corpus does not cover at all.
*
* WHAT A LAMBDA ACTUALLY IS. An unnamed struct holding the captures, plus an
* `operator()`. Three capture modes produce three different objects:
*
* * capture-by-value -> the captured object is COPIED into the closure, so
* the closure's field is a distinct storage location
* from the variable it came from;
* * capture-by-reference -> the field is a POINTER to the enclosing frame, so
* reads through it must be modelled as memory, not as
* a copy;
* * no capture -> an empty object with a static-like call operator,
* which every compiler inlines away entirely at -O2.
*
* A decompiler that folds the by-value copy into a direct read of the original
* variable produces C that is right until the original is mutated after
* capture — which is exactly what `capture_then_mutate` does. That is a
* silent, plausible wrong answer, and it is the reason this fixture exists.
*
* At -O0 each closure is a real stack object with a real `operator()` call; at
* -O2 most collapse to inline arithmetic. Both are worth covering: the -O0 lane
* tests object recovery and the -O2 lane tests that the collapse is followed.
*
* `10_cpp_runtime_shapes` covers vtables, ctors/dtors and RAII;
* `137_cpp_templates` covers monomorphization; `138_cpp_operators` covers
* operator overloading on a named class. None of them constructs a closure, and
* none exercises a capture list. `std::function` is deliberately NOT used here:
* it would pull in libstdc++ type-erasure and heap allocation, which the
* corpus's no-libc, no-allocation rule excludes. The hand-written
* `callable_ref` below is the same indirection with none of the runtime.
*/
/* Capture by value: `base` is copied into the closure. */
extern "C" __attribute__((noinline)) int32_t capture_by_value(int32_t base,
int32_t count) {
if (count < 0 || count > 32) {
return -1;
}
auto add_base = [base](int32_t v) { return v + base; };
int32_t total = 0;
for (int32_t i = 0; i < count; i++) {
total += add_base(i);
}
return total;
}
/* Capture by reference: the closure holds a pointer into this frame, and the
* accumulator is mutated through it. */
extern "C" __attribute__((noinline)) int32_t capture_by_reference(int32_t count) {
if (count < 0 || count > 32) {
return -1;
}
int32_t total = 0;
auto accumulate = [&total](int32_t v) { total += v * 2; };
for (int32_t i = 0; i < count; i++) {
accumulate(i);
}
return total;
}
/* THE DISCRIMINATOR. `base` is captured by value and then mutated. A recovery
* that reads the original variable instead of the closure's copy returns a
* different number. */
extern "C" __attribute__((noinline)) int32_t capture_then_mutate(int32_t base) {
auto snapshot = [base](int32_t v) { return v + base; };
base += 1000; /* must NOT affect the closure */
return snapshot(1) + base;
}
/* Mixed capture: one by value, one by reference, in one closure object. */
extern "C" __attribute__((noinline)) int32_t mixed_capture(int32_t scale, int32_t count) {
if (count < 0 || count > 32) {
return -1;
}
int32_t total = 0;
auto step = [scale, &total](int32_t v) { total += v * scale; };
for (int32_t i = 0; i < count; i++) {
step(i);
}
return total;
}
/* Hand-written type erasure: a function pointer plus an environment pointer,
* which is what `std::function` is underneath and what a captureless lambda
* decays to. This is an INDIRECT CALL through a recovered object field. */
struct callable_ref {
int32_t (*fn)(const void *env, int32_t value);
const void *env;
};
struct scale_env {
int32_t factor;
};
static int32_t scale_apply(const void *env, int32_t value) {
return value * static_cast<const scale_env *>(env)->factor;
}
extern "C" __attribute__((noinline)) int32_t erased_callable(int32_t factor,
int32_t count) {
if (count < 0 || count > 32) {
return -1;
}
scale_env env{factor & 7};
callable_ref call{&scale_apply, &env};
int32_t total = 0;
for (int32_t i = 0; i < count; i++) {
total += call.fn(call.env, i);
}
return total;
}
/* CONTROL: the same arithmetic as an ordinary function call, no closure. */
static int32_t add_base_plain(int32_t v, int32_t base) { return v + base; }
extern "C" __attribute__((noinline)) int32_t plain_call_control(int32_t base,
int32_t count) {
if (count < 0 || count > 32) {
return -1;
}
int32_t total = 0;
for (int32_t i = 0; i < count; i++) {
total += add_base_plain(i, base);
}
return total;
} 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.
clang -O0
5/6capture_by_reference pass 26 lines
// glaurung: capture_by_reference @ 0x11a0
__attribute__((no_stack_protector)) int32_t capture_by_reference(int32_t arg0) {
extern void _ZZ20capture_by_referenceENK3__1clEi(char *, int);
unsigned char total[12];
int i;
unsigned char local_18[8];
// x86-64 prologue: save rbp, frame 32 bytes
if (((long)(arg0) < 0)) {
*(int *)((&total[0] + 8)) = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(*(int *)((&total[0] + 8)));
}
if (((((unsigned long)((unsigned int)(arg0)) == 32) | ((long)(arg0) < 32)) == 0)) {
*(int *)((&total[0] + 8)) = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(*(int *)((&total[0] + 8)));
}
*(int *)(&total[0]) = 0;
*(long *)(&local_18[0]) = (long)((long)(&total[0]));
for (i = 0; (i < arg0); i++) {
_ZZ20capture_by_referenceENK3__1clEi((char *)(&local_18[0]), (unsigned long)((unsigned int)(i)));
}
*(int *)((&total[0] + 8)) = *(int *)(&total[0]);
// x86-64 epilogue: restore rbp
return (unsigned int)(*(int *)((&total[0] + 8)));
} capture_by_value pass 29 lines
// glaurung: capture_by_value @ 0x1100
__attribute__((no_stack_protector)) int32_t capture_by_value(int32_t arg0, int32_t arg1) {
extern int _ZZ16capture_by_valueENK3__0clEi(char *, int);
int total;
int i;
unsigned char local_10[4];
int local_4;
int var2;
// x86-64 prologue: save rbp, frame 32 bytes
if (((long)(arg1) < 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((((unsigned long)((unsigned int)(arg1)) == 32) | ((long)(arg1) < 32)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
*(int *)(&local_10[0]) = arg0;
total = 0;
for (i = 0; (i < arg1); i++) {
var2 = _ZZ16capture_by_valueENK3__0clEi((char *)(&local_10[0]), (unsigned long)((unsigned int)(i)));
total = (var2 + total);
}
local_4 = total;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} capture_then_mutate pass 12 lines
// glaurung: capture_then_mutate @ 0x1240
__attribute__((no_stack_protector)) int32_t capture_then_mutate(int32_t arg0) {
extern int _ZZ19capture_then_mutateENK3__2clEi(char *, int);
unsigned char local_8[4];
int var4;
// x86-64 prologue: save rbp, frame 16 bytes
*(int *)(&local_8[0]) = arg0;
arg0 = ((unsigned int)(arg0) + 1000);
var4 = _ZZ19capture_then_mutateENK3__2clEi((char *)(&local_8[0]), 1);
// x86-64 epilogue: restore rbp
return (unsigned int)((var4 + arg0));
} erased_callable fail 31 lines
// glaurung: erased_callable @ 0x1340
__attribute__((no_stack_protector)) int32_t erased_callable(int32_t arg0, int32_t arg1) {
int total;
int i;
unsigned char local_10[4];
unsigned char local_20[16];
int local_4;
long var7;
// x86-64 prologue: save rbp, frame 48 bytes
if (((long)(arg1) < 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((((unsigned long)((unsigned int)(arg1)) == 32) | ((long)(arg1) < 32)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
*(int *)(&local_10[0]) = ((unsigned long)((unsigned int)(arg0)) & 7);
*(long *)(&local_20[0]) = (long)((long)(0x13e0));
*(long *)((&local_20[0] + 8)) = (long)((long)(&local_10[0]));
total = 0;
for (i = 0; (i < arg1); i++) {
var7 = ((long (*)(long, long))(*(long *)(&local_20[0])))(*(long *)((&local_20[0] + 8)), (unsigned long)((unsigned int)(i)));
total = (var7 + total);
}
local_4 = total;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} mixed_capture pass 28 lines
// glaurung: mixed_capture @ 0x12a0
__attribute__((no_stack_protector)) int32_t mixed_capture(int32_t arg0, int32_t arg1) {
extern void _ZZ13mixed_captureENK3__3clEi(char *, int);
unsigned char total[4];
int i;
unsigned char local_20[16];
int local_4;
// x86-64 prologue: save rbp, frame 48 bytes
if (((long)(arg1) < 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((((unsigned long)((unsigned int)(arg1)) == 32) | ((long)(arg1) < 32)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
*(int *)(&total[0]) = 0;
*(int *)(&local_20[0]) = arg0;
*(long *)((&local_20[0] + 8)) = (long)((long)(&total[0]));
for (i = 0; (i < arg1); i++) {
_ZZ13mixed_captureENK3__3clEi((char *)(&local_20[0]), (unsigned long)((unsigned int)(i)));
}
local_4 = *(int *)(&total[0]);
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} plain_call_control pass 27 lines
// glaurung: plain_call_control @ 0x1400
int32_t plain_call_control(int32_t arg0, int32_t arg1) {
extern int _ZL14add_base_plainii(int, int);
int total;
int i;
int local_4;
int var1;
// x86-64 prologue: save rbp, frame 32 bytes
if (((long)(arg1) < 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
if (((((unsigned long)((unsigned int)(arg1)) == 32) | ((long)(arg1) < 32)) == 0)) {
local_4 = -1;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
}
total = 0;
for (i = 0; (i < arg1); i++) {
var1 = _ZL14add_base_plainii((unsigned long)((unsigned int)(i)), (unsigned long)((unsigned int)(arg0)));
total = (var1 + total);
}
local_4 = total;
// x86-64 epilogue: restore rbp
return (unsigned int)(local_4);
} gcc -O0
5/6capture_by_reference pass 27 lines
// glaurung: capture_by_reference @ 0x11de
int32_t capture_by_reference(int32_t arg0) {
extern void _ZZ20capture_by_referenceENKUliE_clEi(char *, int);
extern __attribute__((noreturn)) void __stack_chk_fail(void);
unsigned char total[8];
int i;
unsigned char local_10[8];
long local_8;
long ret;
// x86-64 prologue: save rbp, frame 48 bytes
local_8 = (long)(0x28);
if ((((long)(arg0) < 0) || (((unsigned long)((unsigned int)(arg0)) != 32) && (32 <= (long)(arg0))))) {
ret = 0xffffffff;
} else {
*(int *)(&total[0]) = 0;
*(long *)(&local_10[0]) = (long)((long)(&total[0]));
for (i = 0; (i < arg0); i++) {
_ZZ20capture_by_referenceENKUliE_clEi((char *)(&local_10[0]), (unsigned long)((unsigned int)(i)));
}
ret = (unsigned long)((unsigned int)(*(int *)(&total[0])));
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} capture_by_value pass 29 lines
// glaurung: capture_by_value @ 0x1132
int32_t capture_by_value(int32_t arg0, int32_t arg1) {
extern int _ZZ16capture_by_valueENKUliE_clEi(char *, int);
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int total;
int i;
unsigned char local_14[4];
long local_8;
long ret;
int var7;
// x86-64 prologue: save rbp, frame 48 bytes
local_8 = (long)(0x28);
if ((((long)(arg1) < 0) || (((unsigned long)((unsigned int)(arg1)) != 32) && (32 <= (long)(arg1))))) {
ret = 0xffffffff;
} else {
*(int *)(&local_14[0]) = arg0;
total = 0;
for (i = 0; (i < arg1); i++) {
var7 = _ZZ16capture_by_valueENKUliE_clEi((char *)(&local_14[0]), (unsigned long)((unsigned int)(i)));
total = (total + var7);
}
ret = (unsigned long)((unsigned int)(total));
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} capture_then_mutate pass 20 lines
// glaurung: capture_then_mutate @ 0x1276
int32_t capture_then_mutate(int32_t arg0) {
extern int _ZZ19capture_then_mutateENKUliE_clEi(char *, int);
extern __attribute__((noreturn)) void __stack_chk_fail(void);
long local_8;
unsigned char local_c[4];
long ret;
int var5;
// x86-64 prologue: save rbp, frame 32 bytes
local_8 = (long)(0x28);
*(int *)(&local_c[0]) = arg0;
arg0 = (arg0 + 1000);
var5 = _ZZ19capture_then_mutateENKUliE_clEi((char *)(&local_c[0]), 1);
ret = (unsigned long)((unsigned int)((var5 + (unsigned long)((unsigned int)(arg0)))));
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} erased_callable fail 33 lines
// glaurung: erased_callable @ 0x13a1
int32_t erased_callable(int32_t arg0, int32_t arg1) {
extern __attribute__((noreturn)) void __stack_chk_fail(void);
int total;
int i;
unsigned char local_20[16];
unsigned char local_2c[4];
long local_8;
long ret;
long var12;
// x86-64 prologue: save rbp, frame 64 bytes
local_8 = (long)(0x28);
if ((((long)(arg1) < 0) || (((unsigned long)((unsigned int)(arg1)) != 32) && (32 <= (long)(arg1))))) {
ret = 0xffffffff;
} else {
*(int *)(&local_2c[0]) = ((unsigned long)((unsigned int)(arg0)) & 7);
*(long *)(&local_20[0]) = 0;
*(long *)((&local_20[0] + 8)) = 0;
*(long *)(&local_20[0]) = (long)((long)(0x1386));
*(long *)((&local_20[0] + 8)) = (long)((long)(&local_2c[0]));
total = 0;
for (i = 0; (i < arg1); i++) {
var12 = ((long (*)(long, long))(*(long *)(&local_20[0])))(*(long *)((&local_20[0] + 8)), (unsigned long)((unsigned int)(i)));
total = (total + var12);
}
ret = (unsigned long)((unsigned int)(total));
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} mixed_capture pass 28 lines
// glaurung: mixed_capture @ 0x12fe
int32_t mixed_capture(int32_t arg0, int32_t arg1) {
extern void _ZZ13mixed_captureENKUliE_clEi(char *, int);
extern __attribute__((noreturn)) void __stack_chk_fail(void);
unsigned char total[8];
int i;
unsigned char local_20[16];
long local_8;
long ret;
// x86-64 prologue: save rbp, frame 64 bytes
local_8 = (long)(0x28);
if ((((long)(arg1) < 0) || (((unsigned long)((unsigned int)(arg1)) != 32) && (32 <= (long)(arg1))))) {
ret = 0xffffffff;
} else {
*(int *)(&total[0]) = 0;
*(int *)(&local_20[0]) = arg0;
*(long *)((&local_20[0] + 8)) = (long)((long)(&total[0]));
for (i = 0; (i < arg1); i++) {
_ZZ13mixed_captureENKUliE_clEi((char *)(&local_20[0]), (unsigned long)((unsigned int)(i)));
}
ret = (unsigned long)((unsigned int)(*(int *)(&total[0])));
}
if ((local_8 != 0x28)) {
__stack_chk_fail();
}
// x86-64 epilogue: restore rbp
return ret;
} plain_call_control pass 23 lines
// glaurung: plain_call_control @ 0x1463
int32_t plain_call_control(int32_t arg0, int32_t arg1) {
extern int _ZL14add_base_plainii(int, int);
int total;
int i;
int var3;
// x86-64 prologue: save rbp, frame 24 bytes
if (((long)(arg1) < 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
if (((((unsigned long)((unsigned int)(arg1)) == 32) | ((long)(arg1) < 32)) == 0)) {
// x86-64 epilogue: restore rbp
return 0xffffffff;
}
total = 0;
for (i = 0; (i < arg1); i++) {
var3 = _ZL14add_base_plainii((unsigned long)((unsigned int)(i)), (unsigned long)((unsigned int)(arg0)));
total = (total + var3);
}
// x86-64 epilogue: restore rbp
return (unsigned int)(total);
} clang -O2
6/6capture_by_reference pass 13 lines
// glaurung: capture_by_reference @ 0x1130
int32_t capture_by_reference(int32_t arg0) {
int i;
long ret;
ret = 0xffffffff;
if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg0))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg0)) == 0)) {
return 0;
}
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 - 2))) * (unsigned long)((unsigned int)((arg0 - 1)))))) & -2))) + (arg0 * 2)))) - 2));
} capture_by_value pass 16 lines
// glaurung: capture_by_value @ 0x1100
int32_t capture_by_value(int32_t arg0, int32_t arg1) {
int i;
int total;
long ret;
long var1;
ret = 0xffffffff;
if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var1 = (unsigned long)((unsigned int)((arg1 - 1)));
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + 1))) * var1))) + arg0))) + ((unsigned long)(((unsigned long)((unsigned int)((arg1 - 2))) * var1)) >> 1)));
} capture_then_mutate pass 4 lines
// glaurung: capture_then_mutate @ 0x1160
int32_t capture_then_mutate(int32_t arg0) {
return (unsigned int)(((unsigned long)((unsigned int)((arg0 + arg0))) + 1001));
} erased_callable pass 14 lines
// glaurung: erased_callable @ 0x11a0
int32_t erased_callable(int32_t arg0, int32_t arg1) {
int i;
int total;
long ret;
ret = 0xffffffff;
if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((((unsigned long)(((unsigned long)((unsigned int)((arg1 - 2))) * (unsigned long)((unsigned int)((arg1 - 1))))) >> 1) + arg1))) - 1))) * (unsigned long)((unsigned int)((arg0 & 7)))));
} mixed_capture pass 13 lines
// glaurung: mixed_capture @ 0x1170
int32_t mixed_capture(int32_t arg0, int32_t arg1) {
int i;
long ret;
ret = 0xffffffff;
if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((((unsigned long)(((unsigned long)((unsigned int)((arg1 - 2))) * (unsigned long)((unsigned int)((arg1 - 1))))) >> 1) + arg1))) - 1))) * arg0));
} plain_call_control pass 16 lines
// glaurung: plain_call_control @ 0x11d0
int32_t plain_call_control(int32_t arg0, int32_t arg1) {
int i;
int total;
long ret;
long var1;
ret = 0xffffffff;
if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return ret;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var1 = (unsigned long)((unsigned int)((arg1 - 1)));
return (unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)(((unsigned long)((unsigned int)((arg0 + 1))) * var1))) + arg0))) + ((unsigned long)(((unsigned long)((unsigned int)((arg1 - 2))) * var1)) >> 1)));
} gcc -O2
6/6capture_by_reference pass 33 lines
// glaurung: capture_by_reference @ 0x1140
int32_t capture_by_reference(int32_t arg0) {
int total;
int i;
long var1;
long var3;
long var6;
int var8;
long var9;
if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg0))))) {
goto L_1177;
}
if (((unsigned long)((unsigned int)(arg0)) == 0)) {
goto L_1170;
}
var1 = (unsigned long)((unsigned int)((arg0 + arg0)));
var3 = 0;
var6 = 0;
do {
total = (var6 + var3);
var6 = (unsigned long)((unsigned int)(total));
var8 = (var3 + 2);
var3 = (unsigned long)((unsigned int)(var8));
var9 = (unsigned long)((unsigned int)(total));
} while (((unsigned int)(var1) != (unsigned int)(var8)));
L_1162: ;
return (unsigned int)(var9);
L_1170: ;
return 0;
L_1177: ;
var9 = 0xffffffff;
goto L_1162;
} capture_by_value pass 24 lines
// glaurung: capture_by_value @ 0x1100
int32_t capture_by_value(int32_t arg0, int32_t arg1) {
int i;
int total;
long ret;
long var2;
long var5;
int var7;
if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return 0xffffffff;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (unsigned long)((unsigned int)((arg1 + arg0)));
ret = 0;
var5 = (unsigned long)((unsigned int)(arg0));
do {
ret = (unsigned long)((unsigned int)((ret + var5)));
var7 = (var5 + 1);
var5 = (unsigned long)((unsigned int)(var7));
} while (((unsigned int)(var2) != (unsigned int)(var7)));
return ret;
} capture_then_mutate pass 4 lines
// glaurung: capture_then_mutate @ 0x1180
int32_t capture_then_mutate(int32_t arg0) {
return (unsigned int)(((arg0 + arg0) + 1001));
} erased_callable pass 35 lines
// glaurung: erased_callable @ 0x11d0
int32_t erased_callable(int32_t arg0, int32_t arg1) {
int i;
int total;
long var1;
int var10;
long var13;
long var3;
long var8;
if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
goto L_1207;
}
var1 = (unsigned long)((unsigned int)((arg0 & 7)));
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
goto L_1200;
}
var3 = 0;
var8 = 0;
i = 0;
do {
var10 = (i + 1);
i = (unsigned long)((unsigned int)(var10));
total = (var8 + var3);
var8 = (unsigned long)((unsigned int)(total));
var3 = (unsigned long)((unsigned int)((var3 + var1)));
var13 = (unsigned long)((unsigned int)(total));
} while (((unsigned int)(arg1) != (unsigned int)(var10)));
L_11fc: ;
return (unsigned int)(var13);
L_1200: ;
return 0;
L_1207: ;
var13 = 0xffffffff;
goto L_11fc;
} mixed_capture pass 33 lines
// glaurung: mixed_capture @ 0x1190
int32_t mixed_capture(int32_t arg0, int32_t arg1) {
int i;
int total;
long var1;
long var11;
long var6;
int var8;
if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
goto L_11c7;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
goto L_11c0;
}
var1 = 0;
var6 = 0;
i = 0;
do {
var8 = (i + 1);
i = (unsigned long)((unsigned int)(var8));
total = (var6 + var1);
var6 = (unsigned long)((unsigned int)(total));
var1 = (unsigned long)((unsigned int)((var1 + arg0)));
var11 = (unsigned long)((unsigned int)(total));
} while (((unsigned int)(arg1) != (unsigned int)(var8)));
L_11b4: ;
return (unsigned int)(var11);
L_11c0: ;
return 0;
L_11c7: ;
var11 = 0xffffffff;
goto L_11b4;
} plain_call_control pass 24 lines
// glaurung: plain_call_control @ 0x1210
int32_t plain_call_control(int32_t arg0, int32_t arg1) {
int i;
int total;
long ret;
long var2;
long var5;
int var7;
if (((unsigned long)(32) < (unsigned long)((unsigned long)((unsigned int)(arg1))))) {
return 0xffffffff;
}
if (((unsigned long)((unsigned int)(arg1)) == 0)) {
return 0;
}
var2 = (unsigned long)((unsigned int)((arg1 + arg0)));
ret = 0;
var5 = (unsigned long)((unsigned int)(arg0));
do {
ret = (unsigned long)((unsigned int)((ret + var5)));
var7 = (var5 + 1);
var5 = (unsigned long)((unsigned int)(var7));
} while (((unsigned int)(var2) != (unsigned int)(var7)));
return ret;
}