Message ID | 54713265.8040105@gmail.com |
---|---|
State | New |
Headers | show |
On Sun, 23 Nov 2014, Chen Gang wrote: > + gcc_assert (wi::fits_to_tree_p(value, integer_type_node)); Watch formatting: space before '(' in the wi::fits_to_tree_p call. Applies elsewhere in this patch as well. When making such an interface change, (a) you should update the comment on builtin_define_with_int_value to explain the new interface, and (b) you should check existing callers to make sure their values are indeed in range, and describe the check you did. In fact, -fabi-version=0 results in __GXX_ABI_VERSION being defined to 999999 using builtin_define_with_int_value. That's out of range of int on targets with 16-bit int. So that indicates against requiring the value to be within range of int. It might however be OK to require the value to be within range of target long. > + if (value >= 0) > + { > + sprintf (buf, "%s="HOST_WIDE_INT_PRINT_DEC"%s", > + macro, value, > + value <= HOST_INT_MAX > + ? "" > + : value <= HOST_LONG_MAX > + ? "L" : "LL"); Limits on the host's int and long are completely irrelevant here. The question is the target's int and long, not the host's - and consistency indicates checking with wi::fits_to_tree_p (value, integer_type_node) if the assertion checked with long_integer_type_node.
On 11/25/14 7:56, Joseph Myers wrote: > On Sun, 23 Nov 2014, Chen Gang wrote: > >> + gcc_assert (wi::fits_to_tree_p(value, integer_type_node)); > > Watch formatting: space before '(' in the wi::fits_to_tree_p call. > Applies elsewhere in this patch as well. > OK, thanks, I shall notice next. > When making such an interface change, (a) you should update the comment on > builtin_define_with_int_value to explain the new interface, and (b) you > should check existing callers to make sure their values are indeed in > range, and describe the check you did. > > In fact, -fabi-version=0 results in __GXX_ABI_VERSION being defined to > 999999 using builtin_define_with_int_value. That's out of range of int on > targets with 16-bit int. So that indicates against requiring the value to > be within range of int. It might however be OK to require the value to be > within range of target long. > For me, can let builtin_define_with_int_value() fit all kinds of integer values, and the assert need be: gcc_assert (wi::fits_to_tree_p (value, char_type_node) || wi::fits_to_tree_p (value, short_integer_type_node) || wi::fits_to_tree_p (value, integer_type_node) || wi::fits_to_tree_p (value, long_integer_type_node) || wi::fits_to_tree_p (value, long_long_integer_type_node)); If it really can fit all kinds of integer values, for me, the related comments of builtin_define_with_int_value() need not be changed. >> + if (value >= 0) >> + { >> + sprintf (buf, "%s="HOST_WIDE_INT_PRINT_DEC"%s", >> + macro, value, >> + value <= HOST_INT_MAX >> + ? "" >> + : value <= HOST_LONG_MAX >> + ? "L" : "LL"); > > Limits on the host's int and long are completely irrelevant here. The > question is the target's int and long, not the host's - and consistency > indicates checking with wi::fits_to_tree_p (value, integer_type_node) if > the assertion checked with long_integer_type_node. > OK, thanks. And for me, the related sprintf() should be: sprintf (buf, "%s=%s"HOST_WIDE_INT_PRINT_DEC"%s%s", macro, value < 0 ? "(" : "", value, wi::fits_to_tree_p (value, char_type_node) || wi::fits_to_tree_p (value, short_integer_type_node) || wi::fits_to_tree_p (value, integer_type_node) ? "" : wi::fits_to_tree_p (value, long_integer_type_node) ? "L" : "LL", value < 0 ? ")" : ""); Thanks.
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index c571d1b..88a717b 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -1366,15 +1366,31 @@ static void builtin_define_with_int_value (const char *macro, HOST_WIDE_INT value) { char *buf; - size_t mlen = strlen (macro); - size_t vlen = 18; - size_t extra = 2; /* space for = and NUL. */ + size_t vlen = 20; /* maximize value length: -9223372036854775807 */ + size_t extra = 6; /* space for =, NUL, (, ), and L L. */ + + gcc_assert (wi::fits_to_tree_p(value, integer_type_node)); - buf = (char *) alloca (mlen + vlen + extra); - memcpy (buf, macro, mlen); - buf[mlen] = '='; - sprintf (buf + mlen + 1, HOST_WIDE_INT_PRINT_DEC, value); + buf = (char *) alloca (strlen(macro) + vlen + extra); + if (value >= 0) + { + sprintf (buf, "%s="HOST_WIDE_INT_PRINT_DEC"%s", + macro, value, + value <= HOST_INT_MAX + ? "" + : value <= HOST_LONG_MAX + ? "L" : "LL"); + } + else + { + sprintf (buf, "%s=("HOST_WIDE_INT_PRINT_DEC"%s)", + macro, value, + value > HOST_INT_MIN + ? "" + : value > HOST_LONG_MIN + ? "L" : "LL"); + } cpp_define (parse_in, buf); } diff --git a/gcc/hwint.h b/gcc/hwint.h index fd961fd..3aecba3 100644 --- a/gcc/hwint.h +++ b/gcc/hwint.h @@ -225,6 +225,12 @@ exact_log2 (unsigned HOST_WIDE_INT x) #endif /* GCC_VERSION >= 3004 */ +#define HOST_INT_MIN (int) ((unsigned int) 1 << (HOST_BITS_PER_INT - 1)) +#define HOST_INT_MAX (~(HOST_INT_MIN)) + +#define HOST_LONG_MIN (long) ((unsigned long) 1 << (HOST_BITS_PER_LONG - 1)) +#define HOST_LONG_MAX (~(HOST_LONG_MIN)) + #define HOST_WIDE_INT_MIN (HOST_WIDE_INT) \ ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)) #define HOST_WIDE_INT_MAX (~(HOST_WIDE_INT_MIN))