Fixed some very obvious errors that should have been fixed before I
submitted v1, lesson learned this time I hope.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
From 32fa771d65eeca675d268bcf96b654fe5ac64eaf Mon Sep 17 00:00:00 2001
From: Waffl3x <waff...@baylibre.com>
Date: Tue, 8 Jul 2025 19:25:20 -0600
Subject: [PATCH 1/3] tree: Add TREE_NOT_RANGE_CHECK

There was no inverted counterpart to TREE_RANGE_CHECK, this adds one.

gcc/ChangeLog:

	* tree.cc (tree_not_range_check_failed): New.
	* tree.h (TREE_NOT_RANGE_CHECK): Define.
	(tree_not_range_check_failed): New declaration.
	(tree_not_range_check): New.

Signed-off-by: Waffl3x <waff...@baylibre.com>
---
 gcc/tree.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++
 gcc/tree.h  | 29 +++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/gcc/tree.cc b/gcc/tree.cc
index 6a055c8c2d0..9a5477df88d 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -9246,6 +9246,51 @@ tree_range_check_failed (const_tree node, const char *file, int line,
 		  function, trim_filename (file), line);
 }
 
+/* Similar to tree_not_check_failed, except that instead of specifying a
+   dozen codes, use the knowledge that they're all sequential.
+   C1 and C2 are an inclusive range.  */
+
+void
+tree_not_range_check_failed (const_tree node, const char *file, int line,
+			     const char *function, enum tree_code c1,
+			     enum tree_code c2)
+{
+  gcc_assert (c1 <= c2);
+  static constexpr size_t seperator_length = 4;
+  const size_t buffer_length = [&] ()
+    {
+      size_t length = 0;
+      /* Overallocates by 4, which is fine, accounts for null terminator.  */
+      for (unsigned int c = c1; c <= c2; ++c)
+	length += seperator_length
+		  + strlen (get_tree_code_name ((enum tree_code) c));
+      return length;
+    } (); /* IILE.  */
+  gcc_assert (buffer_length);
+  char *buffer = (char *) alloca (buffer_length);
+
+  unsigned int c = c1;
+  /* First case unrolled.  */
+  const char *node_name = get_tree_code_name ((enum tree_code) c);
+  size_t written_length = strlen (node_name);
+  /* Account for null terminator.  */
+  gcc_assert (written_length + 1 <= buffer_length);
+  strcpy (buffer, node_name);
+  ++c;
+  for (; c <= c2; ++c)
+    {
+      char *unwritten_start = buffer + written_length;
+      node_name = get_tree_code_name ((enum tree_code) c);
+      written_length += strlen (node_name) + seperator_length;
+      /* Account for null terminator.  */
+      gcc_assert (written_length + 1 <= buffer_length);
+      strcpy (unwritten_start, " or ");
+      strcpy (unwritten_start + seperator_length, node_name);
+    }
+  internal_error ("tree check: expected none of %s, have %s in %s, at %s:%d",
+		  buffer, get_tree_code_name (TREE_CODE (node)),
+		  function, trim_filename (file), line);
+}
 
 /* Similar to tree_check_failed, except that we check that a tree does
    not have the specified code, given in CL.  */
diff --git a/gcc/tree.h b/gcc/tree.h
index e87fa0f81bc..40255b535f6 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -380,6 +380,10 @@ code_helper::is_builtin_fn () const
 #define TREE_RANGE_CHECK(T, CODE1, CODE2) \
 (tree_range_check ((T), (CODE1), (CODE2), __FILE__, __LINE__, __FUNCTION__))
 
+#define TREE_NOT_RANGE_CHECK(T, CODE1, CODE2) \
+(tree_not_range_check ((T), (CODE1), (CODE2), \
+		       __FILE__, __LINE__, __FUNCTION__))
+
 #define OMP_CLAUSE_SUBCODE_CHECK(T, CODE) \
 (omp_clause_subcode_check ((T), (CODE), __FILE__, __LINE__, __FUNCTION__))
 
@@ -453,6 +457,10 @@ extern void tree_range_check_failed (const_tree, const char *, int,
 				     const char *, enum tree_code,
 				     enum tree_code)
     ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
+extern void tree_not_range_check_failed (const_tree, const char *, int,
+					 const char *, enum tree_code,
+					 enum tree_code)
+    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
 extern void tree_not_class_check_failed (const_tree,
 					 const enum tree_code_class,
 					 const char *, int, const char *)
@@ -497,6 +505,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 #define TREE_NOT_CHECK6(T, CODE1, CODE2, CODE3, CODE4, CODE5, CODE6) (T)
 #define TREE_CLASS_CHECK(T, CODE)		(T)
 #define TREE_RANGE_CHECK(T, CODE1, CODE2)	(T)
+#define TREE_NOT_RANGE_CHECK(T, CODE1, CODE2)	(T)
 #define EXPR_CHECK(T)				(T)
 #define NON_TYPE_CHECK(T)			(T)
 #define TREE_INT_CST_ELT_CHECK(T, I)		((T)->int_cst.val[I])
@@ -3882,6 +3891,16 @@ tree_range_check (tree __t,
   return __t;
 }
 
+inline tree
+tree_not_range_check (tree __t,
+		      enum tree_code __code1, enum tree_code __code2,
+		      const char *__f, int __l, const char *__g)
+{
+  if (!(TREE_CODE (__t) < __code1 || TREE_CODE (__t) > __code2))
+    tree_not_range_check_failed (__t, __f, __l, __g, __code1, __code2);
+  return __t;
+}
+
 inline tree
 omp_clause_subcode_check (tree __t, enum omp_clause_code __code,
                           const char *__f, int __l, const char *__g)
@@ -4170,6 +4189,16 @@ tree_range_check (const_tree __t,
   return __t;
 }
 
+inline const_tree
+tree_not_range_check (const_tree __t,
+		      enum tree_code __code1, enum tree_code __code2,
+		      const char *__f, int __l, const char *__g)
+{
+  if (!(TREE_CODE (__t) < __code1 || TREE_CODE (__t) > __code2))
+    tree_not_range_check_failed (__t, __f, __l, __g, __code1, __code2);
+  return __t;
+}
+
 inline const_tree
 omp_clause_subcode_check (const_tree __t, enum omp_clause_code __code,
                           const char *__f, int __l, const char *__g)
-- 
2.49.0

Reply via email to