From 38c33fd2b5967f52144226a19f761fac8f85ea32 Mon Sep 17 00:00:00 2001 From: Martin Uecker <uecker@tugraz.at> Date: Fri, 22 Dec 2023 17:32:34 +0100 Subject: [PATCH] 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. --- gcc/c/c-typeck.cc | 19 ++++++++----------- gcc/testsuite/gcc.dg/c23-tag-9.c | 8 ++++++++ 2 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/c23-tag-9.c diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 2d9139d09d24..84ddda1ebab6 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 000000000000..1d32560ec237 --- /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); + + -- GitLab