]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: Fix ICE in cxx_printable_name_internal [PR123578]
authorJakub Jelinek <jakub@redhat.com>
Tue, 27 Jan 2026 09:19:39 +0000 (10:19 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 27 Jan 2026 09:19:39 +0000 (10:19 +0100)
commitd341b0d57fc61e58598f072a5c2be1f8a5873ff3
tree96ba560bac284815ad9b05b80eaf360efecadbda
parentc86745f4f6e57ac5bd3d399f294860753bcbaa11
c++: Fix ICE in cxx_printable_name_internal [PR123578]

On the following testcase, we end up with cxx_printable_name_internal
recursion, in particular
+../../gcc/cp/pt.cc:20736
+../../gcc/cp/error.cc:625
+template_args=<tree_vec 0x7fffe94b59b0>, flags=4) at ../../gcc/cp/error.cc:1876
The ICE is due to double free, that function is doing caching of up to 4
printed names, but if such a recursion happens, the inner call can change
ring_counter etc. and the caller will then store the result in a different
ring element from what was freed and so the freed one can be left
unmodified.

The patch fixes it by moving the lang_decl_name call earlier, after the:
  /* See if this print name is lying around.  */
  for (i = 0; i < PRINT_RING_SIZE; i++)
    if (uid_ring[i] == DECL_UID (decl) && translate == trans_ring[i])
      /* yes, so return it.  */
      return print_ring[i];
loop and repeating the loop again just for the theoretical case
that some recursion would add the same entry.

The ring_counter adjustment and decision which cache entry to reuse
for the cache is then done without the possibility of ring_counter
or the cache being changed in the middle.

2026-01-27  Jakub Jelinek  <jakub@redhat.com>

PR c++/123578
* tree.cc (cxx_printable_name_internal): Call lang_decl_name before
finding the slot to cache it in and repeat search in the cache
after the call.

* g++.dg/cpp2a/pr123578.C: New test.
gcc/cp/tree.cc
gcc/testsuite/g++.dg/cpp2a/pr123578.C [new file with mode: 0644]