c: fix ICE when forming composite type for two structures / unions [PR117548]
When forming the composite type from two tagged type, we need to find the original type for a typedecl to get the correct tag. PR c/117548 gcc/c/ChangeLog: * c-decl.cc (finish_struct): Add checking assertion. * c-typeck.cc (c_type_original): New function. (composite_types_internal): Get tag from original type. gcc/testsuite/ChangeLog: * gcc.dg/pr117548.c: New test.
This commit is contained in:
parent
6aabe3adef
commit
d8af6c203f
3 changed files with 38 additions and 15 deletions
|
@ -9872,6 +9872,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
|
|||
hashval_t hash = c_struct_hasher::hash (t);
|
||||
|
||||
gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
|
||||
gcc_checking_assert (!TYPE_NAME (t)
|
||||
|| TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE);
|
||||
|
||||
tree *e = c_struct_htab->find_slot_with_hash (t, hash, INSERT);
|
||||
if (*e)
|
||||
TYPE_CANONICAL (t) = *e;
|
||||
|
|
|
@ -576,6 +576,21 @@ c_build_functype_attribute_variant (tree ntype, tree otype, tree attrs)
|
|||
|
||||
}
|
||||
|
||||
/* Given a type which could be a typedef name, make sure to return the
|
||||
original type. */
|
||||
static const_tree
|
||||
c_type_original (const_tree t)
|
||||
{
|
||||
/* It may even be a typedef of a typedef...
|
||||
In the case of compiler-created builtin structs the TYPE_DECL
|
||||
may be a dummy, with no DECL_ORIGINAL_TYPE. Don't fault. */
|
||||
while (TYPE_NAME (t)
|
||||
&& TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
|
||||
&& DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
|
||||
t = DECL_ORIGINAL_TYPE (TYPE_NAME (t));
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/* Return the composite type of two compatible types.
|
||||
|
||||
|
@ -728,8 +743,11 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache)
|
|||
case UNION_TYPE:
|
||||
if (flag_isoc23 && !comptypes_same_p (t1, t2))
|
||||
{
|
||||
/* Go to the original type to get the right tag. */
|
||||
tree tag = TYPE_NAME (c_type_original (const_cast<tree> (t1)));
|
||||
|
||||
gcc_checking_assert (COMPLETE_TYPE_P (t1) && COMPLETE_TYPE_P (t2));
|
||||
gcc_checking_assert (!TYPE_NAME (t1) || comptypes (t1, t2));
|
||||
gcc_checking_assert (!tag || comptypes (t1, t2));
|
||||
|
||||
/* If a composite type for these two types is already under
|
||||
construction, return it. */
|
||||
|
@ -742,7 +760,7 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache)
|
|||
|
||||
tree n = make_node (code1);
|
||||
SET_TYPE_STRUCTURAL_EQUALITY (n);
|
||||
TYPE_NAME (n) = TYPE_NAME (t1);
|
||||
TYPE_NAME (n) = tag;
|
||||
|
||||
struct composite_cache cache2 = { t1, t2, n, cache };
|
||||
cache = &cache2;
|
||||
|
@ -1781,19 +1799,9 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
|
|||
|
||||
/* We have to verify that the tags of the types are the same. This
|
||||
is harder than it looks because this may be a typedef, so we have
|
||||
to go look at the original type. It may even be a typedef of a
|
||||
typedef...
|
||||
In the case of compiler-created builtin structs the TYPE_DECL
|
||||
may be a dummy, with no DECL_ORIGINAL_TYPE. Don't fault. */
|
||||
while (TYPE_NAME (t1)
|
||||
&& TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL
|
||||
&& DECL_ORIGINAL_TYPE (TYPE_NAME (t1)))
|
||||
t1 = DECL_ORIGINAL_TYPE (TYPE_NAME (t1));
|
||||
|
||||
while (TYPE_NAME (t2)
|
||||
&& TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL
|
||||
&& DECL_ORIGINAL_TYPE (TYPE_NAME (t2)))
|
||||
t2 = DECL_ORIGINAL_TYPE (TYPE_NAME (t2));
|
||||
to go look at the original type. */
|
||||
t1 = c_type_original (t1);
|
||||
t2 = c_type_original (t2);
|
||||
|
||||
if (TYPE_NAME (t1) != TYPE_NAME (t2))
|
||||
return false;
|
||||
|
|
12
gcc/testsuite/gcc.dg/pr117548.c
Normal file
12
gcc/testsuite/gcc.dg/pr117548.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c23" } */
|
||||
|
||||
typedef struct A { int q; } A;
|
||||
void f(A*);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct A { int q; };
|
||||
void f(struct A*);
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue