This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/22371] C front-end produces mis-match types in MODIFY_EXPR



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]