public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Martin Uecker <uecker@tugraz.at>
To: gcc-patches@gcc.gnu.org
Cc: Joseph Myers <joseph@codesourcery.com>
Subject: [PATCH 3/4] c23: aliasing of compatible tagged types
Date: Thu, 16 Nov 2023 22:39:26 +0100	[thread overview]
Message-ID: <223aa096afbdbb177d4ad5245696d439ad4cf87f.camel@tugraz.at> (raw)
In-Reply-To: <02a9b94e4d653b6f1b9f89a1b62187f46e871738.camel@tugraz.at>




Tell the backend which types are equivalent by setting
TYPE_CANONICAL to one struct in the set of equivalent
structs. Structs are considered equivalent by ignoring
all sizes of arrays nested in types below field level.

gcc/c:
	* c-decl.cc (c_struct_hasher): Hash stable for struct
	types.
	(c_struct_hasher::hash, c_struct_hasher::equal): New
	functions.
	(finish_struct): Set TYPE_CANONICAL to first struct in
	equivalence class.
	* c-objc-common.cc (c_get_alias_set): Let structs or
	unions with variable size alias anything.
	* c-tree.h (comptypes_equiv): New prototype.
	* c-typeck.cc (comptypes_equiv): New function.
	(comptypes_internal): Implement equivalence mode.
	(tagged_types_tu_compatible): Implement equivalence mode.

gcc/testsuite:
	* gcc.dg/c23-tag-2.c: Activate.
	* gcc.dg/c23-tag-6.c: Activate.
	* gcc.dg/c23-tag-alias-1.c: New test.
	* gcc.dg/c23-tag-alias-2.c: New test.
	* gcc.dg/c23-tag-alias-3.c: New test.
	* gcc.dg/c23-tag-alias-4.c: New test.
	* gcc.dg/c23-tag-alias-5.c: New test.
	* gcc.dg/c23-tag-alias-6.c: New test.
	* gcc.dg/c23-tag-alias-7.c: New test.
	* gcc.dg/c23-tag-alias-8.c: New test.
	* gcc.dg/gnu23-tag-alias-1.c: New test.
---
 gcc/c/c-decl.cc                          | 48 +++++++++++++
 gcc/c/c-objc-common.cc                   |  5 ++
 gcc/c/c-tree.h                           |  1 +
 gcc/c/c-typeck.cc                        | 31 ++++++++
 gcc/testsuite/gcc.dg/c23-tag-2.c         |  4 +-
 gcc/testsuite/gcc.dg/c23-tag-5.c         |  5 +-
 gcc/testsuite/gcc.dg/c23-tag-alias-1.c   | 48 +++++++++++++
 gcc/testsuite/gcc.dg/c23-tag-alias-2.c   | 73 +++++++++++++++++++
 gcc/testsuite/gcc.dg/c23-tag-alias-3.c   | 48 +++++++++++++
 gcc/testsuite/gcc.dg/c23-tag-alias-4.c   | 73 +++++++++++++++++++
 gcc/testsuite/gcc.dg/c23-tag-alias-5.c   | 30 ++++++++
 gcc/testsuite/gcc.dg/c23-tag-alias-6.c   | 77 ++++++++++++++++++++
 gcc/testsuite/gcc.dg/c23-tag-alias-7.c   | 86 ++++++++++++++++++++++
 gcc/testsuite/gcc.dg/c23-tag-alias-8.c   | 90 ++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/gnu23-tag-alias-1.c | 33 +++++++++
 15 files changed, 648 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/c23-tag-alias-1.c
 create mode 100644 gcc/testsuite/gcc.dg/c23-tag-alias-2.c
 create mode 100644 gcc/testsuite/gcc.dg/c23-tag-alias-3.c
 create mode 100644 gcc/testsuite/gcc.dg/c23-tag-alias-4.c
 create mode 100644 gcc/testsuite/gcc.dg/c23-tag-alias-5.c
 create mode 100644 gcc/testsuite/gcc.dg/c23-tag-alias-6.c
 create mode 100644 gcc/testsuite/gcc.dg/c23-tag-alias-7.c
 create mode 100644 gcc/testsuite/gcc.dg/c23-tag-alias-8.c
 create mode 100644 gcc/testsuite/gcc.dg/gnu23-tag-alias-1.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index e5d48c3fa56..d0a405087c3 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -634,6 +634,36 @@ public:
   auto_vec<tree> typedefs_seen;
 };
 
