]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
analyzer: fix ICE on effective modulo by zero [PR124433]
authorDavid Malcolm <dmalcolm@redhat.com>
Thu, 12 Mar 2026 00:45:29 +0000 (20:45 -0400)
committerDavid Malcolm <dmalcolm@redhat.com>
Thu, 12 Mar 2026 00:45:29 +0000 (20:45 -0400)
gcc/analyzer/ChangeLog:
PR analyzer/124433
* region-model-manager.cc
(region_model_manager::maybe_fold_binop): When checking for
division by zero, use the value range of the divisor, rather
than merely checking for constant 0.
* region-model.cc (region_model::get_gassign_result): Likewise.

gcc/testsuite/ChangeLog:
PR analyzer/124433
* gcc.dg/analyzer/divide-by-zero-ice-pr124433.c: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
gcc/analyzer/region-model-manager.cc
gcc/analyzer/region-model.cc
gcc/testsuite/gcc.dg/analyzer/divide-by-zero-ice-pr124433.c [new file with mode: 0644]

index 33d9a62937c34a2586cde508947622b88c04647d..702a8ae72440aa4e85df15e48a43daee4c2ead2e 100644 (file)
@@ -803,8 +803,12 @@ region_model_manager::maybe_fold_binop (tree type, enum tree_code op,
     case ROUND_MOD_EXPR:
     case RDIV_EXPR:
     case EXACT_DIV_EXPR:
-      if (cst1 && zerop (cst1))
-       return get_or_create_unknown_svalue (type);
+      {
+       value_range arg1_vr;
+       if (arg1->maybe_get_value_range (arg1_vr))
+         if (arg1_vr.zero_p ())
+           return get_or_create_unknown_svalue (type);
+      }
       break;
     }
 
index a85c6958838add4559265fc1378e5716478d4c76..a044aeb9700f5ccc021b50950ad69ad7f4143e74 100644 (file)
@@ -1365,8 +1365,9 @@ region_model::get_gassign_result (const gassign *assign,
                || op == RDIV_EXPR
                || op == EXACT_DIV_EXPR))
          {
-           if (const tree rhs2_cst = rhs2_sval->maybe_get_constant ())
-             if (zerop (rhs2_cst))
+           value_range rhs_vr;
+           if (rhs2_sval->maybe_get_value_range (rhs_vr))
+             if (rhs_vr.zero_p ())
                {
                  /* Ideally we should issue a warning here;
                     see PR analyzer/124217.  */
diff --git a/gcc/testsuite/gcc.dg/analyzer/divide-by-zero-ice-pr124433.c b/gcc/testsuite/gcc.dg/analyzer/divide-by-zero-ice-pr124433.c
new file mode 100644 (file)
index 0000000..9b52ac8
--- /dev/null
@@ -0,0 +1,9 @@
+unsigned m;
+int c;
+
+void
+foo()
+{
+  do c %= (5ull << 40) & m;
+  while (c);
+}