From d929913e77af0f9b6bc262610af204bf4e7fffba Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Sat, 14 Jul 2007 16:19:18 +0000 Subject: [PATCH] * config/tc-arm.c (create_register_alias): Return a boolean rather than an integer. Check the return value of insert_reg_alias and do not continue to create aliases once an insertion has failed. (s_unreq): Delete the all-upper-case and all-lower-case alternatives as well. * testsuite/gas/arm/arm.s: Add tests for re-aliasing a previously removed alias. * testsuite/gas/arm/arm.l: Add new expected warning message. --- gas/ChangeLog | 9 +++++ gas/config/tc-arm.c | 81 +++++++++++++++++++++++++++++++++++---------- gas/testsuite/ChangeLog | 6 ++++ gas/testsuite/gas/arm/req.l | 1 + gas/testsuite/gas/arm/req.s | 20 +++++++++-- 5 files changed, 98 insertions(+), 19 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index d1a43a3..602c58c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2007-07-14 Nick Clifton + + * config/tc-arm.c (create_register_alias): Return a boolean rather + than an integer. + Check the return value of insert_reg_alias and do not continue to + create aliases once an insertion has failed. + (s_unreq): Delete the all-upper-case and all-lower-case + alternatives as well. + 2007-07-12 Kai Tietz * symbols.c: Print bfd_hostptr_t to file via fprintf_vma. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index fbb7ae2..82562d7 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -1971,7 +1971,7 @@ insert_reg_alias (char *str, int number, int type) else if (new->number != number || new->type != type) as_warn (_("ignoring redefinition of register alias '%s'"), str); - return 0; + return NULL; } name = xstrdup (str); @@ -2013,9 +2013,9 @@ insert_neon_reg_alias (char *str, int number, int type, new_register_name .req existing_register_name If we find one, or if it looks sufficiently like one that we want to - handle any error here, return non-zero. Otherwise return zero. */ + handle any error here, return TRUE. Otherwise return FALSE. */ -static int +static bfd_boolean create_register_alias (char * newname, char *p) { struct reg_entry *old; @@ -2026,17 +2026,17 @@ create_register_alias (char * newname, char *p) collapsed to single spaces. */ oldname = p; if (strncmp (oldname, " .req ", 6) != 0) - return 0; + return FALSE; oldname += 6; if (*oldname == '\0') - return 0; + return FALSE; old = hash_find (arm_reg_hsh, oldname); if (!old) { as_warn (_("unknown register '%s' -- .req ignored"), oldname); - return 1; + return TRUE; } /* If TC_CASE_SENSITIVE is defined, then newname already points to @@ -2056,21 +2056,34 @@ create_register_alias (char * newname, char *p) /* Create aliases under the new name as stated; an all-lowercase version of the new name; and an all-uppercase version of the new name. */ - insert_reg_alias (nbuf, old->number, old->type); - - for (p = nbuf; *p; p++) - *p = TOUPPER (*p); + if (insert_reg_alias (nbuf, old->number, old->type) != NULL) + { + for (p = nbuf; *p; p++) + *p = TOUPPER (*p); - if (strncmp (nbuf, newname, nlen)) - insert_reg_alias (nbuf, old->number, old->type); + if (strncmp (nbuf, newname, nlen)) + { + /* If this attempt to create an additional alias fails, do not bother + trying to create the all-lower case alias. We will fail and issue + a second, duplicate error message. This situation arises when the + programmer does something like: + foo .req r0 + Foo .req r1 + The second .req creates the "Foo" alias but then fails to create + the artifical FOO alias because it has already been created by the + first .req. */ + if (insert_reg_alias (nbuf, old->number, old->type) == NULL) + return TRUE; + } - for (p = nbuf; *p; p++) - *p = TOLOWER (*p); + for (p = nbuf; *p; p++) + *p = TOLOWER (*p); - if (strncmp (nbuf, newname, nlen)) - insert_reg_alias (nbuf, old->number, old->type); + if (strncmp (nbuf, newname, nlen)) + insert_reg_alias (nbuf, old->number, old->type); + } - return 1; + return TRUE; } /* Create a Neon typed/indexed register alias using directives, e.g.: @@ -2270,11 +2283,45 @@ s_unreq (int a ATTRIBUTE_UNUSED) name); else { + char * p; + char * nbuf; + hash_delete (arm_reg_hsh, name); free ((char *) reg->name); if (reg->neon) free (reg->neon); free (reg); + + /* Also locate the all upper case and all lower case versions. + Do not complain if we cannot find one or the other as it + was probably deleted above. */ + + nbuf = strdup (name); + for (p = nbuf; *p; p++) + *p = TOUPPER (*p); + reg = hash_find (arm_reg_hsh, nbuf); + if (reg) + { + hash_delete (arm_reg_hsh, nbuf); + free ((char *) reg->name); + if (reg->neon) + free (reg->neon); + free (reg); + } + + for (p = nbuf; *p; p++) + *p = TOLOWER (*p); + reg = hash_find (arm_reg_hsh, nbuf); + if (reg) + { + hash_delete (arm_reg_hsh, nbuf); + free ((char *) reg->name); + if (reg->neon) + free (reg->neon); + free (reg); + } + + free (nbuf); } } diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index b165e57..210e5f6 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2007-07-14 Nick Clifton + + * gas/arm/arm.s: Add tests for re-aliasing a previously removed + alias. + * gas/arm/arm.l: Add new expected warning message. + 2007-07-04 H.J. Lu * gas/i386/ssemmx2.d: Ignore padding. diff --git a/gas/testsuite/gas/arm/req.l b/gas/testsuite/gas/arm/req.l index 165d1d8..293db4d 100644 --- a/gas/testsuite/gas/arm/req.l +++ b/gas/testsuite/gas/arm/req.l @@ -1,3 +1,4 @@ [^:]*: Assembler messages: [^:]*:18: Error: ARM register expected -- `add foo,foo,foo' [^:]*:21: Warning: ignoring attempt to undefine built-in register 'r0' +[^:]*:41: Warning: ignoring redefinition of register alias 'FOO' diff --git a/gas/testsuite/gas/arm/req.s b/gas/testsuite/gas/arm/req.s index 341f66d..1330e75 100644 --- a/gas/testsuite/gas/arm/req.s +++ b/gas/testsuite/gas/arm/req.s @@ -19,7 +19,23 @@ test_dot_req_and_unreq: # Attempt to remove the builtin alias for r0. .unreq r0 - + # That is ignored, so this should still work. add r0, r0, r0 - + + # Now attempt to re-alias foo. There used to be a bug whereby the + # first creation of an alias called foo would also create an alias + # called FOO, but the .unreq of foo would not delete FOO. Thus a + # second attempt at aliasing foo (to something different than + # before) would fail because the assembler would complain that FOO + # already existed. + foo .req r1 + + add foo, foo, foo + + # Check that the upper case alias was also recreated. + add FOO, FOO, FOO + + # Check that a second attempt to alias foo, using a mixed case + # verison of the name, will fail. + Foo .req r2 -- 2.7.4