+
+/* Hash table for structs and unions.  */
+struct c_struct_hasher : ggc_ptr_hash<tree_node>
+{
+  static hashval_t hash (tree t);
+  static bool equal (tree, tree);
+};
+
+/* Hash an RECORD OR UNION.  */
+hashval_t
+c_struct_hasher::hash (tree type)
+{
+  inchash::hash hstate;
+
+  hstate.add_int (TREE_CODE (type));
+  hstate.add_object (TYPE_NAME (type));
+
+  return hstate.end ();
+}
+
+/* Compare two RECORD or UNION types.  */
+bool
+c_struct_hasher::equal (tree t1,  tree t2)
+{
+  return comptypes_equiv_p (t1, t2);
+}
+
+/* All tagged typed so that TYPE_CANONICAL can be set correctly.  */
+static GTY (()) hash_table<c_struct_hasher> *c_struct_htab;
+
 /* Information for the struct or union currently being parsed, or
    NULL if not parsing a struct or union.  */
 static class c_struct_parse_info *struct_parse_info;
@@ -9646,6 +9676,24 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
 
   C_TYPE_BEING_DEFINED (t) = 0;
 
+  /* Set type canonical based on equivalence class.  */
+  if (flag_isoc23)
+    {
+      if (NULL == c_struct_htab)
+	c_struct_htab = hash_table<c_struct_hasher>::create_ggc (61);
+
+      hashval_t hash = c_struct_hasher::hash (t);
+
+      tree *e = c_struct_htab->find_slot_with_hash (t, hash, INSERT);
+      if (*e)
+	TYPE_CANONICAL (t) = *e;
+      else
+	{
+	  TYPE_CANONICAL (t) = t;
+	  *e = t;
+	}
+    }
+
   tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
   for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
     {
diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc
index c8f49aa2370..738afbad770 100644
--- a/gcc/c/c-objc-common.cc
+++ b/gcc/c/c-objc-common.cc
@@ -389,6 +389,11 @@ c_get_alias_set (tree t)
   if (TREE_CODE (t) == ENUMERAL_TYPE)
     return get_alias_set (ENUM_UNDERLYING_TYPE (t));
 
+  /* Structs with variable size can alias different incompatible
+     structs.  Let them alias anything.   */
+  if (RECORD_OR_UNION_TYPE_P (t) && C_TYPE_VARIABLE_SIZE (t))
+    return 0;
+
   return c_common_get_alias_set (t);
 }
 
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index a5dd9a37944..ece5b6a5d26 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -758,6 +758,7 @@ extern tree require_complete_type (location_t, tree);
 extern bool same_translation_unit_p (const_tree, const_tree);
 extern int comptypes (tree, tree);
 extern bool comptypes_same_p (tree, tree);
+extern int comptypes_equiv_p (tree, tree);
 extern int comptypes_check_different_types (tree, tree, bool *);
 extern int comptypes_check_enum_int (tree, tree, bool *);
 extern bool c_mark_addressable (tree, bool = false);
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 8116c9b3e68..262b04c582f 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -1063,6 +1063,7 @@ struct comptypes_data {
   bool different_types_p;
   bool warning_needed;
   bool anon_field;
+  bool equiv;
 
   const struct tagged_tu_seen_cache* cache;
 };
@@ -1123,6 +1124,21 @@ comptypes_check_different_types (tree type1, tree type2,
 
   return ret ? (data.warning_needed ? 2 : 1) : 0;
 }
