]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/16876 (ICE on testcase with -O3 in fold-const)
authorRichard Guenther <rguenther@suse.de>
Sat, 23 Jun 2007 18:17:57 +0000 (18:17 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Sat, 23 Jun 2007 18:17:57 +0000 (18:17 +0000)
2007-06-23  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/16876
PR middle-end/29478
* tree.h (CALL_CANNOT_INLINE_P): New macro to access static_flag
for CALL_EXPRs.
* tree-inline.c (initialize_inlined_parameters): Do not call
lang_hooks.tree_inlining.convert_parm_for_inlining.
* cgraphbuild.c (initialize_inline_failed): Set inline failed
reason for mismatched types.
* gimplify.c (gimplify_call_expr): Verify the call expression
arguments match the called function type signature.  Otherwise
mark the call expression to be not considered for inlining
using CALL_CANNOT_INLINE_P flag.
* ipa-inline.c (cgraph_mark_inline): Honor CALL_CANNOT_INLINE_P on the
edges call expression.
(cgraph_decide_inlining_of_small_function): Likewise.
(cgraph_decide_inlining): Likewise.
* c-objc-common.h (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
Remove define.
* c-tree.h (c_convert_parm_for_inlining): Remove declaration.
* c-typeck.c (c_convert_parm_for_inlining): Remove.
* langhooks-def.h (lhd_tree_inlining_convert_parm_for_inlining):
Remove declaration.
(LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING): Remove define.
* langhooks.c (lhd_tree_inlining_convert_parm_for_inlining):
Remove.
* langhooks.h (struct lang_hooks_for_tree_inlining): Remove
convert_parm_for_inlining member.

* gcc.dg/pr29254.c: The warning is bogus.
* gcc.dg/warn-1.c: Likewise.
* gcc.dg/assign-warn-3.c: Likewise.
* gcc.dg/noncompile/pr16876.c: The testcase is bogus, remove.

From-SVN: r125974

17 files changed:
gcc/ChangeLog
gcc/c-objc-common.h
gcc/c-tree.h
gcc/c-typeck.c
gcc/cgraphbuild.c
gcc/gimplify.c
gcc/ipa-inline.c
gcc/langhooks-def.h
gcc/langhooks.c
gcc/langhooks.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/assign-warn-3.c
gcc/testsuite/gcc.dg/noncompile/pr16876.c [deleted file]
gcc/testsuite/gcc.dg/pr29254.c
gcc/testsuite/gcc.dg/warn-1.c
gcc/tree-inline.c
gcc/tree.h

index 9ea41e117635e0ab3f8014dea12d3a114df44580..6756a73fc78230a64974092f66d27571c9828e46 100644 (file)
@@ -1,3 +1,33 @@
+2007-06-23  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/16876
+       PR middle-end/29478
+       * tree.h (CALL_CANNOT_INLINE_P): New macro to access static_flag
+       for CALL_EXPRs.
+       * tree-inline.c (initialize_inlined_parameters): Do not call
+       lang_hooks.tree_inlining.convert_parm_for_inlining.
+       * cgraphbuild.c (initialize_inline_failed): Set inline failed
+       reason for mismatched types.
+       * gimplify.c (gimplify_call_expr): Verify the call expression
+       arguments match the called function type signature.  Otherwise
+       mark the call expression to be not considered for inlining
+       using CALL_CANNOT_INLINE_P flag.
+       * ipa-inline.c (cgraph_mark_inline): Honor CALL_CANNOT_INLINE_P on the
+       edges call expression.
+       (cgraph_decide_inlining_of_small_function): Likewise.
+       (cgraph_decide_inlining): Likewise.
+       * c-objc-common.h (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
+       Remove define.
+       * c-tree.h (c_convert_parm_for_inlining): Remove declaration.
+       * c-typeck.c (c_convert_parm_for_inlining): Remove.
+       * langhooks-def.h (lhd_tree_inlining_convert_parm_for_inlining):
+       Remove declaration.
+       (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING): Remove define.
+       * langhooks.c (lhd_tree_inlining_convert_parm_for_inlining):
+       Remove.
+       * langhooks.h (struct lang_hooks_for_tree_inlining): Remove
+       convert_parm_for_inlining member.
+
 2007-06-23  Richard Earnshaw  <rearnsha@arm.com>
 
        PR target/31152
index e6a82efd4aef8a172d8acc06d4066ef7dfdb0fb8..171e702e59d3064ef5e2910a545b5063b137d082 100644 (file)
@@ -89,9 +89,6 @@ extern void c_initialize_diagnostics (diagnostic_context *);
 #undef LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS
 #define LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS \
   c_disregard_inline_limits
-#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
-#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
-  c_convert_parm_for_inlining
 #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
 #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN c_dump_tree
 
index e5f4a153fd550a24e7e770df80cda0f3c1c25922..3bc98507eaf4927e479b257352ae506043bbb9e6 100644 (file)
@@ -577,7 +577,6 @@ extern tree c_start_case (tree);
 extern void c_finish_case (tree);
 extern tree build_asm_expr (tree, tree, tree, tree, bool);
 extern tree build_asm_stmt (tree, tree);
-extern tree c_convert_parm_for_inlining (tree, tree, tree, int);
 extern int c_types_compatible_p (tree, tree);
 extern tree c_begin_compound_stmt (bool);
 extern tree c_end_compound_stmt (tree, bool);
index 9811d873d3810781ec576336c7f1146227fdf9d3..2a19f0875fb571b11048217b0b3bd344796fc924 100644 (file)
@@ -4247,37 +4247,6 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
 
   return error_mark_node;
 }
-
-/* Convert VALUE for assignment into inlined parameter PARM.  ARGNUM
-   is used for error and warning reporting and indicates which argument
-   is being processed.  */
-
-tree
-c_convert_parm_for_inlining (tree parm, tree value, tree fn, int argnum)
-{
-  tree ret, type;
-
-  /* If FN was prototyped at the call site, the value has been converted
-     already in convert_arguments.
-     However, we might see a prototype now that was not in place when
-     the function call was seen, so check that the VALUE actually matches
-     PARM before taking an early exit.  */
-  if (!value
-      || (TYPE_ARG_TYPES (TREE_TYPE (fn))
-         && (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
-             == TYPE_MAIN_VARIANT (TREE_TYPE (value)))))
-    return value;
-
-  type = TREE_TYPE (parm);
-  ret = convert_for_assignment (type, value,
-                               ic_argpass_nonproto, fn,
-                               fn, argnum);
-  if (targetm.calls.promote_prototypes (TREE_TYPE (fn))
-      && INTEGRAL_TYPE_P (type)
-      && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
-    ret = default_conversion (ret);
-  return ret;
-}
 \f
 /* If VALUE is a compound expr all of whose expressions are constant, then
    return its value.  Otherwise, return error_mark_node.
index ec4e356c8c271bf3c731fa20bc37f08cc0b78450..dbd8b48978beae3831ce2c063a37d7c003dbf708 100644 (file)
@@ -99,6 +99,8 @@ initialize_inline_failed (struct cgraph_node *node)
                           "considered for inlining");
       else if (!node->local.inlinable)
        e->inline_failed = N_("function not inlinable");
+      else if (CALL_CANNOT_INLINE_P (e->call_stmt))
+       e->inline_failed = N_("mismatched arguments");
       else
        e->inline_failed = N_("function not considered for inlining");
     }
index e4d650b78ab44095c9198e597d3845f86f804b38..7f5615e344d898e144dfc44df6c48a2d093cf433 100644 (file)
@@ -2058,7 +2058,7 @@ gimplify_arg (tree *expr_p, tree *pre_p)
 static enum gimplify_status
 gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
 {
-  tree decl;
+  tree decl, parms, p;
   enum gimplify_status ret;
   int i, nargs;
 
@@ -2124,6 +2124,48 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
 
   nargs = call_expr_nargs (*expr_p);
 
+  /* Get argument types for verification.  */
+  decl = get_callee_fndecl (*expr_p);
+  parms = NULL_TREE;
+  if (decl)
+    parms = TYPE_ARG_TYPES (TREE_TYPE (decl));
+  else if (POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_FN (*expr_p))))
+    parms = TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (*expr_p))));
+
+  /* Verify if the type of the argument matches that of the function
+     declaration.  If we cannot verify this or there is a mismatch,
+     mark the call expression so it doesn't get inlined later.  */
+  if (parms)
+    {
+      for (i = 0, p = parms; i < nargs; i++, p = TREE_CHAIN (p))
+       if (!p
+           || TREE_VALUE (p) == error_mark_node
+           || CALL_EXPR_ARG (*expr_p, i) == error_mark_node
+           || !lang_hooks.types_compatible_p
+                (TREE_TYPE (CALL_EXPR_ARG (*expr_p, i)), TREE_VALUE (p)))
+         {
+           CALL_CANNOT_INLINE_P (*expr_p) = 1;
+           break;
+         }
+    }
+  else if (decl && DECL_ARGUMENTS (decl))
+    {
+      for (i = 0, p = DECL_ARGUMENTS (decl); i < nargs;
+          i++, p = TREE_CHAIN (p))
+       if (!p
+           || p == error_mark_node
+           || CALL_EXPR_ARG (*expr_p, i) == error_mark_node
+           || !lang_hooks.types_compatible_p
+                (TREE_TYPE (CALL_EXPR_ARG (*expr_p, i)), TREE_TYPE (p)))
+         {
+           CALL_CANNOT_INLINE_P (*expr_p) = 1;
+           break;
+         }
+    }
+  else if (nargs != 0)
+    CALL_CANNOT_INLINE_P (*expr_p) = 1;
+
+  /* Finally, gimplify the function arguments.  */
   for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
        PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
        PUSH_ARGS_REVERSED ? i-- : i++)
