https://gcc.gnu.org/g:4acab372d31a9fe9184ccc247780940821cda367
commit r15-5877-g4acab372d31a9fe9184ccc247780940821cda367 Author: Heiko Eißfeldt <he...@hexco.de> Date: Tue Dec 3 09:47:59 2024 +0100 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> Diff: --- gcc/testsuite/gcc.dg/pr114540.c | 31 +++++++++++++++++++++++++++++++ gcc/varasm.cc | 23 ++++++++++++++--------- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr114540.c b/gcc/testsuite/gcc.dg/pr114540.c new file mode 100644 index 000000000000..e59dffa1e90c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr114540.c @@ -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 +} diff --git a/gcc/varasm.cc b/gcc/varasm.cc index be11123180cd..261621a18c73 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -990,16 +990,21 @@ decode_reg_name_and_count (const char *asmspec, int *pnregs) 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++)