From 9c5cabb502b59e5cc4354c8ca66be3d4a3e03bf9 Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
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 0386b956a..34e4f41ce 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 ea8c3a655..f350f8934 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 6fe110b7d..57fac1729 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) {
-- 
GitLab