From e36711f3cd476b24b011f18953aa3ed3e9a70a36 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Sat, 23 Jun 2007 18:17:57 +0000 Subject: [PATCH] re PR tree-optimization/16876 (ICE on testcase with -O3 in fold-const) 2007-06-23 Richard Guenther 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 --- gcc/ChangeLog | 30 ++++++++++++++++ gcc/c-objc-common.h | 3 -- gcc/c-tree.h | 1 - gcc/c-typeck.c | 31 ---------------- gcc/cgraphbuild.c | 2 ++ gcc/gimplify.c | 44 ++++++++++++++++++++++- gcc/ipa-inline.c | 11 +++--- gcc/langhooks-def.h | 4 --- gcc/langhooks.c | 12 ------- gcc/langhooks.h | 1 - gcc/testsuite/ChangeLog | 9 +++++ gcc/testsuite/gcc.dg/assign-warn-3.c | 4 +-- gcc/testsuite/gcc.dg/noncompile/pr16876.c | 15 -------- gcc/testsuite/gcc.dg/pr29254.c | 3 +- gcc/testsuite/gcc.dg/warn-1.c | 2 +- gcc/tree-inline.c | 13 +------ gcc/tree.h | 8 ++++- 17 files changed, 101 insertions(+), 92 deletions(-) delete mode 100644 gcc/testsuite/gcc.dg/noncompile/pr16876.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9ea41e117635..6756a73fc782 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,33 @@ +2007-06-23 Richard Guenther + + 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 PR target/31152 diff --git a/gcc/c-objc-common.h b/gcc/c-objc-common.h index e6a82efd4aef..171e702e59d3 100644 --- a/gcc/c-objc-common.h +++ b/gcc/c-objc-common.h @@ -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 diff --git a/gcc/c-tree.h b/gcc/c-tree.h index e5f4a153fd55..3bc98507eaf4 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -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); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 9811d873d381..2a19f0875fb5 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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; -} /* If VALUE is a compound expr all of whose expressions are constant, then return its value. Otherwise, return error_mark_node. diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index ec4e356c8c27..dbd8b48978be 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -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"); } diff --git a/gcc/gimplify.c b/gcc/gimplify.c index e4d650b78ab4..7f5615e344d8 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -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++) diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index ee9d7e6ca004..c682f86866f3 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -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)) diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 28b35bb89b17..6ca6e2f40de0 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -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 diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 5d4d63c70664..85ce93524bf8 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -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. */ diff --git a/gcc/langhooks.h b/gcc/langhooks.h index e48c0bca81c5..1af85b348ea8 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 48c7ab65de4d..abdb62fa6344 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2007-06-23 Richard Guenther + + 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 * gcc.c-torture/execute/20070623-1.c: New. diff --git a/gcc/testsuite/gcc.dg/assign-warn-3.c b/gcc/testsuite/gcc.dg/assign-warn-3.c index 1463fce0f68d..86d1b3028f23 100644 --- a/gcc/testsuite/gcc.dg/assign-warn-3.c +++ b/gcc/testsuite/gcc.dg/assign-warn-3.c @@ -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 index 9587849b2fcb..000000000000 --- a/gcc/testsuite/gcc.dg/noncompile/pr16876.c +++ /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); -} diff --git a/gcc/testsuite/gcc.dg/pr29254.c b/gcc/testsuite/gcc.dg/pr29254.c index 98846a920909..598b6bf7b115 100644 --- a/gcc/testsuite/gcc.dg/pr29254.c +++ b/gcc/testsuite/gcc.dg/pr29254.c @@ -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" } */ } diff --git a/gcc/testsuite/gcc.dg/warn-1.c b/gcc/testsuite/gcc.dg/warn-1.c index dc2cd0e7c716..6db4ae5cd6ce 100644 --- a/gcc/testsuite/gcc.dg/warn-1.c +++ b/gcc/testsuite/gcc.dg/warn-1.c @@ -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" } */ } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 01816862ce04..054ca8cc7d53 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -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; diff --git a/gcc/tree.h b/gcc/tree.h index 5bee34cf1dbe..28169d7a5439 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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 -- 2.47.2