This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/22371] C front-end produces mis-match types in MODIFY_EXPR
- From: "rguenther at suse dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 22 Aug 2007 13:45:54 -0000
- Subject: [Bug c/22371] C front-end produces mis-match types in MODIFY_EXPR
- References: <bug-22371-6528@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #9 from rguenther at suse dot de 2007-08-22 13:45 -------
Subject: Re: C front-end produces mis-match types in MODIFY_EXPR
On Wed, 22 Aug 2007, joseph at codesourcery dot com wrote:
> ------- Comment #8 from joseph at codesourcery dot com 2007-08-22 13:12 -------
> Subject: Re: C front-end produces mis-match types in MODIFY_EXPR
>
> > The real problem is that the frontend creates a conversion to (int[] *) rather
> > than (A5 *) which is the type of ap at gimplification time. The patch
> > doesn't address this, but merely forces the conversion to (int[] *) which is
> > there also without the patch.
>
> I think the C gimplifier should accept such assignments between compatible
> types (not other pairs of types that can be assigned in C, just compatible
> types) and generate whatever conversions are needed for valid GIMPLE at
> that point.
Ok, so when gimplifying a MODIFY_EXPR the following works:
gcc_assert (lang_hooks.types_compatible_p (TREE_TYPE (*to_p),
TREE_TYPE (*from_p)));
that is, as far as C is concerned, (int[] *) is convertible to (int[5] *).
Now, it is also convertible the other way around which is why
the conversion to (int[] *) is useless on the RHS -- but the conversion
from (int[10] *) to (int[5] *) is not useless, as they are not
compatible types as far as C is concerned.
So, strictly speaking, this special property of (int[] *) breaks
transitiveness of the useless_type_converison_p middle-end type-system
predicate.
We can fix things up in the gimplifier as you suggest by doing
(for gimplifying MODIFY_EXPR):
gcc_assert (lang_hooks.types_compatible_p (TREE_TYPE (*to_p),
TREE_TYPE (*from_p)));
STRIP_USELESS_TYPE_CONVERSION (*from_p);
if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
*from_p = fold_convert (TREE_TYPE (*to_p), *from_p);
which in the case of this PR re-inserts (after stripping the cast
to (int[] *))
array10.0 = (int[5] *) &array10;
ap = array10.0;
As far as I see we still need to re-instantiate transitiveness
of useless_type_converison_p somehow, by handling all of the
aggregate type compatibilities in the middle-end without dispatching
back to the frontends. Like with something like
Index: tree-ssa.c
===================================================================
--- tree-ssa.c (revision 127700)
+++ tree-ssa.c (working copy)
@@ -1019,6 +1019,31 @@ useless_type_conversion_p (tree outer_ty
return useless_type_conversion_p (TREE_TYPE (outer_type),
TREE_TYPE (inner_type));
+ /* For array types we have to consider element types and array domain. */
+ else if (TREE_CODE (inner_type) == ARRAY_TYPE
+ && TREE_CODE (outer_type) == ARRAY_TYPE)
+ {
+ /* If the element types are not trivially convertible, the
+ arrays are not compatible. */
+ if (!useless_type_conversion_p (TREE_TYPE (outer_type),
+ TREE_TYPE (inner_type)))
+ return false;
+
+ /* A conversion to an unknown domain is useless. */
+ if (!TYPE_DOMAIN (outer_type))
+ return true;
+
+ /* Likewise a conversion to a equal domain. */
+ if (TYPE_DOMAIN (outer_type)
+ && TYPE_DOMAIN (inner_type))
+ return (operand_equal_p (TYPE_MIN_VALUE (TYPE_DOMAIN (outer_type)),
+ TYPE_MIN_VALUE (TYPE_DOMAIN (inner_type)), 0)
+ && operand_equal_p (TYPE_MAX_VALUE (TYPE_DOMAIN (outer_type)),
+ TYPE_MAX_VALUE (TYPE_DOMAIN (inner_type)),
0));
+
+ return false;
+ }
+
/* For aggregates we may need to fall back to structural equality
checks. */
else if (AGGREGATE_TYPE_P (inner_type)
still this would need fixing up the types during gimplification as
int[5] * = (int[] *)&int[10];
with the patch above lacks the cast to (int[5] *).
I see that Honza is thinking of a type merging/fixup "pass" anyway, but
I wonder if the frontend is really "unfixable" here (supposedly the
proposed fixup to the gimplifier above could be done in the gimplify_expr
langhook as well, to not "pessimize" other frontends).
Richard.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22371