Thanks for your feedback!

On 11/23/24 11:02 PM, Jakub Jelinek wrote:
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.
I agree, but was hesitant to change more than the offending atoi() part.
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')
+           {
I would then add a

+ static_assert ( FIRST_PSEUDO_REGISTER <= INT_MAX );

here to 'document' the underlying assumption. I hope that is ok.

Would it make sense to have a nullptr check for asmspec at the
beginning, too?

+             if (errno != ERANGE
+                 && j < FIRST_PSEUDO_REGISTER
+                 && reg_names[j][0])
+               return j;
+             else
+               return -2;
+           }
+       }

        Jakub

diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index dd67dd441c0..3e3e4bc5b42 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -988,16 +988,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