On Thu, Nov 28, 2024 at 08:15:08PM +0100, Heiko Eißfeldt wrote: > > There are three important parts missing. > > > > I don't see you in MAINTAINERS file, so you need to decide if you assign > > copyright to FSF or submit this under DCO. > I wonder if it is ok to add myself to MAINTAINERS file?
No. That happens only if/when one gets account on sourceware, as a first commit under the new rights. And account is given only after a few earlier contributions where somebody commits it for you. > --- a/gcc/ChangeLog > +++ b/gcc/ChangeLog > @@ -1,3 +1,16 @@ > +2024-11-28 Heiko Eißfeldt <he...@hexco.de> > + > + PR middle-end/114540 > + * varasm.cc (decode_reg_name_and_count): Use strtoul instead of atoi > + and simplify verification the whole asmspec contains just decimal > + digits. > + > + * gcc.dg/pr114540.c: New test. > + > + Signed-off-by: Heiko Eißfeldt <he...@hexco.de> > + Co-authored-by: Jakub Jelinek <ja...@redhat.com> We don't put the ChangeLog changes into the patch being committed, that would result in patch conflicts all the time, so the ChangeLog entry is written in the plaintext at the end of the commit message instead and a daily script processes commits and populates ChangeLog files. > + asm("":::"2147483647&"); /* INT_MAX + garbage char { dg-error > "unknown register name" } */ I chose to use 4& instead of 2147483647& because for 2147483647 it would be rejected anyway, no matter whether there is garbage after it or not. And I've added one case with garbage in between. > + > + register int a asm("2147483648"); /* INT_MAX + 1 { > dg-error "invalid register name for" } */ > + register int b asm("4294967296"); /* UINT_MAX + 1 { > dg-error "invalid register name for" } */ > + register int c asm("18446744073709551616"); /* ULONG_MAX + 1 { > dg-error "invalid register name for" } */ > + register int d asm("9223372036854775808"); /* LONG_MAX + 1 { > dg-error "invalid register name for" } */ > + register int e asm("9223372036854775807"); /* LONG_MAX { > dg-error "invalid register name for" } */ > + register int f asm("2147483647"); /* INT_MAX { > dg-error "invalid register name for" } */ > + register int g asm("2147483647&"); /* INT_MAX + garbage char { > dg-error "invalid register name for" } */ > + register int h asm("0"); /* real reg */ This one doesn't really work on all targets, e.g. on hppa-linux I get error: the register specified for ‘h’ is not general enough to be used as a register variable So, I've guarded the 0 cases with #if check for a couple of targets which handle register 0 well. Here is what I've committed in https://gcc.gnu.org/r15-5877 for you: replace atoi with strtoul in varasm.cc (decode_reg_name_and_count) [PR114540] The function uses atoi, which can silently return valid numbers even for some too large numbers in the string. Furthermore, the verification that all the characters in asmspec are decimal digits can be simplified when using strotoul, we can check just the first digit and whether the end pointer points to '\0'. 2024-12-03 Heiko Eißfeldt <he...@hexco.de> PR middle-end/114540 * varasm.cc (decode_reg_name_and_count): Use strtoul instead of atoi and simplify verification that the whole asmspec contains just decimal digits. * gcc.dg/pr114540.c: New test. Signed-off-by: Heiko Eißfeldt <he...@hexco.de> Co-authored-by: Jakub Jelinek <ja...@redhat.com> --- gcc/varasm.cc.jj 2024-11-28 11:42:02.289812658 +0100 +++ gcc/varasm.cc 2024-12-02 19:49:40.602841404 +0100 @@ -990,16 +990,21 @@ decode_reg_name_and_count (const char *a asmspec = strip_reg_name (asmspec); /* Allow a decimal number as a "register name". */ - for (i = strlen (asmspec) - 1; i >= 0; i--) - if (! ISDIGIT (asmspec[i])) - break; - if (asmspec[0] != 0 && i < 0) + if (ISDIGIT (asmspec[0])) { - i = atoi (asmspec); - if (i < FIRST_PSEUDO_REGISTER && i >= 0 && reg_names[i][0]) - return i; - else - return -2; + char *pend; + errno = 0; + unsigned long j = strtoul (asmspec, &pend, 10); + if (*pend == '\0') + { + static_assert (FIRST_PSEUDO_REGISTER <= INT_MAX, ""); + if (errno != ERANGE + && j < FIRST_PSEUDO_REGISTER + && reg_names[j][0]) + return j; + else + return -2; + } } for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) --- gcc/testsuite/gcc.dg/pr114540.c.jj 2024-12-02 19:49:40.603841390 +0100 +++ gcc/testsuite/gcc.dg/pr114540.c 2024-12-02 19:58:29.021425513 +0100 @@ -0,0 +1,31 @@ +/* PR middle-end/114540 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void +foo () +{ + asm ("" : : : "2147483648"); /* { dg-error "unknown register name" } */ + asm ("" : : : "4294967296"); /* { dg-error "unknown register name" } */ + asm ("" : : : "18446744073709551616"); /* { dg-error "unknown register name" } */ + asm ("" : : : "9223372036854775808"); /* { dg-error "unknown register name" } */ + asm ("" : : : "9223372036854775807"); /* { dg-error "unknown register name" } */ + asm ("" : : : "2147483647"); /* { dg-error "unknown register name" } */ + asm ("" : : : "4&"); /* { dg-error "unknown register name" } */ + asm ("" : : : "1'0"); /* { dg-error "unknown register name" } */ +#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__s390__) || defined(__aarch64__) || defined(__arm__) + asm ("" : : : "0"); +#endif + + register int a asm("2147483648"); /* { dg-error "invalid register name for" } */ + register int b asm("4294967296"); /* { dg-error "invalid register name for" } */ + register int c asm("18446744073709551616"); /* { dg-error "invalid register name for" } */ + register int d asm("9223372036854775808"); /* { dg-error "invalid register name for" } */ + register int e asm("9223372036854775807"); /* { dg-error "invalid register name for" } */ + register int f asm("2147483647"); /* { dg-error "invalid register name for" } */ + register int g asm("4&"); /* { dg-error "invalid register name for" } */ + register int h asm("1'0"); /* { dg-error "invalid register name for" } */ +#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__s390__) || defined(__aarch64__) || defined(__arm__) + register int i asm("0"); +#endif +} Jakub