-
Notifications
You must be signed in to change notification settings - Fork 179
Open
Labels
Milestone
Description
I have the following code
(defn testrec [n]
(let [loop (fn [i]
(if (< i n)
(loop (+ i 1))
i))]
(loop 0)))
(defn main []
(IO.println &(fmt "out %d" (testrec 10))))and I get the following C code for the testrec function
int testrec(int n) {
int _31;
/* let */ {
// This lambda captures 1 variables: n
_Lambda_testrec_26_env_ty *_26_env = CARP_MALLOC(sizeof(_Lambda_testrec_26_env_ty));
_26_env->n = n;
Lambda _26 = {
.callback = (void*)_Lambda_testrec_26_env,
.env = _26_env,
.delete = (void*)_Lambda_testrec_26_env_ty_delete,
.copy = (void*)_Lambda_testrec_26_env_ty_copy
};
Lambda loop = _26;
int _30 = loop.env ? ((int(*)(LambdaEnv, int))loop.callback)(loop.env, 0) : ((int(*)(int))loop.callback)(0);
_31 = _30;
Function_delete__int_int(loop);
}
return _31;
}The environment is clearly stored in the _26 which is passed to the function when it's called
This is the generated function for loop
int _Lambda_testrec_26_env(_Lambda_testrec_26_env_ty* _env, int i) {
int _25;
bool _13 = Int__LT_(i, _env->n);
if (_13) {
Lambda _15 = { .callback = (void*)_Lambda_testrec_26_env, .env = NULL, .delete = NULL, .copy = NULL }; //Sym_Lambda_testrec_26_env LookupRecursive
int _19 = Int__PLUS_(i, 1);
int _20 = _15.env ? ((int(*)(LambdaEnv, int))_15.callback)(_15.env, _19) : ((int(*)(int))_15.callback)(_19);
int _21 = _20;
_25 = _21;
} else {
int _24 = i;
_25 = _24;
}
return _25;
}For some reason the .env is never set and the _env is not passed to the next recursive call to loop (_Lambda_testrec_26_env),
but it tries to access _env->n in the next iteration, which is now set to NULL. This causes a segfault and the program crashes.
When i manually set .env = _env in the C code for the lambda, the program works as intended.
This looks like a compiler bug.