Skip to content

Commit ca19686

Browse files
committed
c: Fix ICE in c_type_tag on va_list [PR121506]
The C and C++ FEs disagree on what TYPE_NAME on RECORD_TYPE for structure/class definition is (rather than typedef/using, for those both have TYPE_NAME of TYPE_DECL with DECL_ORIGINAL_TYPE), the C FE just uses IDENTIFIER_NODE as TYPE_NAME on RECORD_TYPE, while the C++ FE uses TYPE_DECL as TYPENAME on RECORD_TYPE and only DECL_NAME on the TYPE_DECL provides the IDENTIFIER_NODE. The reason for the C++ FE way is that there can be type definitions at class scope (rather than just typedefs) and those need to be among TYPE_FIELDS (so the corresponding TYPE_DECL is in that chain) etc. The middle-end can cope with it, e.g. if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE) pp_tree_identifier (pp, TYPE_NAME (node)); else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL && DECL_NAME (TYPE_NAME (node))) dump_decl_name (pp, TYPE_NAME (node), flags); and many other places. Now, the backends on various targets create artificial structure definitions for va_list, e.g. x86 creates struct __va_list_tag and they do it the C++ FE way so that the C++ FE can cope with those. Except the new c_type_tag can't deal with that and ICEs. The following patch fixes it so that it can handle it too. 2025-11-27 Jakub Jelinek <[email protected]> PR c/121506 * c-typeck.cc (c_type_tag): If TYPE_NAME is TYPE_DECL with non-NULL DECL_NAME, return that. * gcc.dg/pr121506.c: New test.
1 parent f768b15 commit ca19686

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

gcc/c/c-typeck.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -610,9 +610,9 @@ c_type_tag (const_tree t)
610610
return NULL_TREE;
611611
if (TREE_CODE (name) == TYPE_DECL)
612612
{
613-
/* A TYPE_DECL added by add_decl_expr. */
614-
gcc_checking_assert (!DECL_NAME (name));
615-
return NULL_TREE;
613+
if (!DECL_NAME (name))
614+
return NULL_TREE;
615+
name = DECL_NAME (name);
616616
}
617617
gcc_checking_assert (TREE_CODE (name) == IDENTIFIER_NODE);
618618
return name;

gcc/testsuite/gcc.dg/pr121506.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/* PR c/121506 */
2+
/* { dg-do compile } */
3+
4+
#include <stdarg.h>
5+
6+
struct A;
7+
void foo (struct A *); /* { dg-message "previous declaration of 'foo' with type 'void\\\(struct A \\\*\\\)'" } */
8+
void foo (va_list); /* { dg-error "conflicting types for 'foo'; have" } */

0 commit comments

Comments
 (0)