bounded_ranges::eval_condition might got some non-integral rhs_const
like a pointer-typed INTEGER_CST (the NULL of the pointer type) when
analyzing, and that will crash later when we try to get TYPE_MIN_VALUE
/ TYPE_MAX_VALUE / tree_int_cst_lt of a pointer type.
So we might bail out for those cases, I guess another approach is to
handle pointer-typed INTEGER_CST at bounded_ranges::bounded_ranges, but
I am not sure that's right direction.
gcc/analyzer/ChangeLog:
PR analyzer/125380
* constraint-manager.cc (bounded_ranges::eval_condition): Return
tristate::unknown for non-integral rhs_const, matching the existing
guard in range::add_bound.
gcc/testsuite/ChangeLog:
PR analyzer/125380
* gcc.dg/analyzer/pr125380.c: New test.
---
gcc/analyzer/constraint-manager.cc | 5 +++++
gcc/testsuite/gcc.dg/analyzer/pr125380.c | 18 ++++++++++++++++++
2 files changed, 23 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr125380.c
diff --git a/gcc/analyzer/constraint-manager.cc
b/gcc/analyzer/constraint-manager.cc
index 22b8d402df0..1bcd2d1c8d0 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -744,6 +744,11 @@ bounded_ranges::eval_condition (enum tree_code op,
tree rhs_const,
bounded_ranges_manager *mgr) const
{
+ /* bounded_ranges require INTEGRAL_TYPE_P, and rhs_const might hold
+ integer_cst with pointer_type. */
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (rhs_const)))
+ return tristate::unknown ();
+
/* Convert (X OP RHS_CONST) to a bounded_ranges instance and find
the intersection of that with this object. */
bounded_ranges other (op, rhs_const);
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr125380.c
b/gcc/testsuite/gcc.dg/analyzer/pr125380.c
new file mode 100644
index 00000000000..d43ae6848bb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr125380.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+typedef struct {
+ long a;
+ long b;
+} c;
+
+long d;
+
+void e (void)
+{
+ long a = d;
+ switch (d) {
+ case 0:
+ case (long)&((c *)0)->b:
+ *(long *)a = d;
+ }
+}
--
2.52.0