]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
analyzer: fix ICE on computed goto [PR124375]
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/124375
* ops.cc (ggoto_edge_op::apply_constraints): Ensure that we write
back a rejected_constraint if the edge is infeasible.
* region-model.cc (region_model::add_constraint): Convert
rejected_op_constraint from tree to const svalue *.
(rejected_op_constraint::dump_to_pp): Likewise.
* region-model.h (class rejected_op_constraint): Likewise.

gcc/testsuite/ChangeLog:
PR analyzer/124375
* gcc.dg/analyzer/ice-pr124375-1.c: New test.
* gcc.dg/analyzer/ice-pr124375-2.c: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
gcc/analyzer/ops.cc
gcc/analyzer/region-model.cc
gcc/analyzer/region-model.h
gcc/testsuite/gcc.dg/analyzer/ice-pr124375-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/analyzer/ice-pr124375-2.c [new file with mode: 0644]

index 92e2cc42917b48be64b7259c17f12aafdaaa98d6..b40e078c928ba42daeccbc9ea601e37ad65525be 100644 (file)
@@ -1481,7 +1481,7 @@ ggoto_edge_op::
 apply_constraints (const superedge *,
                   region_model &model,
                   region_model_context *ctxt,
-                  std::unique_ptr<rejected_constraint> */*out_rc*/) const
+                  std::unique_ptr<rejected_constraint> *out_rc) const
 {
   const ggoto &goto_stmt = get_ggoto ();
   tree dest = gimple_goto_dest (&goto_stmt);
@@ -1497,7 +1497,15 @@ apply_constraints (const superedge *,
        = mgr->get_ptr_svalue (ptr_type_node, dst_label_reg);
 
       if (!model.add_constraint (dest_sval, EQ_EXPR, dst_label_ptr, ctxt))
-       return false;
+       {
+         if (out_rc)
+           *out_rc
+             = std::make_unique <rejected_op_constraint> (model,
+                                                          dest_sval,
+                                                          EQ_EXPR,
+                                                          dst_label_ptr);
+         return false;
+       }
     }
 
   return true;
index a044aeb9700f5ccc021b50950ad69ad7f4143e74..4a6f5b4800c03eaa3f7f2f32b2fb3478d2ea4dbb 100644 (file)
@@ -5806,7 +5806,12 @@ region_model::add_constraint (tree lhs, enum tree_code op, tree rhs,
 {
   bool sat = add_constraint (lhs, op, rhs, ctxt);
   if (!sat && out)
-    *out = std::make_unique <rejected_op_constraint> (*this, lhs, op, rhs);
+    {
+      const svalue *lhs_sval = get_rvalue (lhs, nullptr);
+      const svalue *rhs_sval = get_rvalue (rhs, nullptr);
+      *out = std::make_unique <rejected_op_constraint> (*this,
+                                                       lhs_sval, op, rhs_sval);
+    }
   return sat;
 }
 
@@ -7623,11 +7628,9 @@ void
 rejected_op_constraint::dump_to_pp (pretty_printer *pp) const
 {
   region_model m (m_model);
-  const svalue *lhs_sval = m.get_rvalue (m_lhs, nullptr);
-  const svalue *rhs_sval = m.get_rvalue (m_rhs, nullptr);
-  lhs_sval->dump_to_pp (pp, true);
+  m_lhs->dump_to_pp (pp, true);
   pp_printf (pp, " %s ", op_symbol_code (m_op));
-  rhs_sval->dump_to_pp (pp, true);
+  m_rhs->dump_to_pp (pp, true);
 }
 
 /* class rejected_default_case : public rejected_constraint.  */
index 6e9129a6dca1f2e7d670bee09ff4354af68d2e90..fb15afb71d07efa5419311e3f346eec170bb34d4 100644 (file)
@@ -1268,16 +1268,16 @@ class rejected_op_constraint : public rejected_constraint
 {
 public:
   rejected_op_constraint (const region_model &model,
-                         tree lhs, enum tree_code op, tree rhs)
+                         const svalue *lhs, enum tree_code op, const svalue *rhs)
   : rejected_constraint (model),
     m_lhs (lhs), m_op (op), m_rhs (rhs)
   {}
 
   void dump_to_pp (pretty_printer *pp) const final override;
 
-  tree m_lhs;
+  const svalue *m_lhs;
   enum tree_code m_op;
-  tree m_rhs;
+  const svalue *m_rhs;
 };
 
 class rejected_default_case : public rejected_constraint
diff --git a/gcc/testsuite/gcc.dg/analyzer/ice-pr124375-1.c b/gcc/testsuite/gcc.dg/analyzer/ice-pr124375-1.c
new file mode 100644 (file)
index 0000000..537f513
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-additional-options "-O2" } */
+
+char __printf_buffer_spec;
+int __printf_buffer_offset;
+void *__printf_buffer_ptr;
+void __printf_buffer() {
+  int step0_jumps[] = {&&do_flag_hash - &&do_form_unknown};
+do_flag_hash:
+  __printf_buffer_offset = __printf_buffer_spec /* { dg-warning "stack-based buffer over-read" } */
+                               ? &&do_form_unknown - &&do_form_unknown
+                               : step0_jumps[' '];
+  __printf_buffer_ptr = &&do_form_unknown + __printf_buffer_offset;
+  goto *__printf_buffer_ptr;
+do_form_unknown:
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/ice-pr124375-2.c b/gcc/testsuite/gcc.dg/analyzer/ice-pr124375-2.c
new file mode 100644 (file)
index 0000000..e20a439
--- /dev/null
@@ -0,0 +1,11 @@
+int __wcslen_spec, __wcslen_offset;
+void *__wcslen_ptr;
+long __wcslen() {
+  &&do_form_binary;
+  __wcslen_offset =
+      __wcslen_spec ? &&do_form_unknown - &&do_form_unknown : L' ';
+  __wcslen_ptr = &&do_form_unknown + __wcslen_offset;
+  goto *__wcslen_ptr;
+do_form_binary:
+do_form_unknown:
+} /* { dg-warning "return-value" } */