On Fri, 19 Aug 2016, David Malcolm wrote:

> Please could you take this opportunity to add some examples to the
> header comment for that function, both for the common cases e.g. "f",
> and for the new suffixes; nothing in the patch body appears to document
> them.  (ideally, referencing the standard).
> 
> Also, it would be good to add some more comments to the function body. 
>  For example, in this hunk:
> 
> -  if (f + d + l + w + q > 1 || i > 1)
> +  if (f + d + l + w + q + fn + fnx > 1 || i > 1)
> 
> should it read something like :
>    /* Reject duplicate suffixes, contradictory suffixes [...] */
> 
> where "[...]" is something relating to fn + fnx, which I can't figure
> out in the absence of the standard you're referring to.

How does this seem?  I think 
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1945.pdf> was the last 
public draft of TS 18661-3 before publication.

Index: libcpp/expr.c
===================================================================
--- libcpp/expr.c       (revision 239623)
+++ libcpp/expr.c       (working copy)
@@ -86,16 +86,53 @@ static cpp_num parse_has_include (cpp_reader *, en
 
 /* Subroutine of cpp_classify_number.  S points to a float suffix of
    length LEN, possibly zero.  Returns 0 for an invalid suffix, or a
-   flag vector describing the suffix.  */
+   flag vector (of CPP_N_* bits) describing the suffix.  */
 static unsigned int
 interpret_float_suffix (cpp_reader *pfile, const uchar *s, size_t len)
 {
   size_t flags;
-  size_t f, d, l, w, q, i;
+  size_t f, d, l, w, q, i, fn, fnx, fn_bits;
 
   flags = 0;
-  f = d = l = w = q = i = 0;
+  f = d = l = w = q = i = fn = fnx = fn_bits = 0;
 
+  /* The following decimal float suffixes, from TR 24732:2009 and TS
+     18661-2:2015, are supported:
+
+     df, DF - _Decimal32.
+     dd, DD - _Decimal64.
+     dl, DL - _Decimal128.
+
+     The dN and DN suffixes for _DecimalN, and dNx and DNx for
+     _DecimalNx, defined in TS 18661-3:2015, are not supported.
+
+     Fixed-point suffixes, from TR 18037:2008, are supported.  They
+     consist of three parts, in order:
+
+     (i) An optional u or U, for unsigned types.
+
+     (ii) An optional h or H, for short types, or l or L, for long
+     types, or ll or LL, for long long types.  Use of ll or LL is a
+     GNU extension.
+
+     (iii) r or R, for _Fract types, or k or K, for _Accum types.
+
+     Otherwise the suffix is for a binary or standard floating-point
+     type.  Such a suffix, or the absence of a suffix, may be preceded
+     or followed by i, I, j or J, to indicate an imaginary number with
+     the corresponding complex type.  The following suffixes for
+     binary or standard floating-point types are supported:
+
+     f, F - float (ISO C and C++).
+     l, L - long double (ISO C and C++).
+     d, D - double, even with the FLOAT_CONST_DECIMAL64 pragma in
+           operation (from TR 24732:2009; the pragma and the suffix
+           are not included in TS 18661-2:2015).
+     w, W - machine-specific type such as __float80 (GNU extension).
+     q, Q - machine-specific type such as __float128 (GNU extension).
+     fN, FN - _FloatN (TS 18661-3:2015).
+     fNx, FNx - _FloatNx (TS 18661-3:2015).  */
+
   /* Process decimal float suffixes, which are two letters starting
      with d or D.  Order and case are significant.  */
   if (len == 2 && (*s == 'd' || *s == 'D'))
@@ -172,21 +209,65 @@ interpret_float_suffix (cpp_reader *pfile, const u
 
   /* In any remaining valid suffix, the case and order don't matter.  */
   while (len--)
-    switch (s[len])
-      {
-      case 'f': case 'F': f++; break;
-      case 'd': case 'D': d++; break;
-      case 'l': case 'L': l++; break;
-      case 'w': case 'W': w++; break;
-      case 'q': case 'Q': q++; break;
-      case 'i': case 'I':
-      case 'j': case 'J': i++; break;
-      default:
-       return 0;
-      }
+    {
+      switch (s[0])
+       {
+       case 'f': case 'F':
+         f++;
+         if (len > 0
+             && !CPP_OPTION (pfile, cplusplus)
+             && s[1] >= '1'
+             && s[1] <= '9'
+             && fn_bits == 0)
+           {
+             f--;
+             while (len > 0
+                    && s[1] >= '0'
+                    && s[1] <= '9'
+                    && fn_bits < CPP_FLOATN_MAX)
+               {
+                 fn_bits = fn_bits * 10 + (s[1] - '0');
+                 len--;
+                 s++;
+               }
+             if (len > 0 && s[1] == 'x')
+               {
+                 fnx++;
+                 len--;
+                 s++;
+               }
+             else
+               fn++;
+           }
+         break;
+       case 'd': case 'D': d++; break;
+       case 'l': case 'L': l++; break;
+       case 'w': case 'W': w++; break;
+       case 'q': case 'Q': q++; break;
+       case 'i': case 'I':
+       case 'j': case 'J': i++; break;
+       default:
+         return 0;
+       }
+      s++;
+    }
 
-  if (f + d + l + w + q > 1 || i > 1)
+  /* Reject any case of multiple suffixes specifying types, multiple
+     suffixes specifying an imaginary constant, _FloatN or _FloatNx
+     suffixes for invalid values of N, and _FloatN suffixes for values
+     of N larger than can be represented in the return value.  The
+     caller is responsible for rejecting _FloatN suffixes where
+     _FloatN is not supported on the chosen target.  */
+  if (f + d + l + w + q + fn + fnx > 1 || i > 1)
     return 0;
+  if (fn_bits > CPP_FLOATN_MAX)
+    return 0;
+  if (fnx && fn_bits != 32 && fn_bits != 64 && fn_bits != 128)
+    return 0;
+  if (fn && fn_bits != 16 && fn_bits % 32 != 0)
+    return 0;
+  if (fn && fn_bits == 96)
+    return 0;
 
   if (i && !CPP_OPTION (pfile, ext_numeric_literals))
     return 0;
@@ -199,7 +280,10 @@ interpret_float_suffix (cpp_reader *pfile, const u
             d ? CPP_N_MEDIUM :
             l ? CPP_N_LARGE :
             w ? CPP_N_MD_W :
-            q ? CPP_N_MD_Q : CPP_N_DEFAULT));
+            q ? CPP_N_MD_Q :
+            fn ? CPP_N_FLOATN | (fn_bits << CPP_FLOATN_SHIFT) :
+            fnx ? CPP_N_FLOATNX | (fn_bits << CPP_FLOATN_SHIFT) :
+            CPP_N_DEFAULT));
 }
 
 /* Return the classification flags for a float suffix.  */

-- 
Joseph S. Myers
jos...@codesourcery.com

Reply via email to