]> git.ipfire.org Git - thirdparty/gcc.git/commit
tree-cfg: Fix up assign_discriminator ICE with too large #line [PR121663]
authorJakub Jelinek <jakub@redhat.com>
Tue, 2 Sep 2025 10:18:52 +0000 (12:18 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 2 Sep 2025 10:18:52 +0000 (12:18 +0200)
commit5440f4ceee3152148c6c212f57b85da918b66abf
tree83df330fcff1e95c814e40e4a122828f277ea2d1
parent13eee16e925218afe469a799ca17aec1e607e568
tree-cfg: Fix up assign_discriminator ICE with too large #line [PR121663]

As mentioned in the PR, LOCATION_LINE is represented in an int,
and while we have -pedantic diagnostics (and -pedantic-error error)
for too large #line, we can still overflow into negative line
numbers up to -2 and -1.  We could overflow to that even with valid
source if it says has #line 2147483640 and then just has
2G+ lines after it.
Now, the ICE is because assign_discriminator{,s} uses a hash_map
with int_hash <int64_t, -1, -2>, so values -2 and -1 are reserved
for deleted and empty entries.  We just need to make sure those aren't
valid.  One possible fix would be just that
-  discrim_entry &e = map.get_or_insert (LOCATION_LINE (loc), &existed);
+  discrim_entry &e
+    = map.get_or_insert ((unsigned) LOCATION_LINE (loc), &existed);
by adding unsigned cast when the key is signed 64-bit, it will never
be -1 or -2.
But I think that is wasteful, discrim_entry is a struct with 2 unsigned
non-static data members, so for lines which can only be 0 to 0xffffffff
(sure, with wrap-around), I think just using a hash_map with 96bit elts
is better than 128bit.
So, the following patch just doesn't assign any discriminators for lines
-1U and -2U, I think that is fine, normal programs never do that.
Another possibility would be to handle lines -1U and -2U as if it was say
-3U.

2025-09-02  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/121663
* tree-cfg.cc (assign_discriminator): Change map argument type
from hash_map with int_hash <int64_t, -1, -2> to one with
int_hash <unsigned, -1U, -2U>.  Cast LOCATION_LINE to unsigned.
Return early for (unsigned) LOCATION_LINE above -3U.
(assign_discriminators): Change map type from hash_map with
int_hash <int64_t, -1, -2> to one with int_hash <unsigned, -1U, -2U>.

* gcc.dg/pr121663.c: New test.
gcc/testsuite/gcc.dg/pr121663.c [new file with mode: 0644]
gcc/tree-cfg.cc