https://gcc.gnu.org/g:5457388f58262bee41ae1d744ff6f3da34119e2d
commit r14-11611-g5457388f58262bee41ae1d744ff6f3da34119e2d Author: Eric Botcazou <ebotca...@adacore.com> Date: Mon Apr 14 23:35:43 2025 +0200 Revert very recent backport of changes to the type system The backport of the change made for PR c/113688 onto the 14 branch a couple of weeks ago has seriously broken the LTO compiler for the Ada language on the 14 branch, because it changes the GCC type system for the sake of C in a way that is not compatible with simple discriminated types in Ada. To be more precise, useless_type_conversion_p now returns true for some (view-) conversions that are needed by the rest of the compiler. gcc/ PR lto/119792 Revert Backported from master: 2024-12-12 Martin Uecker <uec...@tugraz.at> PR c/113688 PR c/114014 PR c/114713 PR c/117724 * tree.cc (gimple_canonical_types_compatible_p): Add exception. (verify_type): Add exception. gcc/lto/ PR lto/119792 Revert Backported from master: 2024-12-12 Martin Uecker <uec...@tugraz.at> * lto-common.cc (hash_canonical_type): Add exception. gcc/testsuite/ * gcc.dg/pr113688.c: Delete. * gcc.dg/pr114014.c: Likewise. * gcc.dg/pr114713.c: Likewise. * gcc.dg/pr117724.c: Likewise Diff: --- gcc/lto/lto-common.cc | 9 ++------ gcc/testsuite/gcc.dg/pr113688.c | 8 ------- gcc/testsuite/gcc.dg/pr114014.c | 14 ------------ gcc/testsuite/gcc.dg/pr114713.c | 35 ----------------------------- gcc/testsuite/gcc.dg/pr117724.c | 16 -------------- gcc/tree.cc | 49 +++++++++-------------------------------- 6 files changed, 12 insertions(+), 119 deletions(-) diff --git a/gcc/lto/lto-common.cc b/gcc/lto/lto-common.cc index 7697a7d6ea02..2ce94cc32828 100644 --- a/gcc/lto/lto-common.cc +++ b/gcc/lto/lto-common.cc @@ -254,8 +254,7 @@ hash_canonical_type (tree type) checked. */ code = tree_code_for_canonical_type_merging (TREE_CODE (type)); hstate.add_int (code); - if (!RECORD_OR_UNION_TYPE_P (type)) - hstate.add_int (TYPE_MODE (type)); + hstate.add_int (TYPE_MODE (type)); /* Incorporate common features of numerical types. */ if (INTEGRAL_TYPE_P (type) @@ -333,11 +332,7 @@ hash_canonical_type (tree type) && (! DECL_SIZE (f) || ! integer_zerop (DECL_SIZE (f)))) { - tree t = TREE_TYPE (f); - if (!TREE_CHAIN (f) - && TREE_CODE (t) == ARRAY_TYPE) - t = TREE_TYPE (t); - iterative_hash_canonical_type (t, hstate); + iterative_hash_canonical_type (TREE_TYPE (f), hstate); nf++; } diff --git a/gcc/testsuite/gcc.dg/pr113688.c b/gcc/testsuite/gcc.dg/pr113688.c deleted file mode 100644 index 8dee8c86f1bf..000000000000 --- a/gcc/testsuite/gcc.dg/pr113688.c +++ /dev/null @@ -1,8 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-g" } */ - -struct S{int x,y[1];}*a; -int main(void){ - struct S{int x,y[];}; -} - diff --git a/gcc/testsuite/gcc.dg/pr114014.c b/gcc/testsuite/gcc.dg/pr114014.c deleted file mode 100644 index 1531ffab1b75..000000000000 --- a/gcc/testsuite/gcc.dg/pr114014.c +++ /dev/null @@ -1,14 +0,0 @@ -/* PR c/114014 - * { dg-do compile } - * { dg-options "-std=gnu23 -g" } */ - -struct r { - int a; - char b[]; -}; -struct r { - int a; - char b[0]; -}; - - diff --git a/gcc/testsuite/gcc.dg/pr114713.c b/gcc/testsuite/gcc.dg/pr114713.c deleted file mode 100644 index 78e3237de948..000000000000 --- a/gcc/testsuite/gcc.dg/pr114713.c +++ /dev/null @@ -1,35 +0,0 @@ -/* { dg-do run } */ -/* { dg-require-effective-target lto } */ -/* { dg-options "-std=c23 -flto -O2" } */ - -struct foo { int x; char a[]; }; - -void test_bar(void* b); - -__attribute__((noinline)) -int test_foo(struct foo* a, void* b) -{ - a->x = 1; - test_bar(b); - return a->x; -} - -int main() -{ - struct foo y; - - if (2 != test_foo(&y, &y)) - __builtin_abort(); - - return 0; -} - -// TU2 -struct foo { int x; char a[0]; }; - -void test_bar(void* b) -{ - struct foo *p = b; - p->x = 2; -} - diff --git a/gcc/testsuite/gcc.dg/pr117724.c b/gcc/testsuite/gcc.dg/pr117724.c deleted file mode 100644 index d631daeb644d..000000000000 --- a/gcc/testsuite/gcc.dg/pr117724.c +++ /dev/null @@ -1,16 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-g" } */ - -struct { - unsigned long len; - unsigned long size; - char data[]; -}; /* { dg-warning "unnamed struct" } */ -struct { - struct { - unsigned long len; - unsigned long size; - char data[6]; - }; -}; /* { dg-warning "unnamed struct" } */ - diff --git a/gcc/tree.cc b/gcc/tree.cc index a4c62e1f0681..d716d7ccfe31 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -13846,11 +13846,8 @@ gimple_canonical_types_compatible_p (const_tree t1, const_tree t2, || TREE_CODE (t1) == NULLPTR_TYPE) return true; - /* Can't be compatible types if they have different mode. Because of - flexible array members, we allow mismatching modes for structures or - unions. */ - if (!RECORD_OR_UNION_TYPE_P (t1) - && TYPE_MODE (t1) != TYPE_MODE (t2)) + /* Can't be the same type if they have different mode. */ + if (TYPE_MODE (t1) != TYPE_MODE (t2)) return false; /* Non-aggregate types can be handled cheaply. */ @@ -13901,7 +13898,7 @@ gimple_canonical_types_compatible_p (const_tree t1, const_tree t2, { case ARRAY_TYPE: /* Array types are the same if the element types are the same and - minimum and maximum index are the same. */ + the number of elements are the same. */ if (!gimple_canonical_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2), trust_type_canonical) || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2) @@ -13995,46 +13992,23 @@ gimple_canonical_types_compatible_p (const_tree t1, const_tree t2, f1 || f2; f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2)) { - /* Skip non-fields and zero-sized fields, except zero-sized - arrays at the end. */ + /* Skip non-fields and zero-sized fields. */ while (f1 && (TREE_CODE (f1) != FIELD_DECL || (DECL_SIZE (f1) - && integer_zerop (DECL_SIZE (f1)) - && (TREE_CHAIN (f1) - || TREE_CODE (TREE_TYPE (f1)) - != ARRAY_TYPE)))) + && integer_zerop (DECL_SIZE (f1))))) f1 = TREE_CHAIN (f1); while (f2 && (TREE_CODE (f2) != FIELD_DECL || (DECL_SIZE (f2) - && integer_zerop (DECL_SIZE (f2)) - && (TREE_CHAIN (f2) - || TREE_CODE (TREE_TYPE (f2)) - != ARRAY_TYPE)))) + && integer_zerop (DECL_SIZE (f2))))) f2 = TREE_CHAIN (f2); if (!f1 || !f2) break; - - tree t1 = TREE_TYPE (f1); - tree t2 = TREE_TYPE (f2); - - /* If the last element are arrays, we only compare the element - types. */ - if (TREE_CHAIN (f1) == NULL_TREE && TREE_CODE (t1) == ARRAY_TYPE - && TREE_CHAIN (f2) == NULL_TREE && TREE_CODE (t2) == ARRAY_TYPE) - { - /* If both arrays have zero size, this is a match. */ - if (DECL_SIZE (f1) && integer_zerop (DECL_SIZE (f1)) - && DECL_SIZE (f2) && integer_zerop (DECL_SIZE (f2))) - return true; - - t1 = TREE_TYPE (t1); - t2 = TREE_TYPE (t2); - } - + /* The fields must have the same name, offset and type. */ if (DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2) || !gimple_compare_field_offset (f1, f2) || !gimple_canonical_types_compatible_p - (t1, t2, trust_type_canonical)) + (TREE_TYPE (f1), TREE_TYPE (f2), + trust_type_canonical)) return false; } @@ -14176,11 +14150,8 @@ verify_type (const_tree t) debug_tree (ct); error_found = true; } + if (COMPLETE_TYPE_P (t) && TYPE_CANONICAL (t) - /* We allow a mismatch for structure or union because of - flexible array members. */ - && !RECORD_OR_UNION_TYPE_P (t) - && !RECORD_OR_UNION_TYPE_P (TYPE_CANONICAL (t)) && TYPE_MODE (t) != TYPE_MODE (TYPE_CANONICAL (t))) { error ("%<TYPE_MODE%> of %<TYPE_CANONICAL%> is not compatible");