Implementing wbN suffix for literals (#119058)

2025-06-28 Thread Alejandro Colomar via Gcc
Hi!

I'm trying to implement the wbN suffix as per the extension proposed in
.

I think I've got most of it, but need to know how I can parse an integer
that is in the middle of a token.  That is, I have a token that could be
0x1234wb567u, and need to have a subtoken that starts right after the
wb (or WB), so '567u', which I can pass to cpp_interpret_integer().  Is
there any function to generate such a subtoken, or do I need to do it
manually?

Below is the draft with which I'm working.


Have a lovely night!
Alex

---
diff --git i/gcc/c-family/c-lex.cc w/gcc/c-family/c-lex.cc
index 8e182938938..32cf253df8d 100644
--- i/gcc/c-family/c-lex.cc
+++ w/gcc/c-family/c-lex.cc
@@ -930,7 +930,7 @@ interpret_integer (const cpp_token *token, unsigned int 
flags,
 
   *overflow = OT_NONE;
 
-  if (UNLIKELY (flags & CPP_N_BITINT))
+  if (UNLIKELY (flags & (CPP_N_BITINT | CPP_N_BITINT_N)))
 {
   unsigned int suffix_len = 2 + ((flags & CPP_N_UNSIGNED) ? 1 : 0);
   int max_bits_per_digit = 4; // ceil (log2 (10))
@@ -1070,11 +1070,29 @@ interpret_integer (const cpp_token *token, unsigned int 
flags,
  while (1);
}
 
-  prec = wi::min_precision (wval, UNSIGNED);
-  if (prec == 0)
-   prec = 1;
-  if ((flags & CPP_N_UNSIGNED) == 0)
-   ++prec;
+  if (flags & CPP_N_BITINT)
+   {
+ prec = wi::min_precision (wval, UNSIGNED);
+ if (prec == 0)
+   prec = 1;
+ if ((flags & CPP_N_UNSIGNED) == 0)
+   ++prec;
+   }
+  else
+   {
+ /* (flags & CPP_N_BITINT_N) */
+ /* TODO: Parse decimal digits after wb/WB.  */
+ /* Need a subtoken that starts right after wb/WB. */
+ cpp_token subtok;
+ subtok = subtoken(token, "wb") ?: subtoken(token, "WB");
+ integer = cpp_interpret_integer (parse_in, subtoken,
+  CPP_N_DECIMAL | CPP_N_UNSIGNED);
+ ival[0] = integer.low;
+ ival[1] = integer.high;
+ ival[2] = 0;
+ prec = widest_int::from_array (ival, 3);
+   }
+
   if (prec > bitint_maxwidth)
{
bitint_overflow:
diff --git i/libcpp/expr.cc w/libcpp/expr.cc
index 685233797c8..a8a715b1364 100644
--- i/libcpp/expr.cc
+++ w/libcpp/expr.cc
@@ -338,7 +338,8 @@ static unsigned int
 interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len)
 {
   size_t orig_len = len;
-  size_t u, l, i, z, wb;
+  size_t u, l, i, z, wb, wbN;
+  size_t wbN_bits;
 
   u = l = i = z = wb = 0;
 
@@ -366,11 +367,40 @@ interpret_int_suffix (cpp_reader *pfile, const uchar *s, 
size_t len)
wb++;
len--;
break;
+  case 0:
+  case 1:
+  case 2:
+  case 3:
+  case 4:
+  case 5:
+  case 6:
+  case 7:
+  case 8:
+  case 9:
+   {
+ size_t dd;
+
+ for (dd = 1; dd < len && ISDIGIT(s[len - dd]); dd++)
+   continue;
+ /* Octals and 0 not allowed.  */
+ if (s[len - dd + 1] == '0')
+   return 0;
+ len -= dd;
+ if (len == 0)
+   return 0;
+ len--;
+ wbN++;
+ if (s[len] == 'w' && s[len + 1] == 'b')
+   break;
+ if (s[len] == 'W' && s[len + 1] == 'B')
+   break;
+ return 0;
+   }
   default:
return 0;
   }
 
-  if (l > 2 || u > 1 || i > 1 || z > 1 || wb > 1)
+  if (l > 2 || u > 1 || i > 1 || z > 1 || wb > 1 || wbN > 1)
 return 0;
 
   if (z)
@@ -389,6 +419,14 @@ interpret_int_suffix (cpp_reader *pfile, const uchar *s, 
size_t len)
return 0;
 }
 
+  if (wbN)
+{
+  if (CPP_OPTION (pfile, cplusplus))
+   return 0;
+  if (l > 0 || i > 0 || z > 0 || wb > 0)
+   return 0;
+}
+
   if (i)
 {
   if (!CPP_OPTION (pfile, ext_numeric_literals))
@@ -408,7 +446,8 @@ interpret_int_suffix (cpp_reader *pfile, const uchar *s, 
size_t len)
  | ((l == 0) ? CPP_N_SMALL
 : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE)
  | (z ? CPP_N_SIZE_T : 0)
- | (wb ? CPP_N_BITINT : 0));
+ | (wb ? CPP_N_BITINT : 0)
+ | (wbN ? CPP_N_BITINT_N : 0));
 }
 
 /* Return the classification flags for an int suffix.  */
