Here is a fix for a mistake I made when recursively checking for type compatibility.
Bootstrapped and regression tested on x86-64. c: fix crash when checking for compatibility of structures [PR116726] When checking for compatibility of structure or union types in tagged_types_tu_compatible_p, restore the old value of the pointer to the top of the temporary cache after recursively calling comptypes_internal when looping over the members of a structure of union. While the next iteration of the loop overwrites the pointer, I missed the fact that it can be accessed again when types of function arguments are compared as part of recursive type checking and the function is entered again. PR c/116726 gcc/Changelog: * c/c-typeck.cc (tagged_types_tu_compatible_p): Restore value of the cache after recursing into comptypes_internal. gcc/testsuite/Changelog: * pr116726.c: New test. diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 58b2724b39e..ba6d96d26b2 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -1686,8 +1686,11 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2, data->anon_field = !DECL_NAME (s1); data->pointedto = false; + const struct tagged_tu_seen_cache *cache = data->cache; data->cache = &entry; - if (!comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2), data)) + bool ret = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2), data); + data->cache = cache; + if (!ret) return false; tree st1 = TYPE_SIZE (TREE_TYPE (s1)); diff --git a/gcc/testsuite/gcc.dg/pr116726.c b/gcc/testsuite/gcc.dg/pr116726.c new file mode 100644 index 00000000000..bb25efca586 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr116726.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c23" } */ + +struct s1 { + int f1; +}; +struct s2 { + int f2; +}; +struct s1 f(struct s2 *); + +struct s1 { + int f1; +}; +struct s2 { + int f2; +}; +struct s1 f(struct s2 *); .