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++)

Reply via email to