On Thu, 12 Jan 2017, Richard Biener wrote: > On Wed, 11 Jan 2017, Joseph Myers wrote: > > > On Wed, 11 Jan 2017, Richard Biener wrote: > > > > > As you can see I adjusted dumping of pointer constants (we can't > > > parse the B suffix and large unsigned numbers get a warning so > > > add 'U'). There's the general issue that we dump > > > > > > short x; > > > x = 1; > > > > > > and then lex the '1' as type int and there's no suffixes for integer > > > types smaller than int which means we can't write those constants > > > type correct :/ Suggestions welcome (currently we ICE with type > > > mismatches in those cases, we can avoid that by auto-fixing during > > > parsing but I'd like to be explicit somehow). > > > > You could always dump as ((short) 1); that's valid C. > > Indeed. It makes parsing a little more awkward as (short) 1 is not > a postfix expression. > > I suppose adding additional suffixes for char/short conditional on > -fgimple would be another way (either via setting user_literals option > or teaching libcpp about those itself). 's' and 'ss' (CPP_N_SMALL_SMALL > and CPP_N_SMALL_SMALL_SMALL?) would be my choice... > > I'll give the (short) 1 parsing a try though to see how awkward it > really gets.
Ok, doesn't look a good way to go. Apart from making it difficult to handle in the parser you can't distinguish a conversion from an integer literal and a short literal for short s; s_1 = (short) 1; I've pasted below what I came up with for 's' and 'ss'. It's just a prototype as it doens't handle larger literals and bit-precision literals we have in the IL. So I suppose user_literals and interpreting uN/sN with N being the actual precision looks better here? Likewise we need something for pointer literals (where we might need to encode the address-space as well...). A simple pN would work for a start I suppose. It looks like we currently have no way to write __int128 literals in C? __int128 x = 0xffffeeeeffffeeeeffffeeeeffffeeee; yields t.c:1:14: warning: integer constant is too large for its type __int128 x = 0xffffeeeeffffeeeeffffeeeeffffeeee; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ and truncation to 64bits which looks like a limitation of cpp_num. I'd like to solve the issue of short and char literals for GIMPLE testcases for GCC 6, any preference on the solution? There's also bool literals (1-bit precision integers in GIMPLE...), for those using _True and _False might be a workaround. Though 1u1 and 0u1 would work for those as well. Thanks, Richard. 2017-01-12 Richard Biener <rguent...@suse.de> c-family/ * c-lex.c (narrowest_unsigned_type): Handle CPP_N_TINY and CPP_N_MINISCULE. (narrowest_signed_type): Likewise. libcpp/ * include/cpplib.h (CPP_N_TINY): New. (CPP_N_MINISCULE): Likewise. * expr.c (interpret_int_suffix): Map 's' to CPP_N_TINY and 'ss' to CPP_N_MINISCULE if ext_numeric_literals. * tree-pretty-print.c (dump_generic_node): Dump integer constant type suffixes with -gimple. Index: gcc/c-family/c-lex.c =================================================================== --- gcc/c-family/c-lex.c (revision 244350) +++ gcc/c-family/c-lex.c (working copy) @@ -641,7 +641,11 @@ narrowest_unsigned_type (const widest_in { int itk; - if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) + if ((flags & CPP_N_WIDTH) == CPP_N_MINISCULE) + itk = itk_unsigned_char; + else if ((flags & CPP_N_WIDTH) == CPP_N_TINY) + itk = itk_unsigned_short; + else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) itk = itk_unsigned_int; else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM) itk = itk_unsigned_long; @@ -669,7 +673,11 @@ narrowest_signed_type (const widest_int { int itk; - if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) + if ((flags & CPP_N_WIDTH) == CPP_N_MINISCULE) + itk = itk_signed_char; + else if ((flags & CPP_N_WIDTH) == CPP_N_TINY) + itk = itk_short; + else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL) itk = itk_int; else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM) itk = itk_long; Index: gcc/tree-pretty-print.c =================================================================== --- gcc/tree-pretty-print.c (revision 244350) +++ gcc/tree-pretty-print.c (working copy) @@ -1710,6 +1710,28 @@ dump_generic_node (pretty_printer *pp, t print_hex (val, pp_buffer (pp)->digit_buffer); pp_string (pp, pp_buffer (pp)->digit_buffer); } + if (flags & TDF_GIMPLE) + { + if (TYPE_UNSIGNED (TREE_TYPE (node))) + pp_character (pp, 'u'); + if (POINTER_TYPE_P (TREE_TYPE (node))) + ; + else if (TYPE_PRECISION (TREE_TYPE (node)) + == TYPE_PRECISION (unsigned_char_type_node)) + pp_string (pp, "ss"); + else if (TYPE_PRECISION (TREE_TYPE (node)) + == TYPE_PRECISION (short_unsigned_type_node)) + pp_character (pp, 's'); + else if (TYPE_PRECISION (TREE_TYPE (node)) + == TYPE_PRECISION (unsigned_type_node)) + ; + else if (TYPE_PRECISION (TREE_TYPE (node)) + == TYPE_PRECISION (long_unsigned_type_node)) + pp_character (pp, 'l'); + else if (TYPE_PRECISION (TREE_TYPE (node)) + == TYPE_PRECISION (long_long_unsigned_type_node)) + pp_string (pp, "ll"); + } if (TREE_OVERFLOW (node)) pp_string (pp, "(OVF)"); break; Index: libcpp/expr.c =================================================================== --- libcpp/expr.c (revision 244350) +++ libcpp/expr.c (working copy) @@ -293,40 +293,46 @@ cpp_interpret_float_suffix (cpp_reader * return interpret_float_suffix (pfile, (const unsigned char *)s, len); } -/* Subroutine of cpp_classify_number. S points to an integer suffix +/* Subroutine of cpp_classify_number. SUFF points to an integer suffix of length LEN, possibly zero. Returns 0 for an invalid suffix, or a flag vector describing the suffix. */ static unsigned int -interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len) +interpret_int_suffix (cpp_reader *pfile, const uchar *suff, size_t len) { - size_t u, l, i; + size_t u, l, i, s; - u = l = i = 0; + u = l = i = s = 0; while (len--) - switch (s[len]) + switch (suff[len]) { case 'u': case 'U': u++; break; case 'i': case 'I': case 'j': case 'J': i++; break; case 'l': case 'L': l++; /* If there are two Ls, they must be adjacent and the same case. */ - if (l == 2 && s[len] != s[len + 1]) + if (l == 2 && suff[len] != suff[len + 1]) + return 0; + break; + case 's': case 'S': s++; + /* If there are two Ss, they must be adjacent and the same case. */ + if (s == 2 && suff[len] != suff[len + 1]) return 0; break; default: return 0; } - if (l > 2 || u > 1 || i > 1) + if (l > 2 || s > 2 || (l > 0 && s > 0) || u > 1 || i > 1) return 0; - if (i && !CPP_OPTION (pfile, ext_numeric_literals)) + if ((i || s) && !CPP_OPTION (pfile, ext_numeric_literals)) return 0; return ((i ? CPP_N_IMAGINARY : 0) | (u ? CPP_N_UNSIGNED : 0) - | ((l == 0) ? CPP_N_SMALL + | ((l == 0) ? (s == 0 ? CPP_N_SMALL + : (s == 1) ? CPP_N_TINY : CPP_N_MINISCULE) : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE)); } Index: libcpp/include/cpplib.h =================================================================== --- libcpp/include/cpplib.h (revision 244350) +++ libcpp/include/cpplib.h (working copy) @@ -947,6 +947,8 @@ struct cpp_num #define CPP_N_MEDIUM 0x0020 /* long, double, long _Fract/_Accum. */ #define CPP_N_LARGE 0x0040 /* long long, long double, long long _Fract/Accum. */ +#define CPP_N_TINY 0x0080 /* short. */ +#define CPP_N_MINISCULE 0x0090 /* char. */ #define CPP_N_WIDTH_MD 0xF0000 /* machine defined. */ #define CPP_N_MD_W 0x10000