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

Reply via email to