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

Reply via email to