From e16dee6df363b37a6e2f4cadc6fc242b541dbbc5 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Tue, 19 Sep 2023 09:50:35 +0200
Subject: [PATCH] small _BitInt tweaks

I think it is undesirable when being asked for signed_type_for
of unsigned _BitInt(1) (which is valid) to get signed _BitInt(1) (which is
invalid, the standard only allows signed _BitInt(2) and larger), so the
patch returns 1-bit signed INTEGER_TYPE for those cases.
Furthermore it asserts in build_bitint_type that nothing attempts to create
signed _BitInt(0), unsigned _BitInt(0) or signed _BitInt(1) types.

2023-09-18  Jakub Jelinek  <jakub@redhat.com>

gcc/
	* tree.cc (build_bitint_type): Assert precision is not 0, or
	for signed types 1.
	(signed_or_unsigned_type_for): Return INTEGER_TYPE for signed variant
	of unsigned _BitInt(1).
gcc/c-family/
	* c-common.cc (c_common_signed_or_unsigned_type): Return INTEGER_TYPE
	for signed variant of unsigned _BitInt(1).
---
 gcc/c-family/c-common.cc | 4 +++-
 gcc/tree.cc              | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 73e739c503dd..aae572600979 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -2739,7 +2739,9 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
       || TYPE_UNSIGNED (type) == unsignedp)
     return type;
 
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (TREE_CODE (type) == BITINT_TYPE
+      /* signed _BitInt(1) is invalid, avoid creating that.  */
+      && (unsignedp || TYPE_PRECISION (type) > 1))
     return build_bitint_type (TYPE_PRECISION (type), unsignedp);
 
 #define TYPE_OK(node)							    \
diff --git a/gcc/tree.cc b/gcc/tree.cc
index b34d75f8c85c..8a8d6d5091a4 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -7179,6 +7179,8 @@ build_bitint_type (unsigned HOST_WIDE_INT precision, int unsignedp)
 {
   tree itype, ret;
 
+  gcc_checking_assert (precision >= 1 + !unsignedp);
+
   if (unsignedp)
     unsignedp = MAX_INT_CACHED_PREC + 1;
 
@@ -11096,7 +11098,7 @@ signed_or_unsigned_type_for (int unsignedp, tree type)
   else
     return NULL_TREE;
 
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (TREE_CODE (type) == BITINT_TYPE && (unsignedp || bits > 1))
     return build_bitint_type (bits, unsignedp);
   return build_nonstandard_integer_type (bits, unsignedp);
 }
-- 
GitLab