diff --git i/libcpp/include/cpplib.h w/libcpp/include/cpplib.h
index e73f77e67d8..d76aeec77f4 100644
--- i/libcpp/include/cpplib.h
+++ w/libcpp/include/cpplib.h
@@ -1363,6 +1363,7 @@ struct cpp_num
 #define CPP_N_SIZE_T   0x200 /* C++23 size_t literal.  */
 #define CPP_N_BFLOAT16 0x400 /* std::bfloat16_t type.  */
 #define CPP_N_BITINT   0x800 /* C23 _BitInt literal.  */
+#define CPP_N_BITINT_N 0x1000 /* C2y _BitInt(N) literal.  */
 
 #define CPP_N_WIDTH_FLOATN_NX  0xF000 /* _FloatN / _FloatNx value
  of N, divided by 16.  */


-- 



signature.asc
Description: PGP signature


non-TARGET_SUPPORTS_WIDE_INT targets

2025-06-28 Thread Andrew Pinski (QUIC) via Gcc
Does it makes sense to try to convert and/or depreciate targets that don't have 
TARGET_SUPPORTS_WIDE_INT set to 1? TARGET_SUPPORTS_WIDE_INT has been around 
since 2013 
(https://inbox.sourceware.org/gcc-patches/52a23c51.8040...@naturalbridge.com/).
At least I think we should require new targets have TARGET_SUPPORTS_WIDE_INT 
set.

The following targets have TARGET_SUPPORTS_WIDE_INT set to 1:
aarch64, alpha, arm, i386, loongarch, nvptx, pru, riscv, rs6000, s390, sparc

If agreed that we should convert the rest, I will create a Bugzilla for each 
target.
It does seem like we should be more aggressive on these kind of cleanups rather 
than keeping around the 2 paths around.

Thanks,
Andrew Pinski


gcc-15-20250628 is now available

2025-06-28 Thread GCC Administrator via Gcc
Snapshot gcc-15-20250628 is now available on
  https://gcc.gnu.org/pub/gcc/snapshots/15-20250628/
and on various mirrors, see https://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 15 git branch
with the following options: git://gcc.gnu.org/git/gcc.git branch 
releases/gcc-15 revision 06a26f4d643a5d045d893cd443425b13bd3d1b4b

You'll find:

 gcc-15-20250628.tar.xz   Complete GCC

  SHA256=23491ef6d0251fefc2f28c9c0b81d817c4962f0dad7018fbddf7aa2a1de3a769
  SHA1=e3e89f6dcee500097990281bf1d21e45e672f725

Diffs from 15-20250621 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-15
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.