From 4b1e9d8f92aa948f8ecccf364edcb911a135f2c8 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 23 Jan 2018 20:54:02 -0500 Subject: [PATCH] alloca seems buggy on M4 --- extmod/modure.c | 2 +- py/builtinimport.c | 2 +- py/runtime.c | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/extmod/modure.c b/extmod/modure.c index 78de4706d2..3358b8e210 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -144,7 +144,7 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) { } mp_obj_t retval = mp_obj_new_list(0, NULL); - const char **caps = alloca(caps_num * sizeof(char*)); + const char* caps[caps_num]; while (true) { // cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char memset((char**)caps, 0, caps_num * sizeof(char*)); diff --git a/py/builtinimport.c b/py/builtinimport.c index b76ea00bd8..0caba74f46 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -330,7 +330,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { } uint new_mod_l = (mod_len == 0 ? (size_t)(p - this_name) : (size_t)(p - this_name) + 1 + mod_len); - char *new_mod = alloca(new_mod_l); + char new_mod[new_mod_l]; memcpy(new_mod, this_name, p - this_name); if (mod_len != 0) { new_mod[p - this_name] = '.'; diff --git a/py/runtime.c b/py/runtime.c index cbec82f17c..7a16e4a1b2 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1428,9 +1428,10 @@ import_error: mp_load_method_maybe(module, MP_QSTR___name__, dest); size_t pkg_name_len; const char *pkg_name = mp_obj_str_get_data(dest[0], &pkg_name_len); - const uint dot_name_len = pkg_name_len + 1 + qstr_len(name); - char *dot_name = alloca(dot_name_len); + // Previously dot_name was created using alloca(), but that caused run-time crashes on M4 due to + // stack corruption (compiler bug, it appears), so use an array instead. + char dot_name[dot_name_len]; memcpy(dot_name, pkg_name, pkg_name_len); dot_name[pkg_name_len] = '.'; memcpy(dot_name + pkg_name_len + 1, qstr_str(name), qstr_len(name));