On Jul 18 2021, Segher Boessenkool wrote:

> On Sat, Jul 17, 2021 at 03:13:59PM -0700, Andrew Pinski wrote:
>> On Sat, Jul 17, 2021 at 2:31 PM Segher Boessenkool
>> <seg...@kernel.crashing.org> wrote:
>> > On Fri, Jul 16, 2021 at 11:35:25AM -0700, apinski--- via Gcc-patches wrote:
>> > > --- a/gcc/c-family/c-common.c
>> > > +++ b/gcc/c-family/c-common.c
>> > > @@ -5799,7 +5799,7 @@ parse_optimize_options (tree args, bool attr_p)
>> > >
>> > >        if (TREE_CODE (value) == INTEGER_CST)
>> > >       {
>> > > -       char buffer[20];
>> > > +       char buffer[HOST_BITS_PER_LONG / 3 + 4];
>> > >         sprintf (buffer, "-O%ld", (long) TREE_INT_CST_LOW (value));
>> > >         vec_safe_push (optimize_args, ggc_strdup (buffer));
>> > >       }
>> >
>> > This calculation is correct, assuming "value" is non-negative.  You can
>> > easily avoid all of that though:
>> 
>> Actually it is still correct even for negative values because we are
>> adding 4 rather than 3 to make sure there is enough room for the sign
>> character.
>
> Say your longs have only two bits, one sign and one value (so it is
> {-2, -1, 0, 1}).  There you get  char buffer[4]  although you need 5
> here if you care about negative numbers: '-', 'O', '-', '1', 0.
>
> But longs are at least 32 bits, of course.  And 14 chars is (just)
> enough, because you divide by only 3 now (instead of {}^2 log 10, or
> 3.32 as before), giving some leeway.
>
> (n/3+4 also fails for longs of sizes 5, 8, or 11 bits, but no more).

/* Bound on length of the string representing an unsigned integer
   value representable in B bits.  log10 (2.0) < 146/485.  The
   smallest value of B where this bound is not tight is 2621.  */
#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)

/* Bound on length of the string representing an integer type or expression T.
   Subtract 1 for the sign bit if T is signed, and then add 1 more for
   a minus sign if needed.

   Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 1 when its argument is
   unsigned, this macro may overestimate the true bound by one byte when
   applied to unsigned types of size 2, 4, 16, ... bytes.  */
#define INT_STRLEN_BOUND(t)                                     \
  (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - _GL_SIGNED_TYPE_OR_EXPR (t)) \
   + _GL_SIGNED_TYPE_OR_EXPR (t))

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

Reply via email to