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."