Various broken macro definitions were accepted until now. Built and tested natively on i686-pc-linux-gnu and as cross tools for a large number of targets. Jan gas/ 2005-01-26 Jan Beulich * macro.c (do_formals): Adjust to no longer accept empty parameter names. (define_macro): Adjust to no longer accept empty macro name, garbage following the parameters, or macros that were previously defined. * read.c (s_bad_end): Declare. (potable): Add endm. Handler for endr and endm is s_bad_end. (s_bad_end): Rename from s_bad_endr. Adjust to handle both .endm and .endr. * read.h (s_bad_endr): Remove. gas/testsuite/ 2005-01-26 Jan Beulich * gas/macros/badarg.[ls]: New. * gas/macros/end.[ls]: New. * gas/macros/redef.[ls]: New. * gas/macros/macros.exp (run_list_test): Copy from elsewhere. Run new tests. --- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/macro.c 2004-10-08 08:52:54.000000000 +0200 +++ 2005-01-25.13.54/gas/macro.c 2005-01-26 08:32:36.982880800 +0100 @@ -435,9 +435,11 @@ do_formals (macro_entry *macro, int idx, macro->formal_count = 0; macro->formal_hash = hash_new (); + idx = sb_skip_white (idx, in); while (idx < in->len) { formal_entry *formal; + int cidx; formal = (formal_entry *) xmalloc (sizeof (formal_entry)); @@ -445,27 +447,33 @@ do_formals (macro_entry *macro, int idx, sb_new (&formal->def); sb_new (&formal->actual); - idx = sb_skip_white (idx, in); idx = get_token (idx, in, &formal->name); if (formal->name.len == 0) - break; + { + if (macro->formal_count) + --idx; + break; + } idx = sb_skip_white (idx, in); - if (formal->name.len) + /* This is a formal. */ + if (idx < in->len && in->ptr[idx] == '=') { - /* This is a formal. */ - if (idx < in->len && in->ptr[idx] == '=') - { - /* Got a default. */ - idx = get_any_string (idx + 1, in, &formal->def, 1, 0); - } + /* Got a default. */ + idx = get_any_string (idx + 1, in, &formal->def, 1, 0); + idx = sb_skip_white (idx, in); } /* Add to macro's hash table. */ hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal); - formal->index = macro->formal_count; + formal->index = macro->formal_count++; + cidx = idx; idx = sb_skip_comma (idx, in); - macro->formal_count++; + if (idx != cidx && idx >= in->len) + { + idx = cidx; + break; + } *p = formal; p = &formal->next; *p = NULL; @@ -533,8 +541,9 @@ define_macro (int idx, sb *in, sb *label { /* It's the label: MACRO (formals,...) sort */ idx = do_formals (macro, idx + 1, in); - if (in->ptr[idx] != ')') + if (idx >= in->len || in->ptr[idx] != ')') return _("missing ) after formals"); + idx = sb_skip_white (idx + 1, in); } else { @@ -544,15 +553,27 @@ define_macro (int idx, sb *in, sb *label } else { + int cidx; + idx = get_token (idx, in, &name); - idx = sb_skip_comma (idx, in); - idx = do_formals (macro, idx, in); + if (name.len == 0) + return _("Missing macro name"); + cidx = sb_skip_white (idx, in); + idx = sb_skip_comma (cidx, in); + if (idx == cidx || idx < in->len) + idx = do_formals (macro, idx, in); + else + idx = cidx; } + if (idx < in->len) + return _("Bad macro parameter list"); /* And stick it in the macro hash table. */ for (idx = 0; idx < name.len; idx++) name.ptr[idx] = TOLOWER (name.ptr[idx]); namestr = sb_terminate (&name); + if (hash_find (macro_hash, namestr)) + return _("Macro with this name was already defined"); hash_jam (macro_hash, namestr, (PTR) macro); macro_defined = 1; --- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/read.c 2005-01-24 08:34:19.000000000 +0100 +++ 2005-01-25.13.54/gas/read.c 2005-01-26 08:33:12.715448624 +0100 @@ -214,6 +214,7 @@ static int dwarf_file_string; static void do_align (int, char *, int, int); static void s_align (int, int); static void s_altmacro (int); +static void s_bad_end (int); static int hex_float (int, char *); static segT get_known_segmented_expression (expressionS * expP); static void pobegin (void); @@ -298,7 +299,8 @@ static const pseudo_typeS potable[] = { {"endc", s_endif, 0}, {"endfunc", s_func, 1}, {"endif", s_endif, 0}, - {"endr", s_bad_endr, 0}, + {"endm", s_bad_end, 0}, + {"endr", s_bad_end, 1}, /* endef */ {"equ", s_set, 0}, {"equiv", s_set, 1}, @@ -2659,12 +2661,14 @@ s_purgem (int ignore ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } -/* Handle the .rept pseudo-op. */ +/* Handle the .endm/.endr pseudo-ops. */ -void -s_bad_endr (int ignore ATTRIBUTE_UNUSED) +static void +s_bad_end (int endr) { - as_warn (_(".endr encountered without preceeding .rept, .irc, or .irp")); + as_warn (_(".end%c encountered without preceeding %s"), + endr ? 'r' : 'm', + endr ? ".rept, .irp, or .irpc" : ".macro"); demand_empty_rest_of_line (); } --- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/read.h 2004-11-23 08:19:29.000000000 +0100 +++ 2005-01-25.13.54/gas/read.h 2005-01-26 08:32:37.030873504 +0100 @@ -142,7 +142,6 @@ extern symbolS *s_lcomm_internal (int, s extern void s_app_file_string (char *, int); extern void s_app_file (int); extern void s_app_line (int); -extern void s_bad_endr (int); extern void s_comm (int); extern void s_data (int); extern void s_desc (int); --- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/badarg.l 1970-01-01 01:00:00.000000000 +0100 +++ 2005-01-25.13.54/gas/testsuite/gas/macros/badarg.l 2005-01-25 09:55:54.000000000 +0100 @@ -0,0 +1,7 @@ +.*: Assembler messages: +.*:1: Error: .* +.*:4: Error: .* +.*:7: Error: .* +.*:10: Error: .* +.*:13: Error: .* +.*:16: Error: .* --- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/badarg.s 1970-01-01 01:00:00.000000000 +0100 +++ 2005-01-25.13.54/gas/testsuite/gas/macros/badarg.s 2005-01-25 09:55:37.000000000 +0100 @@ -0,0 +1,17 @@ + .macro + .endm + + .macro ,arg1 + .endm + + .macro m1, + .endm + + .macro m2,, + .endm + + .macro m3,arg1, + .endm + + .macro m4,,arg2 + .endm --- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/end.l 1970-01-01 01:00:00.000000000 +0100 +++ 2005-01-25.13.54/gas/testsuite/gas/macros/end.l 2005-01-25 11:30:38.000000000 +0100 @@ -0,0 +1,3 @@ +.*: Assembler messages: +.*:1: Warning: \.endm .* \.macro +.*:2: Warning: \.endr .* (\.rept|\.irpc?).*(\.rept|\.irpc?).*(\.rept|\.irpc?) --- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/end.s 1970-01-01 01:00:00.000000000 +0100 +++ 2005-01-25.13.54/gas/testsuite/gas/macros/end.s 2005-01-25 11:26:25.000000000 +0100 @@ -0,0 +1,2 @@ + .endm + .endr --- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/macros.exp 2004-11-18 15:05:44.000000000 +0100 +++ 2005-01-25.13.54/gas/testsuite/gas/macros/macros.exp 2005-01-26 08:32:37.074866816 +0100 @@ -1,5 +1,18 @@ # Run some tests of gas macros. +proc run_list_test { name opts } { + global srcdir subdir + set testname "macros $name" + set file $srcdir/$subdir/$name + gas_run ${name}.s $opts ">&dump.out" + if { [regexp_diff "dump.out" "${file}.l"] } then { + fail $testname + verbose "output is [file_contents "dump.out"]" 2 + return + } + pass $testname +} + if { ![istarget hppa*-*-*] || [istarget *-*-linux*] } { run_dump_test test1 } @@ -47,3 +60,7 @@ run_dump_test app1 run_dump_test app2 run_dump_test app3 run_dump_test app4 + +run_list_test badarg "" +run_list_test end "" +run_list_test redef "" --- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/redef.l 1970-01-01 01:00:00.000000000 +0100 +++ 2005-01-25.13.54/gas/testsuite/gas/macros/redef.l 2005-01-25 11:39:54.000000000 +0100 @@ -0,0 +1,2 @@ +.*: Assembler messages: +.*:3: Error: .* --- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/redef.s 1970-01-01 01:00:00.000000000 +0100 +++ 2005-01-25.13.54/gas/testsuite/gas/macros/redef.s 2005-01-25 11:36:32.000000000 +0100 @@ -0,0 +1,4 @@ + .macro m + .endm + .macro m + .endm