index ee9d7e6ca00404836c53adb1077c2a192c7e8aec..c682f86866f39ce274a05c7985c0e66ec41eebc4 100644 (file)
@@ -288,22 +288,21 @@ cgraph_mark_inline (struct cgraph_edge *edge)
   struct cgraph_node *to = edge->caller;
   struct cgraph_node *what = edge->callee;
   struct cgraph_edge *e, *next;
-  int times = 0;
 
   /* Look for all calls, mark them inline and clone recursively
      all inlined functions.  */
   for (e = what->callers; e; e = next)
     {
       next = e->next_caller;
-      if (e->caller == to && e->inline_failed)
+      if (e->caller == to && e->inline_failed
+         && !CALL_CANNOT_INLINE_P (e->call_stmt))
        {
           cgraph_mark_inline_edge (e, true);
          if (e == edge)
            edge = next;
-         times++;
        }
     }
-  gcc_assert (times);
+
   return edge;
 }
 
@@ -885,7 +884,7 @@ cgraph_decide_inlining_of_small_functions (void)
        }
       gcc_assert (edge->aux);
       edge->aux = NULL;
-      if (!edge->inline_failed)
+      if (!edge->inline_failed || CALL_CANNOT_INLINE_P (edge->call_stmt))
        continue;
 
       /* When not having profile info ready we don't weight by any way the
@@ -1076,7 +1075,7 @@ cgraph_decide_inlining (void)
       for (e = node->callers; e; e = next)
        {
          next = e->next_caller;
-         if (!e->inline_failed)
+         if (!e->inline_failed || CALL_CANNOT_INLINE_P (e->call_stmt))
            continue;
          if (cgraph_recursive_inlining_p (e->caller, e->callee,
                                           &e->inline_failed))
index 28b35bb89b17dd39a6d2d6486de6d1c3bf2bdfa4..6ca6e2f40de023d25e220a705c16f7de56fdbc65 100644 (file)
@@ -73,7 +73,6 @@ extern tree lhd_tree_inlining_walk_subtrees (tree *, int *, walk_tree_fn,
 extern int lhd_tree_inlining_cannot_inline_tree_fn (tree *);
 extern int lhd_tree_inlining_disregard_inline_limits (tree);
 extern int lhd_tree_inlining_auto_var_in_fn_p (tree, tree);
-extern tree lhd_tree_inlining_convert_parm_for_inlining (tree, tree, tree, int);
 extern void lhd_initialize_diagnostics (struct diagnostic_context *);
 extern tree lhd_callgraph_analyze_expr (tree *, int *, tree);
 
@@ -145,8 +144,6 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
   lhd_tree_inlining_auto_var_in_fn_p
 #define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P \
   hook_bool_tree_tree_false
-#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
-  lhd_tree_inlining_convert_parm_for_inlining
 
 #define LANG_HOOKS_TREE_INLINING_INITIALIZER { \
   LANG_HOOKS_TREE_INLINING_WALK_SUBTREES, \
@@ -154,7 +151,6 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
   LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS, \
   LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P, \
   LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P, \
-  LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
 }
 
 #define LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR lhd_callgraph_analyze_expr
index 5d4d63c70664ef67183538c8586b11d0c38fb7ed..85ce93524bf85acaa5dfb930acac956ea038fefc 100644 (file)
@@ -330,18 +330,6 @@ lhd_tree_inlining_auto_var_in_fn_p (tree var, tree fn)
              || TREE_CODE (var) == RESULT_DECL));
 }
 
-/* lang_hooks.tree_inlining.convert_parm_for_inlining performs any
-   language-specific conversion before assigning VALUE to PARM.  */
-
-tree
-lhd_tree_inlining_convert_parm_for_inlining (tree parm ATTRIBUTE_UNUSED,
-                                            tree value,
-                                            tree fndecl ATTRIBUTE_UNUSED,
-                                            int argnum ATTRIBUTE_UNUSED)
-{
-  return value;
-}
-
 /* lang_hooks.tree_dump.dump_tree:  Dump language-specific parts of tree
    nodes.  Returns nonzero if it does not want the usual dumping of the
    second argument.  */