+
+
+/* Like comptypes, but if it returns nonzero for struct and union
+   types considered equivalent for aliasing purposes.  */
+
+int
+comptypes_equiv_p (tree type1, tree type2)
+{
+  struct comptypes_data data = { };
+  data.equiv = true;
+  bool ret = comptypes_internal (type1, type2, &data);
+
+  return ret;
+}
+
 \f
 /* Return true if TYPE1 and TYPE2 are compatible types for assignment
    or various other operations.  If they are compatible but a warning may
@@ -1250,6 +1266,9 @@ comptypes_internal (const_tree type1, const_tree type2,
 
 	if ((d1 == NULL_TREE) != (d2 == NULL_TREE))
 	  data->different_types_p = true;
+	/* ignore size mismatches */
+	if (data->equiv)
+	  return 1;
 	/* Sizes must match unless one is missing or variable.  */
 	if (d1 == NULL_TREE || d2 == NULL_TREE || d1 == d2)
 	  return true;
@@ -1467,6 +1486,9 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
 	if (list_length (TYPE_FIELDS (t1)) != list_length (TYPE_FIELDS (t2)))
 	  return false;
 
+	if (data->equiv && (C_TYPE_VARIABLE_SIZE (t1) || C_TYPE_VARIABLE_SIZE (t2)))
+	  return 0;
+
 	for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2);
 	     s1 && s2;
 	     s1 = DECL_CHAIN (s1), s2 = DECL_CHAIN (s2))
@@ -1486,6 +1508,15 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
 		&& simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
 				     DECL_FIELD_BIT_OFFSET (s2)) != 1)
 	      return false;
+
+	    tree st1 = TYPE_SIZE (TREE_TYPE (s1));
+	    tree st2 = TYPE_SIZE (TREE_TYPE (s2));
+
+	    if (data->equiv
+		&& st1 && TREE_CODE (st1) == INTEGER_CST
+		&& st2 && TREE_CODE (st2) == INTEGER_CST
+		&& !tree_int_cst_equal (st1, st2))
+	     return 0;
 	  }
 	return true;
 
diff --git a/gcc/testsuite/gcc.dg/c23-tag-2.c b/gcc/testsuite/gcc.dg/c23-tag-2.c
index 5dd4a21e9df..e28c2b5eea2 100644
--- a/gcc/testsuite/gcc.dg/c23-tag-2.c
+++ b/gcc/testsuite/gcc.dg/c23-tag-2.c
@@ -1,5 +1,5 @@
-/* { dg-do compile { target { ! "*-*-*" } } }
- * { dg-options "-std=c23" }
+/* { dg-do compile }
+ * { dg-options "-std=c2x" }
  */
 
 // compatibility of structs in assignment
diff --git a/gcc/testsuite/gcc.dg/c23-tag-5.c b/gcc/testsuite/gcc.dg/c23-tag-5.c
index ff40d07aef1..95a04bf9b0e 100644
--- a/gcc/testsuite/gcc.dg/c23-tag-5.c
+++ b/gcc/testsuite/gcc.dg/c23-tag-5.c
@@ -1,5 +1,6 @@
-/* { dg-do run { target { ! "*-*-*" } } }
- * { dg-options "-std=c23" }
+/*
+ * { dg-do run }
+ * { dg-options "-std=c2x" }
  */
 
 // nesting and parameters
