From 9c5cabb502b59e5cc4354c8ca66be3d4a3e03bf9 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 3 Mar 2015 17:08:02 +0000 Subject: [PATCH] py: Give error for duplicate label in inline assembler. --- py/compile.c | 5 ++++- py/emit.h | 2 +- py/emitinlinethumb.c | 11 ++++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/py/compile.c b/py/compile.c index 0386b956aa..34e4f41ce1 100644 --- a/py/compile.c +++ b/py/compile.c @@ -3425,7 +3425,10 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind } uint lab = comp_next_label(comp); if (pass > MP_PASS_SCOPE) { - EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0])); + if (!EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0]))) { + compile_syntax_error(comp, nodes[i], "label redefined"); + return; + } } } else if (op == MP_QSTR_align) { if (!(n_args == 1 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) { diff --git a/py/emit.h b/py/emit.h index ea8c3a655a..f350f89343 100644 --- a/py/emit.h +++ b/py/emit.h @@ -193,7 +193,7 @@ typedef struct _emit_inline_asm_method_table_t { void (*start_pass)(emit_inline_asm_t *emit, pass_kind_t pass, scope_t *scope, mp_obj_t *error_slot); void (*end_pass)(emit_inline_asm_t *emit); mp_uint_t (*count_params)(emit_inline_asm_t *emit, mp_uint_t n_params, mp_parse_node_t *pn_params); - void (*label)(emit_inline_asm_t *emit, mp_uint_t label_num, qstr label_id); + bool (*label)(emit_inline_asm_t *emit, mp_uint_t label_num, qstr label_id); void (*align)(emit_inline_asm_t *emit, mp_uint_t align); void (*data)(emit_inline_asm_t *emit, mp_uint_t bytesize, mp_uint_t val); void (*op)(emit_inline_asm_t *emit, qstr op, mp_uint_t n_args, mp_parse_node_t *pn_args); diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 6fe110b7db..57fac17290 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -111,10 +111,19 @@ STATIC mp_uint_t emit_inline_thumb_count_params(emit_inline_asm_t *emit, mp_uint return n_params; } -STATIC void emit_inline_thumb_label(emit_inline_asm_t *emit, mp_uint_t label_num, qstr label_id) { +STATIC bool emit_inline_thumb_label(emit_inline_asm_t *emit, mp_uint_t label_num, qstr label_id) { assert(label_num < emit->max_num_labels); + if (emit->pass == MP_PASS_CODE_SIZE) { + // check for duplicate label on first pass + for (int i = 0; i < emit->max_num_labels; i++) { + if (emit->label_lookup[i] == label_id) { + return false; + } + } + } emit->label_lookup[label_num] = label_id; asm_thumb_label_assign(emit->as, label_num); + return true; } STATIC void emit_inline_thumb_align(emit_inline_asm_t *emit, mp_uint_t align) {