From: Martin Uecker Date: Tue, 17 Sep 2024 09:37:29 +0000 (+0200) Subject: c: fix crash when checking for compatibility of structures [PR116726] X-Git-Tag: basepoints/gcc-16~5808 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9227a64495d5594613604573b72422e8e3722fc5;p=thirdparty%2Fgcc.git 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/c/ChangeLog: * c-typeck.cc (tagged_types_tu_compatible_p): Restore value of the cache after recursing into comptypes_internal. gcc/testsuite/ChangeLog: * gcc.dg/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 *);