------- 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