This fixes the gimple_check_call_args routine to properly check
for compatible aggregate types, something fold_convertible
(which is otherwise more forgiving) does not handle.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-04-10  Richard Guenther  <rguent...@suse.de>

        PR middle-end/52888
        * gimple-low.c (gimple_check_call_args): Properly account for
        compatible aggregate types.

Index: gcc/gimple-low.c
===================================================================
--- gcc/gimple-low.c    (revision 186273)
+++ gcc/gimple-low.c    (working copy)
@@ -240,15 +240,17 @@ gimple_check_call_args (gimple stmt, tre
           i < nargs;
           i++, p = DECL_CHAIN (p))
        {
+         tree arg;
          /* We cannot distinguish a varargs function from the case
             of excess parameters, still deferring the inlining decision
             to the callee is possible.  */
          if (!p)
            break;
+         arg = gimple_call_arg (stmt, i);
          if (p == error_mark_node
-             || gimple_call_arg (stmt, i) == error_mark_node
-             || !fold_convertible_p (DECL_ARG_TYPE (p),
-                                     gimple_call_arg (stmt, i)))
+             || arg == error_mark_node
+             || (!types_compatible_p (DECL_ARG_TYPE (p), TREE_TYPE (arg))
+                 && !fold_convertible_p (DECL_ARG_TYPE (p), arg)))
             return false;
        }
     }
@@ -256,15 +258,17 @@ gimple_check_call_args (gimple stmt, tre
     {
       for (i = 0, p = parms; i < nargs; i++, p = TREE_CHAIN (p))
        {
+         tree arg;
          /* If this is a varargs function defer inlining decision
             to callee.  */
          if (!p)
            break;
+         arg = gimple_call_arg (stmt, i);
          if (TREE_VALUE (p) == error_mark_node
-             || gimple_call_arg (stmt, i) == error_mark_node
+             || arg == error_mark_node
              || TREE_CODE (TREE_VALUE (p)) == VOID_TYPE
-             || !fold_convertible_p (TREE_VALUE (p),
-                                     gimple_call_arg (stmt, i)))
+             || (!types_compatible_p (TREE_VALUE (p), TREE_TYPE (arg))
+                 && !fold_convertible_p (TREE_VALUE (p), arg)))
             return false;
        }
     }

Reply via email to