[PATCH] c++, v2: Fix ICE in cxx_printable_name_internal [PR123578]

Jason Merrill jason@redhat.com
Mon Jan 26 14:58:31 GMT 2026


On 1/26/26 9:36 PM, Jakub Jelinek wrote:
> On Mon, Jan 26, 2026 at 11:04:05AM +0800, Jason Merrill wrote:
>>> +  recursed = true;
>>>      print_ring[ring_counter] = xstrdup (lang_decl_name (decl, v, translate));
>>> +  recursed = false;
>>>      uid_ring[ring_counter] = DECL_UID (decl);
>>>      trans_ring[ring_counter] = translate;
>>>      return print_ring[ring_counter];
>>
>> Would it instead make sense to use a local automatic copy of "ring_counter"
>> so that recursive modifications don't change which element we access here?
> 
> We'd need to move the free call after that and I'd be afraid we would risk
> having duplicate entries in the cache (which is something the function would
> ICE on), because the checking which cache element to use has been done
> before perhaps multiple entries of the cache were changed.
> 
> But I think we could just move the lang_decl_name call earlier before we
> decide in which cache element to cache it.  I can't rule out that the call
> would recursively add the same function to the cache, so I've repeated the
> search (which is not expensive, PRINT_RING_SIZE is just 4).

OK.

> 2026-01-26  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.jj	2026-01-24 09:55:14.411592954 +0100
> +++ gcc/cp/tree.cc	2026-01-26 14:28:07.031283312 +0100
> @@ -2859,6 +2859,15 @@ cxx_printable_name_internal (tree decl,
>         /* yes, so return it.  */
>         return print_ring[i];
>   
> +  const char *ret = lang_decl_name (decl, v, translate);
> +
> +  /* The lang_decl_name call could have called this function recursively,
> +     so check again.  */
> +  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];
> +
>     if (++ring_counter == PRINT_RING_SIZE)
>       ring_counter = 0;
>   
> @@ -2878,7 +2887,7 @@ cxx_printable_name_internal (tree decl,
>   
>     free (print_ring[ring_counter]);
>   
> -  print_ring[ring_counter] = xstrdup (lang_decl_name (decl, v, translate));
> +  print_ring[ring_counter] = xstrdup (ret);
>     uid_ring[ring_counter] = DECL_UID (decl);
>     trans_ring[ring_counter] = translate;
>     return print_ring[ring_counter];
> --- gcc/testsuite/g++.dg/cpp2a/pr123578.C.jj	2026-01-26 14:14:19.391980298 +0100
> +++ gcc/testsuite/g++.dg/cpp2a/pr123578.C	2026-01-26 14:14:19.391980298 +0100
> @@ -0,0 +1,9 @@
> +// PR c++/123578
> +// { dg-do compile { target c++20 } }
> +// { dg-options "-fdump-tree-all" }
> +
> +namespace {
> +  template <typename>
> +  struct A { A (decltype ([] { return 0; } ())) {} };
> +  A <int> b = 0;
> +}
> 
> 
> 	Jakub
> 



More information about the Gcc-patches mailing list