aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Uecker <uecker@tugraz.at>2023-12-22 17:32:34 +0100
committerMartin Uecker <uecker@tugraz.at>2023-12-30 22:32:51 +0100
commit38c33fd2b5967f52144226a19f761fac8f85ea32 (patch)
treed9dbaecf15695059ce9027f470bb84515de74d44
parent77f30e22f179f23e85ab4ab09209aca33190f30c (diff)
downloadgcc-38c33fd2b5967f52144226a19f761fac8f85ea32.zip
gcc-38c33fd2b5967f52144226a19f761fac8f85ea32.tar.gz
gcc-38c33fd2b5967f52144226a19f761fac8f85ea32.tar.bz2
C: Fix type compatibility for structs with variable sized fields.
This fixes the test gcc.dg/gnu23-tag-4.c introduced by commit 23fee88f which fails for -march=... because the DECL_FIELD_BIT_OFFSET are set inconsistently for types with and without variable-sized field. This is fixed by testing for DECL_ALIGN instead. The code is further simplified by removing some unnecessary conditions, i.e. anon_field is set unconditionaly and all fields are assumed to be DECL_FIELDs. gcc/c: * c-typeck.cc (tagged_types_tu_compatible_p): Revise. gcc/testsuite: * gcc.dg/c23-tag-9.c: New test.
-rw-r--r--gcc/c/c-typeck.cc19
-rw-r--r--gcc/testsuite/gcc.dg/c23-tag-9.c8
2 files changed, 16 insertions, 11 deletions
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 2d9139d..84ddda1 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -1511,8 +1511,6 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
if (!data->anon_field && TYPE_STUB_DECL (t1) != TYPE_STUB_DECL (t2))
data->different_types_p = true;
- data->anon_field = false;
-
/* Incomplete types are incompatible inside a TU. */
if (TYPE_SIZE (t1) == NULL || TYPE_SIZE (t2) == NULL)
return false;
@@ -1592,22 +1590,21 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
s1 && s2;
s1 = DECL_CHAIN (s1), s2 = DECL_CHAIN (s2))
{
- if (TREE_CODE (s1) != TREE_CODE (s2)
- || DECL_NAME (s1) != DECL_NAME (s2))
+ gcc_assert (TREE_CODE (s1) == FIELD_DECL);
+ gcc_assert (TREE_CODE (s2) == FIELD_DECL);
+
+ if (DECL_NAME (s1) != DECL_NAME (s2))
+ return false;
+
+ if (DECL_ALIGN (s1) != DECL_ALIGN (s2))
return false;
- if (!DECL_NAME (s1) && RECORD_OR_UNION_TYPE_P (TREE_TYPE (s1)))
- data->anon_field = true;
+ data->anon_field = !DECL_NAME (s1);
data->cache = &entry;
if (!comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2), data))
return false;
- if (TREE_CODE (s1) == FIELD_DECL
- && 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));
diff --git a/gcc/testsuite/gcc.dg/c23-tag-9.c b/gcc/testsuite/gcc.dg/c23-tag-9.c
new file mode 100644
index 0000000..1d32560
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-9.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23" } */
+
+struct foo { int x; } x;
+struct foo { alignas(128) int x; } y; /* { dg-error "redefinition" } */
+static_assert(alignof(y) == 128);
+
+