On 12/12/2018 16:45, Luc Van Oostenryck wrote: > This allows to have a single function to output the > size, the type, the maximal value, ... > > Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> > --- > lib.c | 61 ++++++++++++++++++++------------ > validation/preprocessor/predef.c | 3 ++ > 2 files changed, 41 insertions(+), 23 deletions(-) > > diff --git a/lib.c b/lib.c > index ad583da93..89126fb57 100644 > --- a/lib.c > +++ b/lib.c > @@ -1145,6 +1145,15 @@ static char **handle_switch(char *arg, char **next) > return next; > } > > +#define PTYPE_SIZEOF (1U << 0) > +#define PTYPE_T (1U << 1) > +#define PTYPE_MAX (1U << 2) > +#define PTYPE_MIN (1U << 3) > +#define PTYPE_WIDTH (1U << 4) > +#define PTYPE_TYPE (1U << 5) > +#define PTYPE_ALL (PTYPE_MAX|PTYPE_SIZEOF|PTYPE_WIDTH) > +#define PTYPE_ALL_T (PTYPE_MAX|PTYPE_SIZEOF|PTYPE_WIDTH|PTYPE_T) > + > static void predefined_sizeof(const char *name, const char *suffix, unsigned bits) > { > char buf[32]; > @@ -1163,26 +1172,37 @@ static void predefined_width(const char *name, unsigned bits) > > static void predefined_max(const char *name, const char *suffix, unsigned bits) > { > - unsigned long long max = bits_mask(bits - 1); > + unsigned long long max = bits_mask(bits); > char buf[32]; Hmm, this can't possibly be right, unless ... > > snprintf(buf, sizeof(buf), "__%s_MAX__", name); > predefine(buf, 1, "%#llx%s", max, suffix); > } > > -static void predefined_type_size(const char *name, const char *suffix, unsigned bits) > -{ > - predefined_max(name, suffix, bits); > - predefined_sizeof(name, "", bits); > - predefined_width(name, bits); > -} > - > static void predefined_type(const char *name, struct symbol *type) > { > const char *typename = builtin_typename(type); > add_pre_buffer("#weak_define __%s_TYPE__ %s\n", name, typename); > } > > +static void predefined_ctype(const char *name, struct symbol *type, int flags) > +{ > + unsigned bits = type->bit_size; > + > + if (flags & PTYPE_SIZEOF) { > + const char *suffix = (flags & PTYPE_T) ? "_T" : ""; > + predefined_sizeof(name, suffix, bits); > + } > + if (flags & PTYPE_MAX) { > + const char *suffix = builtin_type_suffix(type); > + predefined_max(name, suffix, bits - is_signed_type(type)); ... you subtract one from the bits parameter for a signed type! Hmm, I'm not sure I like this. I had expected something like: static void predefined_max(const char *name, struct symbol *type) { unsigned bits = type->bit_size; const char *suffix = builtin_type_suffix(type); unsigned long long max; char buf[32]; if (is_signed_type(type)) bits = bits - 1; max = bits_mask(bits); snprintf(buf, sizeof(buf), "__%s_MAX__", name); predefine(buf, 1, "%#llx%s", max, suffix); } ... or something like that. (but it is your call ;-) ). BTW, I haven't finished testing (something else came up), but some platforms are using the 'long' type for wchar_t. (Also, I suspect some of the tests won't work ...) Oh, also, there seems to be a discrepancy in the size of 'long double'. [I will try to finish testing tomorrow] Thanks! ATB, Ramsay Jones > + } > + if (flags & PTYPE_TYPE) > + predefined_type(name, type); > + if (flags & PTYPE_WIDTH) > + predefined_width(name, bits); > +} > + > static void predefined_macros(void) > { > predefine("__CHECKER__", 0, "1"); > @@ -1224,27 +1244,24 @@ static void predefined_macros(void) > break; > } > > - predefined_sizeof("SHORT", "", bits_in_short); > - predefined_max("SHRT", "", bits_in_short); > - predefined_width("SHRT", bits_in_short); > - predefined_max("SCHAR", "", bits_in_char); > - predefined_width("SCHAR", bits_in_char); > predefined_sizeof("WCHAR", "_T", bits_in_wchar); > predefined_max("WCHAR", "", bits_in_wchar); > predefined_width("WCHAR", bits_in_wchar); > predefine("__CHAR_BIT__", 1, "%d", bits_in_char); > > - predefined_type_size("INT", "", bits_in_int); > - predefined_type_size("LONG", "L", bits_in_long); > - predefined_type_size("LONG_LONG", "LL", bits_in_longlong); > + predefined_ctype("SHORT", &short_ctype, PTYPE_SIZEOF); > + predefined_ctype("SHRT", &short_ctype, PTYPE_MAX|PTYPE_WIDTH); > + predefined_ctype("SCHAR", &char_ctype, PTYPE_MAX|PTYPE_WIDTH); > + > + predefined_ctype("INT", &int_ctype, PTYPE_ALL); > + predefined_ctype("LONG", &long_ctype, PTYPE_ALL); > + predefined_ctype("LONG_LONG", &llong_ctype, PTYPE_ALL); > > predefined_sizeof("INT128", "", 128); > > - predefined_sizeof("SIZE", "_T", bits_in_pointer); > - predefined_width( "SIZE", bits_in_pointer); > - predefined_sizeof("PTRDIFF", "_T", bits_in_pointer); > - predefined_width( "PTRDIFF", bits_in_pointer); > - predefined_sizeof("POINTER", "", bits_in_pointer); > + predefined_ctype("PTRDIFF", ssize_t_ctype, PTYPE_ALL_T|PTYPE_TYPE); > + predefined_ctype("SIZE", size_t_ctype, PTYPE_ALL_T|PTYPE_TYPE); > + predefined_ctype("POINTER", &ptr_ctype, PTYPE_SIZEOF); > > predefined_sizeof("FLOAT", "", bits_in_float); > predefined_sizeof("DOUBLE", "", bits_in_double); > @@ -1276,8 +1293,6 @@ static void create_builtin_stream(void) > // Temporary hack > add_pre_buffer("#define _Pragma(x)\n"); > > - predefined_type("SIZE", size_t_ctype); > - > /* add the multiarch include directories, if any */ > if (multiarch_dir && *multiarch_dir) { > add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir); > diff --git a/validation/preprocessor/predef.c b/validation/preprocessor/predef.c > index ccb5d3619..298bdd93c 100644 > --- a/validation/preprocessor/predef.c > +++ b/validation/preprocessor/predef.c > @@ -17,6 +17,8 @@ int test(void) > TEST_SMAX(INT, int); > TEST_SMAX(LONG, long); > TEST_SMAX(LONG_LONG, long long); > + TEST_SMAX(PTRDIFF, __PTRDIFF_TYPE__); > + TEST_UMAX(SIZE, __SIZE_TYPE__); > > #define TEST_SIZEOF(X, T) if (__SIZEOF_ ## X ## __ != sizeof(T)) return 1 > TEST_SIZEOF(SHORT, short); > @@ -24,6 +26,7 @@ int test(void) > TEST_SIZEOF(LONG, long); > TEST_SIZEOF(LONG_LONG, long long); > TEST_SIZEOF(INT128, __int128); > + TEST_SIZEOF(PTRDIFF_T, __PTRDIFF_TYPE__); > TEST_SIZEOF(SIZE_T, __SIZE_TYPE__); > TEST_SIZEOF(POINTER, void*); > TEST_SIZEOF(FLOAT, float); >