Fix PR lto/119792

Message ID 9860997.eNJFYEL58v@fomalhaut
State New
Headers
Series Fix PR lto/119792 |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap fail Patch failed to apply
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap fail Patch failed to apply

Commit Message

Eric Botcazou April 14, 2025, 10 p.m. UTC
  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 (view-) conversions that are
needed by the rest of the compiler.

PR c/113688 is not a regression so it was agreed that the backport should be 
reverted on the 14 branch, while the status quo is kept on the mainline (and 
future 15 branch), where the change is equally problematic, until a way out is 
devised for Ada.

Tested on x86-64/Linux, applied on the 14 branch.


2025-04-14 Eric Botcazou  <ebotcazou@adacore.com>

	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.
lto/
	* lto-common.cc (hash_canonical_type): Add exception.
  

Patch

diff --git a/gcc/lto/lto-common.cc b/gcc/lto/lto-common.cc
index 7697a7d6ea0..2ce94cc3282 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/tree.cc b/gcc/tree.cc
index a4c62e1f068..d716d7ccfe3 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");