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