diff --git a/gcc/testsuite/gcc.dg/c23-tag-alias-1.c b/gcc/testsuite/gcc.dg/c23-tag-alias-1.c
new file mode 100644
index 00000000000..6704ba9c8b4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-alias-1.c
@@ -0,0 +1,48 @@
+/*
+ * { dg-do run }
+ * { dg-options "-std=c23 -O2" }
+ */
+
+
+struct foo { int x; };
+
+int test_foo(struct foo* a, void* b)
+{
+	a->x = 1;
+
+	struct foo { int x; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+enum bar { A = 1, B = 3 };
+
+int test_bar(enum bar* a, void* b)
+{
+	*a = A;
+
+	enum bar { A = 1, B = 3 }* p = b;
+	*p = B;
+
+	return *a;
+}
+
+
+int main()
+{
+	struct foo y;
+
+	if (2 != test_foo(&y, &y))
+		__builtin_abort();
+
+	enum bar z;
+
+	if (A == test_bar(&z, &z))
+		__builtin_abort();
+
+	return 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/c23-tag-alias-2.c b/gcc/testsuite/gcc.dg/c23-tag-alias-2.c
new file mode 100644
index 00000000000..555c30a8501
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-alias-2.c
@@ -0,0 +1,73 @@
+/*
+ * { dg-do run }
+ * { dg-options "-std=c23 -O2" }
+ */
+
+
+struct foo { int x; };
+
+int test_foo1(struct foo* a, void* b)
+{
+	a->x = 1;
+
+	struct foo { int x; int y; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+int test_foo2(struct foo* a, void* b)
+{
+	a->x = 1;
+
+	struct fox { int x; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+enum bar { A = 1, B = 3, C = 5, D = 9 };
+
+int test_bar1(enum bar* a, void* b)
+{
+	*a = A;
+
+	enum bar { A = 1, B = 3, C = 6, D = 9 }* p = b;
+	*p = B;
+
+	return *a;
+}
+
+int test_bar2(enum bar* a, void* b)
+{
+	*a = A;
+
+	enum baX { A = 1, B = 3, C = 5, D = 9 }* p = b;
+	*p = B;
+
+	return *a;
+}
+
+
+int main()
+{
+	struct foo y;
+
+	if (1 != test_foo1(&y, &y))
+		__builtin_abort();
+
+	if (1 != test_foo2(&y, &y))
+		__builtin_abort();
+
+	enum bar z;
+
+	if (A == test_bar1(&z, &z))
+		__builtin_abort();
+
+	if (A == test_bar2(&z, &z))
+		__builtin_abort();
+
+	return 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/c23-tag-alias-3.c b/gcc/testsuite/gcc.dg/c23-tag-alias-3.c
new file mode 100644
index 00000000000..122e8806af8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-alias-3.c
@@ -0,0 +1,48 @@
+/*
+ * { dg-do run }
+ * { dg-options "-std=c23 -flto -O2" }
+ */
+
+
+struct foo { int x; };
+
+int test_foo(struct foo* a, void* b)
+{
+	a->x = 1;
+
+	struct foo { int x; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+enum bar { A = 1, B = 3 };
+
+int test_bar(enum bar* a, void* b)
+{
+	*a = A;
+
+	enum bar { A = 1, B = 3 }* p = b;
+	*p = B;
+
+	return *a;
+}
+
+
+int main()
+{
+	struct foo y;
+
+	if (2 != test_foo(&y, &y))
+		__builtin_abort();
+
+	enum bar z;
+
+	if (A == test_bar(&z, &z))
+		__builtin_abort();
+
+	return 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/c23-tag-alias-4.c b/gcc/testsuite/gcc.dg/c23-tag-alias-4.c
new file mode 100644
index 00000000000..d86a174f4a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-alias-4.c
@@ -0,0 +1,73 @@
+/*
+ * { dg-do run }
+ * { dg-options "-std=c23 -flto -O2" }
+ */
+
+
+struct foo { int x; };
+
+int test_foo1(struct foo* a, void* b)
+{
+	a->x = 1;
+
+	struct foo { int x; int y; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+int test_foo2(struct foo* a, void* b)
+{
+	a->x = 1;
+
+	struct fox { int x; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+enum bar { A = 1, B = 3, C = 5, D = 9 };
+
+int test_bar1(enum bar* a, void* b)
+{
+	*a = A;
+
+	enum bar { A = 1, B = 3, C = 6, D = 9 }* p = b;
+	*p = B;
+
+	return *a;
+}
+
+int test_bar2(enum bar* a, void* b)
+{
+	*a = A;
+
+	enum baX { A = 1, B = 3, C = 5, D = 9 }* p = b;
+	*p = B;
+
+	return *a;
+}
+
+
+int main()
+{
+	struct foo y;
+
+	if (1 != test_foo1(&y, &y))
+		__builtin_abort();
+
+	if (1 != test_foo2(&y, &y))
+		__builtin_abort();
+
+	enum bar z;
+
+	if (A == test_bar1(&z, &z))
+		__builtin_abort();
+
+	if (A == test_bar2(&z, &z))
+		__builtin_abort();
+
+	return 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/c23-tag-alias-5.c b/gcc/testsuite/gcc.dg/c23-tag-alias-5.c
new file mode 100644
index 00000000000..4e956720143
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-alias-5.c
@@ -0,0 +1,30 @@
+/* { dg-do run }
+ * { dg-options "-std=c23 -O2" }
+ */
+
+// not sure this is wise, but this was already like thi sbefore
+
+typedef struct { int x; } foo_t;
+
+int test_foo(foo_t* a, void* b)
+{
+	a->x = 1;
+
+	struct { int x; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+int main()
+{
+	foo_t y;
+
+	if (1 != test_foo(&y, &y))
+		__builtin_abort();
+
+	return 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/c23-tag-alias-6.c b/gcc/testsuite/gcc.dg/c23-tag-alias-6.c
new file mode 100644
index 00000000000..3f3e5f01473
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-alias-6.c
@@ -0,0 +1,77 @@
+/*
+ * { dg-do run }
+ * { dg-options "-std=c23 -O2" }
+ */
+
+
+/* We check that we tolerate differences for
+ * optimization.
+ */
+
+
+struct bar0 { int x; int f[3]; int y; };
+
+int test_bar0(struct bar0* a, void* b)
+{
+	a->x = 1;
+
+	struct bar0 { int x; int f[4]; int y; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+
+struct bar1 { int x; int (*f)[3]; };
+
+int test_bar1(struct bar1* a, void* b)
+{
+	a->x = 1;
+
+	struct bar1 { int x; int (*f)[3]; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+struct bar2 { int x; int (*f)[3]; };
+
+int test_bar2(struct bar2* a, void* b)
+{
+	a->x = 1;
+
+	struct bar2 { int x; int (*f)[4]; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+
+int main()
+{
+	// control
+
+	struct bar0 z0;
+
+	if (1 != test_bar0(&z0, &z0))
+		__builtin_abort();
+
+	// this could be different
+	struct bar1 z1;
+
+	if (2 != test_bar1(&z1, &z1))
+		__builtin_abort();
+
+	struct bar2 z2;
+
+	if (2 != test_bar2(&z2, &z2))
+		__builtin_abort();
+
+
+	return 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/c23-tag-alias-7.c b/gcc/testsuite/gcc.dg/c23-tag-alias-7.c
new file mode 100644
index 00000000000..74cf5f212b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-alias-7.c
@@ -0,0 +1,86 @@
+/*
+ * { dg-do run }
+ * { dg-options "-std=c23 -O2" }
+ */
+
+
+
+struct bar { int x; int f[]; };
+
+int test_bar1(struct bar* a, void* b)
+{
+	a->x = 1;
+
+	struct bar { int x; int f[]; }* p = b;
+	struct bar* q = a;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+int test_bar3(struct bar* a, void* b)
+{
+	a->x = 1;
+
+	struct bar { int x; int f[1]; }* p = b;
+	struct bar* q = a;			/* { dg-warning "incompatible" } */
+	p->x = 2;
+
+	return a->x;
+}
+
+
+int test_bar4(struct bar* a, void* b)
+{
+	a->x = 1;
+
+	int n = 3;
+	struct bar { int x; int f[n]; }* p = b;
+	struct bar* q = a;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+struct foo { int x; int f[3]; };
+
+
+int test_foo1(struct foo* a, void* b)
+{
+	a->x = 1;
+
+	int n = 3;
+	struct foo { int x; int f[n]; }* p = b;
+	struct foo* q = a;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+
+int main()
+{
+	struct bar z;
+
+	if (2 != test_bar1(&z, &z))
+		__builtin_abort();
+
+#if 0
+	if (1 != test_bar3(&z, &z))
+		__builtin_abort();
+#endif
+	if (2 != test_bar4(&z, &z))
+		__builtin_abort();
+
+	struct foo y;
+
+	if (2 != test_foo1(&y, &y))
+		__builtin_abort();
+
+	return 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/c23-tag-alias-8.c b/gcc/testsuite/gcc.dg/c23-tag-alias-8.c
new file mode 100644
index 00000000000..7c2ced4de51
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-alias-8.c
@@ -0,0 +1,90 @@
+/*
+ * { dg-do run }
+ * { dg-options "-std=c23 -O2" }
+ */
+
+
+/* We check that we tolerate differences for
+ * optimization.
+ */
+
+struct bar1 { int x; enum A1 { X1 = 1 } f; };
+
+int test_bar1(struct bar1* a, void* b)
+{
+	a->x = 1;
+
+	struct bar1 { int x; enum A1 { X1 = 2 } f; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+struct bar2 { int x; enum A2 { X2 = 1 } f; };
+
+int test_bar2(struct bar2* a, void* b)
+{
+	a->x = 1;
+
+	struct bar2 { int x; enum B2 { X2 = 1 } f; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+
+struct bar3 { int x; enum A3 { X3 = 1 } f; };
+
+int test_bar3(struct bar3* a, void* b)
+{
+	a->x = 1;
+
+	struct bar3 { int x; enum A3 { Y3 = 1 } f; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+struct bar4 { int x; enum { Z4 = 1 } f; };
+
+int test_bar4(struct bar4* a, void* b)
+{
+	a->x = 1;
+
+	struct bar4 { int x; enum { Z4 = 1 } f; }* p = b;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+
+int main()
+{
+	struct bar1 z1;
+
+	if (1 != test_bar1(&z1, &z1))
+		__builtin_abort();
+
+	struct bar2 z2;
+
+	if (1 != test_bar2(&z2, &z2))
+		__builtin_abort();
+
+	struct bar3 z3;
+
+	if (1 != test_bar3(&z3, &z3))
+		__builtin_abort();
+
+	struct bar4 z4;
+
+	if (1 != test_bar4(&z4, &z4))
+		__builtin_abort();
+
+	return 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/gnu23-tag-alias-1.c b/gcc/testsuite/gcc.dg/gnu23-tag-alias-1.c
new file mode 100644
index 00000000000..9bccc651afb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu23-tag-alias-1.c
@@ -0,0 +1,33 @@
+/*
+ * { dg-do run }
+ * { dg-options "-std=gnu23 -O2" }
+ */
+
+
+
+struct bar { int x; int f[]; };
+
+int test_bar2(struct bar* a, void* b)
+{
+	a->x = 1;
+
+	struct bar { int x; int f[0]; }* p = b;
+	struct bar* q = a;
+	p->x = 2;
+
+	return a->x;
+}
+
+
+
+int main()
+{
+	struct bar z;
+
+	if (2 != test_bar2(&z, &z))
+		__builtin_abort();
+
+	return 0;
+}
+
+
-- 
2.39.2



  parent reply	other threads:[~2023-11-16 21:39 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-16 21:36 c23 type compatibility rules, v3 Martin Uecker
2023-11-16 21:38 ` [PATCH 1/4] c23: tag compatibility rules for struct and unions Martin Uecker
2023-11-23 23:17   ` Joseph Myers
2023-11-16 21:38 ` [PATCH 2/4] c23: tag compatibility rules for enums Martin Uecker
2023-11-23 23:26   ` Joseph Myers
2023-11-16 21:39 ` Martin Uecker [this message]
2023-11-23 23:47   ` [PATCH 3/4] c23: aliasing of compatible tagged types Joseph Myers
2023-11-26 22:48     ` Martin Uecker
2023-11-27  7:46       ` Richard Biener
2023-11-28  1:00       ` Joseph Myers
2023-11-28  6:49         ` Martin Uecker
2023-11-28 10:47         ` Richard Biener
2023-11-28 11:51           ` Martin Uecker
2023-11-16 21:40 ` [PATCH 4/4] c23: construct composite type for " Martin Uecker
2023-11-27 13:16 ` [V4] [C PATCH 1/4] c23: tag compatibility rules for struct and unions Martin Uecker
2023-12-14 20:53   ` Joseph Myers
2023-11-27 13:16 ` [V4] [PATCH 2/4] c23: tag compatibility rules for enums Martin Uecker
2023-12-14 20:58   ` Joseph Myers
2023-11-27 13:16 ` [V4] [PATCH 3/4] c23: aliasing of compatible tagged types Martin Uecker
2023-12-14 21:10   ` Joseph Myers
2023-11-27 13:16 ` [V4] [PATCH 4/4] c23: construct composite type for " Martin Uecker
2023-12-17 17:41 ` [V5] [C PATCH 1/4] c23: tag compatibility rules for struct and unions Martin Uecker
2023-12-19 21:48   ` Joseph Myers
2023-12-17 17:42 ` [V5] [C PATCH 2/4] c23: tag compatibility rules for enums Martin Uecker
2023-12-19 21:50   ` Joseph Myers
2023-12-17 17:42 ` [V5] [C PATCH 3/4] c23: aliasing of compatible tagged types Martin Uecker
2023-12-19 22:02   ` Joseph Myers
2023-12-17 17:42 ` [V5] [C PATCH 4/4] c23: construct composite type for " Martin Uecker
2023-12-19 22:25   ` Joseph Myers
2023-12-21 21:47 ` [V6] " Martin Uecker
2023-12-22 16:27   ` Joseph Myers
2023-12-27 19:23 ` [C PATCH] C: Fix type compatibility for structs with variable sized fields Martin Uecker
2023-12-29 15:57   ` Joseph Myers
2024-01-27 16:10 ` Fix ICE with -g and -std=c23 when forming composite types [PR113438] Martin Uecker
2024-01-29 20:27   ` Joseph Myers
2024-04-02 18:54 ` [C PATCH] Fix ICE with -g and -std=c23 related to incomplete types [PR114361] Martin Uecker
2024-04-02 20:31   ` Joseph Myers
2024-04-02 19:02 ` [C PATCH] fix aliasing for structures/unions with incomplete types Martin Uecker
2024-04-02 20:42   ` Joseph Myers
2024-04-02 21:22     ` Martin Uecker
2024-04-03 15:33       ` Joseph Myers
2024-04-14 12:30 ` [C PATCH, v2] Fix ICE with -g and -std=c23 related to incomplete types [PR114361] Martin Uecker
2024-04-14 12:38   ` Martin Uecker
2024-04-15  6:55   ` Richard Biener
2024-04-15  7:38     ` Jakub Jelinek
2024-04-15  7:59       ` Jakub Jelinek
2024-04-15  8:02         ` Richard Biener
2024-04-15  8:05           ` Jakub Jelinek
2024-04-15 10:48             ` [PATCH] c, v3: " Jakub Jelinek
2024-04-15 11:33               ` Richard Biener
2024-04-16  7:20                 ` Jakub Jelinek
2024-04-19 20:39               ` Joseph Myers
2024-04-15  7:03   ` [C PATCH, v2] " Jakub Jelinek
2024-05-18 13:27 ` [C PATCH] Fix for some variably modified types not being recognized [PR114831] Martin Uecker
2024-05-18 13:29   ` Martin Uecker
2024-05-20 21:18   ` Joseph Myers
2024-05-18 20:18 ` [C PATCH] Fix for redeclared enumerator initialized with different type [PR115109] Martin Uecker
2024-05-19 10:24   ` [C PATCH, v2] " Martin Uecker
2024-05-20 21:30     ` Joseph Myers
2024-05-21  5:40       ` Martin Uecker
2024-05-23 20:51         ` Joseph Myers
2024-05-21 12:18   ` [C PATCH]: allow aliasing of compatible types derived from enumeral types [PR115157] Martin Uecker
2024-05-23 20:59     ` Joseph Myers
2024-05-23 21:30       ` Ian Lance Taylor
2024-05-23 21:47         ` Martin Uecker
2024-05-23 21:53           ` Ian Lance Taylor
2024-05-24  5:56             ` Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=223aa096afbdbb177d4ad5245696d439ad4cf87f.camel@tugraz.at \
    --to=uecker@tugraz.at \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=joseph@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).