aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Eißfeldt <heiko@hexco.de>2024-12-03 09:47:59 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2024-12-03 09:47:59 +0100
commit4acab372d31a9fe9184ccc247780940821cda367 (patch)
tree1a44081e0cc9eece96ef5facd8918cd2b3d07bb1
parentbe8d1a358e3abc50c14a1d7b1cfee82fe6f6aa3c (diff)
downloadgcc-4acab372d31a9fe9184ccc247780940821cda367.zip
gcc-4acab372d31a9fe9184ccc247780940821cda367.tar.gz
gcc-4acab372d31a9fe9184ccc247780940821cda367.tar.bz2
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 <heiko@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 <heiko@hexco.de> Co-authored-by: Jakub Jelinek <jakub@redhat.com>
-rw-r--r--gcc/testsuite/gcc.dg/pr114540.c31
-rw-r--r--gcc/varasm.cc23
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 0000000..e59dffa
--- /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 be11123..261621a 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++)