index e48c0bca81c54280d998f6bfbc69d980d1c1bffb..1af85b348ea8a8089a1f2ab2d9a1626f653cc491 100644 (file)
@@ -42,7 +42,6 @@ struct lang_hooks_for_tree_inlining
   int (*disregard_inline_limits) (tree);
   int (*auto_var_in_fn_p) (tree, tree);
   bool (*var_mod_type_p) (tree, tree);
-  tree (*convert_parm_for_inlining) (tree, tree, tree, int);
 };
 
 struct lang_hooks_for_callgraph
index 48c7ab65de4dd16a9e542acd5cee6f9357575551..abdb62fa6344d9870df301f6f90545d1a794d7d5 100644 (file)
@@ -1,3 +1,12 @@
+2007-06-23  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/16876
+       PR middle-end/29478
+       * gcc.dg/pr29254.c: The warning is bogus.
+       * gcc.dg/warn-1.c: Likewise.
+       * gcc.dg/assign-warn-3.c: Likewise.
+       * gcc.dg/noncompile/pr16876.c: The testcase is bogus, remove.
+
 2007-06-23  Richard Earnshaw  <rearnsha@arm.com>
 
        * gcc.c-torture/execute/20070623-1.c: New.
index 1463fce0f68d31ac0a2eaf0afe39644eb66d159c..86d1b3028f23118105eb63027346b6bce3a8e074 100644 (file)
@@ -6,8 +6,8 @@
 
 /* This is valid to execute, so maybe shouldn't warn at all.  */
 void f0(x) signed char *x; { }
