]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: integer overflow during constraint subsumption [PR118069]
authorPatrick Palka <ppalka@redhat.com>
Thu, 19 Dec 2024 17:00:29 +0000 (12:00 -0500)
committerPatrick Palka <ppalka@redhat.com>
Thu, 19 Dec 2024 17:00:29 +0000 (12:00 -0500)
commit875f14e15d49dce7de501a6357a3d5811b5c36d4
tree4b044d1c447ba01a08454493816d48f7da6513d9
parenta104766914e98ded9b991f1dac9ad22e815a3acc
c++: integer overflow during constraint subsumption [PR118069]

For the testcase in the PR we hang during constraint subsumption
ultimately because one of the constraints is complex enough that its
conjunctive normal form is calculated to have more than 2^31 clauses,
which causes the size calculation (through an int) to overflow and so
the optimization in subsumes_constraints_nonnull

  if (dnf_size (lhs) <= cnf_size (rhs))
    // iterate over DNF of LHS
  else
    // iterate over CNF of RHS

incorrectly decides to loop over the CNF (>> billions of clauses)
instead of the DNF (thousands of clauses).

I haven't verified that the result of cnf_size is correct for the
problematic constraint but integer overflow is definitely plausible
given that CNF/DNF can be exponentially larger than the original
constraint in the worst case.

This patch fixes this by using 64-bit saturating arithmetic during
these size calculations (via new add/mul_sat_hwi functions) so that
overflow is less likely and if it does occur we handle it gracefully.
It should be highly unlikely that both the DNF and CNF sizes overflow,
and if they do then it doesn't matter which form we select, subsumption
will take forever either way.  The testcase now compiles in ~3 seconds
on my machine after this change.

PR c++/118069

gcc/ChangeLog:

* hwint.h (add_sat_hwi): New function.
(mul_sat_hwi): Likewise.

gcc/cp/ChangeLog:

* logic.cc (dnf_size_r): Use HOST_WIDE_INT instead of int, and
handle overflow gracefully via add_sat_hwi and mul_sat_hwi.
(cnf_size_r): Likewise.
(dnf_size): Use HOST_WIDE_INT instead of int.
(cnf_size): Likewise.

Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/logic.cc
gcc/hwint.h