On Sat, Nov 23, 2024 at 07:26:55PM +0100, Heiko Eißfeldt wrote: > --- a/gcc/varasm.cc > +++ b/gcc/varasm.cc > @@ -993,9 +993,12 @@ decode_reg_name_and_count (const char *asmspec, int > *pnregs) > break; > if (asmspec[0] != 0 && i < 0) > { > - i = atoi (asmspec); > - if (i < FIRST_PSEUDO_REGISTER && i >= 0 && reg_names[i][0]) > - return i; > + char *pend{};
Why the {} strtol will write to pend no matter what, so it doesn't need to be cleared. > + errno = 0; > + long j = strtol (asmspec, &pend, 10); > + if (errno != ERANGE && j <= INT_MAX > + && j < FIRST_PSEUDO_REGISTER && j >= 0 && reg_names[j][0]) > + return j; If all conditions don't fit on a single line, all should be written on separate lines, so if (errno != ERANGE && ... && ...) I'm not sure what is the point of the j <= INT_MAX check, FIRST_PSEUDO_REGISTER will surely be smaller than INT_MAX on all targets. Furthermore, when strtol is used, I wonder if that for (i = strlen (asmspec) - 1; i >= 0; i--) if (! ISDIGIT (asmspec[i])) break; isn't just a waste of time, if it wouldn't be enough to test that ISDIGIT (asmspec[0]) and *pend == '\0' after the strtol call (if not, it should fallthrough to the name matching rather than just return -2. So - for (i = strlen (asmspec) - 1; i >= 0; i--) - if (! ISDIGIT (asmspec[i])) - break; - if (asmspec[0] != 0 && i < 0) - { - i = atoi (asmspec); - if (i < FIRST_PSEUDO_REGISTER && i >= 0 && reg_names[i][0]) - return i; - else - return -2; - } + if (ISDIGIT (asmspec[0])) + { + char *pend; + errno = 0; + unsigned long j = strtoul (asmspec, &pend, 10); + if (*pend == '\0') + { + if (errno != ERANGE + && j < FIRST_PSEUDO_REGISTER + && reg_names[j][0]) + return j; + else + return -2; + } + } Jakub