diff mbox

[Ada] Fix inter-unit inlining failure

Message ID 1545700.L1oGMoZcMl@polaris
State New
Headers show

Commit Message

Eric Botcazou Oct. 10, 2016, 9:49 a.m. UTC
This is a regression present on the mainline and 6 branch: the compiler fails 
to inline across units a function declared with pragma Inline_Always because 
the middle-end detects a type mismatch for an argument, after gimplification 
removed a conversion.  The fix is to make the conversion more robust.

Tested on x86_64-suse-linux, applied on mainline and 6 branch.


2016-10-10  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/utils2.c (find_common_type): Do not return the LHS
	type if it's an array with non-constant lower bound and the RHS type
	is an array with a constant one.


2016-10-10  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/inline13.ad[sb]: New test.
	* gnat.dg/inline13_pkg.ad[sb]: New helper.
diff mbox

Patch

Index: gcc-interface/utils2.c
===================================================================
--- gcc-interface/utils2.c	(revision 240890)
+++ gcc-interface/utils2.c	(working copy)
@@ -215,27 +215,40 @@  find_common_type (tree t1, tree t2)
      calling into build_binary_op), some others are really expected and we
      have to be careful.  */
 
+  const bool variable_record_on_lhs
+    = (TREE_CODE (t1) == RECORD_TYPE
+       && TREE_CODE (t2) == RECORD_TYPE
+       && get_variant_part (t1)
+       && !get_variant_part (t2));
+
+  const bool variable_array_on_lhs
+    = (TREE_CODE (t1) == ARRAY_TYPE
+       && TREE_CODE (t2) == ARRAY_TYPE
+       && !TREE_CONSTANT (TYPE_MIN_VALUE (TYPE_DOMAIN (t1)))
+       && TREE_CONSTANT (TYPE_MIN_VALUE (TYPE_DOMAIN (t2))));
+
   /* We must avoid writing more than what the target can hold if this is for
      an assignment and the case of tagged types is handled in build_binary_op
      so we use the lhs type if it is known to be smaller or of constant size
      and the rhs type is not, whatever the modes.  We also force t1 in case of
      constant size equality to minimize occurrences of view conversions on the
-     lhs of an assignment, except for the case of record types with a variant
-     part on the lhs but not on the rhs to make the conversion simpler.  */
+     lhs of an assignment, except for the case of types with a variable part
+     on the lhs but not on the rhs to make the conversion simpler.  */
   if (TREE_CONSTANT (TYPE_SIZE (t1))
       && (!TREE_CONSTANT (TYPE_SIZE (t2))
 	  || tree_int_cst_lt (TYPE_SIZE (t1), TYPE_SIZE (t2))
 	  || (TYPE_SIZE (t1) == TYPE_SIZE (t2)
-	      && !(TREE_CODE (t1) == RECORD_TYPE
-		   && TREE_CODE (t2) == RECORD_TYPE
-		   && get_variant_part (t1)
-		   && !get_variant_part (t2)))))
+	      && !variable_record_on_lhs
+	      && !variable_array_on_lhs)))
     return t1;
 
-  /* Otherwise, if the lhs type is non-BLKmode, use it.  Note that we know
-     that we will not have any alignment problems since, if we did, the
-     non-BLKmode type could not have been used.  */
-  if (TYPE_MODE (t1) != BLKmode)
+  /* Otherwise, if the lhs type is non-BLKmode, use it, except for the case of
+     a non-BLKmode rhs and array types with a variable part on the lhs but not
+     on the rhs to make sure the conversion is preserved during gimplification.
+     Note that we know that we will not have any alignment problems since, if
+     we did, the non-BLKmode type could not have been used.  */
+  if (TYPE_MODE (t1) != BLKmode
+      && (TYPE_MODE (t2) == BLKmode || !variable_array_on_lhs))
     return t1;
 
   /* If the rhs type is of constant size, use it whatever the modes.  At