]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c: fix crash when checking for compatibility of structures [PR116726]
authorMartin Uecker <uecker@tugraz.at>
Tue, 17 Sep 2024 09:37:29 +0000 (11:37 +0200)
committerMartin Uecker <uecker@gcc.gnu.org>
Fri, 20 Sep 2024 20:54:26 +0000 (22:54 +0200)
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.

gcc/c/c-typeck.cc
gcc/testsuite/gcc.dg/pr116726.c [new file with mode: 0644]

index 58b2724b39e32efeee070e59976b27ad9c88e442..ba6d96d26b2b166190c1bb2dac747e2386f0be0e 100644 (file)
@@ -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 (file)
index 0000000..bb25efc
--- /dev/null
@@ -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 *);