]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Revert very recent backport of changes to the type system
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 14 Apr 2025 21:35:43 +0000 (23:35 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Mon, 14 Apr 2025 21:59:20 +0000 (23:59 +0200)
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  <uecker@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  <uecker@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

gcc/lto/lto-common.cc
gcc/testsuite/gcc.dg/pr113688.c [deleted file]
gcc/testsuite/gcc.dg/pr114014.c [deleted file]
gcc/testsuite/gcc.dg/pr114713.c [deleted file]
gcc/testsuite/gcc.dg/pr117724.c [deleted file]
gcc/tree.cc

index 7697a7d6ea02bf0c730c074b8ead342c4bfd92a8..2ce94cc32828ca0073e8501a581c113f6f2c4143 100644 (file)
@@ -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 (file)
index 8dee8c8..0000000
+++ /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 (file)
index 1531ffa..0000000
+++ /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 (file)
index 78e3237..0000000
+++ /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 (file)
index d631dae..0000000
+++ /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" } */
-
index a4c62e1f068152cf875cfadcda2a3584b9b4b50e..d716d7ccfe317944b14295033b7f86eb28cf1e7a 100644 (file)
@@ -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");