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 *);

.

Reply via email to