diff --git a/tccgen.c b/tccgen.c
index 3ecfb099..d77e48cd 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -5419,6 +5419,7 @@ ST_FUNC void decl(int l)
             continue;
         }
         while (1) { /* iterate thru each declaration */
+            char *asm_label; // associated asm label
             type = btype;
             type_decl(&type, &ad, &v, TYPE_DIRECT);
 #if 0
@@ -5439,6 +5440,18 @@ ST_FUNC void decl(int l)
                     func_decl_list(sym);
             }
 
+            asm_label = NULL;
+            if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
+                CString astr;
+
+                asm_label_instr(&astr);
+                asm_label = tcc_strdup(astr.data);
+                cstr_free(&astr);
+                
+                /* parse one last attribute list, after asm label */
+                parse_attribute(&ad);
+            }
+
             if (ad.weak)
                 type.t |= VT_WEAK;
 #ifdef TCC_TARGET_PE
@@ -5548,39 +5561,15 @@ ST_FUNC void decl(int l)
                     sym = sym_push(v, &type, INT_ATTR(&ad), 0);
                     sym->type.t |= VT_TYPEDEF;
                 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
-                    char *asm_label; // associated asm label
-                    Sym *fn;
-
-                    asm_label = NULL;
                     /* external function definition */
                     /* specific case for func_call attribute */
                     type.ref->r = INT_ATTR(&ad);
-
-                    if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
-                        CString astr;
-
-                        asm_label_instr(&astr);
-                        asm_label = tcc_strdup(astr.data);
-                        cstr_free(&astr);
-                    }
-                    fn = external_sym(v, &type, 0, asm_label);
-                    if (gnu_ext && (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2))
-                        parse_attribute((AttributeDef *) &fn->type.ref->r);
+                    external_sym(v, &type, 0, asm_label);
                 } else {
-                    char *asm_label; // associated asm label
-
                     /* not lvalue if array */
                     r = 0;
-                    asm_label = NULL;
                     if (!(type.t & VT_ARRAY))
                         r |= lvalue_type(type.t);
-                    if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
-                        CString astr;
-
-                        asm_label_instr(&astr);
-                        asm_label = tcc_strdup(astr.data);
-                        cstr_free(&astr);
-                    }
                     has_init = (tok == '=');
                     if ((btype.t & VT_EXTERN) ||
                         ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
diff --git a/tests/tcctest.c b/tests/tcctest.c
index 5ebc7bb8..2c4d1d4f 100644
--- a/tests/tcctest.c
+++ b/tests/tcctest.c
@@ -2358,6 +2358,13 @@ extern int                           (*weak_fpa)() __attribute__((weak));
 extern int __attribute__((weak))     (*weak_fpb)();
 extern     __attribute__((weak)) int (*weak_fpc)();
 
+extern int                     weak_asm_f1(void) asm("weak_asm_f1x") __attribute((weak));
+extern int __attribute((weak)) weak_asm_f2(void) asm("weak_asm_f2x")                    ;
+extern int __attribute((weak)) weak_asm_f3(void) asm("weak_asm_f3x") __attribute((weak));
+extern int                     weak_asm_v1       asm("weak_asm_v1x") __attribute((weak));
+extern int __attribute((weak)) weak_asm_v2       asm("weak_asm_v2x")                    ;
+extern int __attribute((weak)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak));
+
 void __attribute__((weak)) weak_test(void)
 {
 	printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123);
@@ -2370,6 +2377,13 @@ void __attribute__((weak)) weak_test(void)
 	printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
 	printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
 	printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
+	
+	printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
+	printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
+	printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);
+	printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL);
+	printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL);
+	printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL);
 }
 
 int __attribute__((weak)) weak_f2() { return 222; }