-void g0(unsigned char *x) { f0(x); } /* { dg-warning "warning: pointer targets in passing argument 1 of 'f0' differ in signedness" } */
+void g0(unsigned char *x) { f0(x); } /* { dg-bogus "warning: pointer targets in passing argument 1 of 'f0' differ in signedness" } */
 
 /* This is undefined on execution but still must compile.  */
 void f1(x) int *x; { }
-void g1(unsigned int *x) { f1(x); } /* { dg-warning "warning: pointer targets in passing argument 1 of 'f1' differ in signedness" } */
+void g1(unsigned int *x) { f1(x); } /* { dg-bogus "warning: pointer targets in passing argument 1 of 'f1' differ in signedness" } */
diff --git a/gcc/testsuite/gcc.dg/noncompile/pr16876.c b/gcc/testsuite/gcc.dg/noncompile/pr16876.c
deleted file mode 100644 (file)
index 9587849..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* { dg-options "-O -finline-functions" } */
-
-static void g();
-struct bigstack {
-   char space[4096];
-};
-
-
-void f() {
-    g(0); /* { dg-error "incompatible type for argument 1 of 'g'" } */
-}
-
-static void g(struct bigstack bstack) {
-     g(bstack);
-}
index 98846a92090974fcc10c59092df6c7479d2f3b15..598b6bf7b115aebc7f7f23c20162cb8938ed729c 100644 (file)
@@ -1,6 +1,5 @@
 /* { dg-do compile } */
 /* { dg-options "-O3 -Werror" } */
-/* { dg-message "warnings being treated as errors" "" {target "*-*-*"} 0 } */
 
 list_compare (int * list1)
 {
@@ -18,5 +17,5 @@ value_compare (int * a)
 
 func2 (const int * fb)
 {
-  func1 ((int *) fb); /* { dg-error "discards qualifiers" } */
+  func1 ((int *) fb); /* { dg-bogus "discards qualifiers" } */
 }
index dc2cd0e7c71687e1357cd53393c2656c016afed6..6db4ae5cd6ce5312011cada2c623b5244a77188c 100644 (file)
@@ -12,5 +12,5 @@ void bar (void)
 {
   void *vp;
 
-  foo (vp);    /* { dg-warning "passing argument 1 of" } */
+  foo (vp);    /* { dg-bogus "passing argument 1 of" } */
 }
index 01816862ce04cb8cd39175fc0193f3670b5876c6..054ca8cc7d53569a94218a22fda4c1f9e4a2acde 100644 (file)
@@ -1451,7 +1451,6 @@ initialize_inlined_parameters (copy_body_data *id, tree exp,
   tree a;
   tree p;
   tree vars = NULL_TREE;
-  int argnum = 0;
   call_expr_arg_iterator iter;
   tree static_chain = CALL_EXPR_STATIC_CHAIN (exp);
 
@@ -1462,17 +1461,7 @@ initialize_inlined_parameters (copy_body_data *id, tree exp,
      equivalent VAR_DECL, appropriately initialized.  */
   for (p = parms, a = first_call_expr_arg (exp, &iter); p;
        a = next_call_expr_arg (&iter), p = TREE_CHAIN (p))
-    {
-      tree value;
-
-      ++argnum;
-
-      /* Find the initializer.  */
-      value = lang_hooks.tree_inlining.convert_parm_for_inlining
-             (p, a, fn, argnum);
-
-      setup_one_parameter (id, p, value, fn, bb, &vars);
-    }
+    setup_one_parameter (id, p, a, fn, bb, &vars);
 
   /* Initialize the static chain.  */
   p = DECL_STRUCT_FUNCTION (fn)->static_chain_decl;
index 5bee34cf1dbe7818b1d61b70e2cc25ecfc15f562..28169d7a543940c1353f72d9e24991e97f83fbac 100644 (file)
@@ -449,7 +449,10 @@ struct gimple_stmt GTY(())
            POINTER_TYPE, REFERENCE_TYPE
        MOVE_NONTEMPORAL in
           GIMPLE_MODIFY_STMT
-       CASE_HIGH_SEEN in CASE_LABEL_EXPR
+       CASE_HIGH_SEEN in
+          CASE_LABEL_EXPR
+       CALL_CANNOT_INLINE_P in
+          CALL_EXPR
 
    public_flag:
 
@@ -1144,6 +1147,9 @@ extern void omp_clause_range_check_failed (const tree, const char *, int,
 #define CASE_HIGH_SEEN(NODE) \
   (CASE_LABEL_EXPR_CHECK (NODE)->base.static_flag)
 
+/* Used to mark a CALL_EXPR as not suitable for inlining.  */
+#define CALL_CANNOT_INLINE_P(NODE) ((NODE)->base.static_flag)
+
 /* In an expr node (usually a conversion) this means the node was made
    implicitly and should not lead to any sort of warning.  In a decl node,
    warnings concerning the decl should be suppressed.  This is used at