From 1628e36bcf93a88d29885dd4e47e44ba80f909c6 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 22 Jun 2015 09:12:22 +0200 Subject: [PATCH] re PR ipa/65908 (ICE: in expand_thunk, at cgraphunit.c:1700) PR ipa/65908 * ipa-icf.c (sem_item::target_supports_symbol_aliases): Remove construction of arg_types. (sem_function::sem_function): Likewise. (sem_function::~sem_function): Remove destruction of arg_types. (sem_function::compatible_parm_types_p): New function. (sem_function::equals_wpa): Reorg matching of return values and parameter types. (sem_function::equals_private): Reorg mathcing of argument types. (sem_function::parse_tree_args): Remove. * ipa-icf.h (init_wpa): Do not call it. (parse_tree_args): Remove. (compatible_parm_types_p): Declare. (result_type): Remove. (arg_types): Remove. * testsuite/g++.dg/ipa/pr65908.C: New testcase. Co-Authored-By: Martin Liska From-SVN: r224720 --- gcc/ChangeLog | 19 +++++ gcc/ipa-icf.c | 127 ++++++++++++++--------------- gcc/ipa-icf.h | 14 +--- gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/g++.dg/ipa/pr65908.C | 27 ++++++ 5 files changed, 119 insertions(+), 74 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ipa/pr65908.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 60f835ea698..a0bcee81d69 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2015-06-22 Jan Hubicka + Martin Liska + + PR ipa/65908 + * ipa-icf.c (sem_item::target_supports_symbol_aliases): Remove + construction of arg_types. + (sem_function::sem_function): Likewise. + (sem_function::~sem_function): Remove destruction of arg_types. + (sem_function::compatible_parm_types_p): New function. + (sem_function::equals_wpa): Reorg matching of return values + and parameter types. + (sem_function::equals_private): Reorg mathcing of argument types. + (sem_function::parse_tree_args): Remove. + * ipa-icf.h (init_wpa): Do not call it. + (parse_tree_args): Remove. + (compatible_parm_types_p): Declare. + (result_type): Remove. + (arg_types): Remove. + 2015-06-22 Jan Hubicka PR ipa/66351 diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index e998fbf216c..9a8133faa2c 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -259,7 +259,6 @@ sem_item::target_supports_symbol_aliases_p (void) sem_function::sem_function (bitmap_obstack *stack): sem_item (FUNC, stack), m_checker (NULL), m_compared_func (NULL) { - arg_types.create (0); bb_sizes.create (0); bb_sorted.create (0); } @@ -271,7 +270,6 @@ sem_function::sem_function (cgraph_node *node, hashval_t hash, sem_item (FUNC, node, hash, stack), m_checker (NULL), m_compared_func (NULL) { - arg_types.create (0); bb_sizes.create (0); bb_sorted.create (0); } @@ -281,7 +279,6 @@ sem_function::~sem_function () for (unsigned i = 0; i < bb_sorted.length (); i++) delete (bb_sorted[i]); - arg_types.release (); bb_sizes.release (); bb_sorted.release (); } @@ -581,6 +578,30 @@ sem_function::param_used_p (unsigned int i) return ipa_is_param_used (IPA_NODE_REF (get_node ()), i); } +/* Perform additional check needed to match types function parameters that are + used. Unlike for normal decls it matters if type is TYPE_RESTRICT and we + make an assumption that REFERENCE_TYPE parameters are always non-NULL. */ + +bool +sem_function::compatible_parm_types_p (tree parm1, tree parm2) +{ + /* Be sure that parameters are TBAA compatible. */ + if (!func_checker::compatible_types_p (parm1, parm2)) + return return_false_with_msg ("parameter type is not compatible"); + + if (POINTER_TYPE_P (parm1) + && (TYPE_RESTRICT (parm1) != TYPE_RESTRICT (parm2))) + return return_false_with_msg ("argument restrict flag mismatch"); + + /* nonnull_arg_p implies non-zero range to REFERENCE types. */ + if (POINTER_TYPE_P (parm1) + && TREE_CODE (parm1) != TREE_CODE (parm2) + && opt_for_fn (decl, flag_delete_null_pointer_checks)) + return return_false_with_msg ("pointer wrt reference mismatch"); + + return true; +} + /* Fast equality function based on knowledge known in WPA. */ bool @@ -593,9 +614,6 @@ sem_function::equals_wpa (sem_item *item, m_compared_func = static_cast (item); - if (arg_types.length () != m_compared_func->arg_types.length ()) - return return_false_with_msg ("different number of arguments"); - if (cnode->thunk.thunk_p != cnode2->thunk.thunk_p) return return_false_with_msg ("thunk_p mismatch"); @@ -684,38 +702,40 @@ sem_function::equals_wpa (sem_item *item, } /* Result type checking. */ - if (!func_checker::compatible_types_p (result_type, - m_compared_func->result_type)) + if (!func_checker::compatible_types_p + (TREE_TYPE (TREE_TYPE (decl)), + TREE_TYPE (TREE_TYPE (m_compared_func->decl)))) return return_false_with_msg ("result types are different"); /* Checking types of arguments. */ - for (unsigned i = 0; i < arg_types.length (); i++) + tree list1 = TYPE_ARG_TYPES (TREE_TYPE (decl)), + list2 = TYPE_ARG_TYPES (TREE_TYPE (m_compared_func->decl)); + for (unsigned i = 0; list1 && list2; + list1 = TREE_CHAIN (list1), list2 = TREE_CHAIN (list2), i++) { + tree parm1 = TREE_VALUE (list1); + tree parm2 = TREE_VALUE (list2); + /* This guard is here for function pointer with attributes (pr59927.c). */ - if (!arg_types[i] || !m_compared_func->arg_types[i]) + if (!parm1 || !parm2) return return_false_with_msg ("NULL argument type"); - /* We always need to match types so we are sure the callin conventions - are compatible. */ - if (!func_checker::compatible_types_p (arg_types[i], - m_compared_func->arg_types[i])) - return return_false_with_msg ("argument type is different"); + /* Verify that types are compatible to ensure that both functions + have same calling conventions. */ + if (!types_compatible_p (parm1, parm2)) + return return_false_with_msg ("parameter types are not compatible"); - /* On used arguments we need to do a bit more of work. */ if (!param_used_p (i)) continue; - if (POINTER_TYPE_P (arg_types[i]) - && (TYPE_RESTRICT (arg_types[i]) - != TYPE_RESTRICT (m_compared_func->arg_types[i]))) - return return_false_with_msg ("argument restrict flag mismatch"); - /* nonnull_arg_p implies non-zero range to REFERENCE types. */ - if (POINTER_TYPE_P (arg_types[i]) - && TREE_CODE (arg_types[i]) - != TREE_CODE (m_compared_func->arg_types[i]) - && opt_for_fn (decl, flag_delete_null_pointer_checks)) - return return_false_with_msg ("pointer wrt reference mismatch"); + + /* Perform additional checks for used parameters. */ + if (!compatible_parm_types_p (parm1, parm2)) + return false; } + if (list1 || list2) + return return_false_with_msg ("Mismatched number of parameters"); + if (node->num_references () != item->node->num_references ()) return return_false_with_msg ("different number of references"); @@ -922,11 +942,23 @@ sem_function::equals_private (sem_item *item) false, &refs_set, &m_compared_func->refs_set); - for (arg1 = DECL_ARGUMENTS (decl), - arg2 = DECL_ARGUMENTS (m_compared_func->decl); - arg1; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2)) - if (!m_checker->compare_decl (arg1, arg2)) - return return_false (); + arg1 = DECL_ARGUMENTS (decl); + arg2 = DECL_ARGUMENTS (m_compared_func->decl); + for (unsigned i = 0; + arg1 && arg2; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2), i++) + { + if (!types_compatible_p (TREE_TYPE (arg1), TREE_TYPE (arg2))) + return return_false_with_msg ("argument types are not compatible"); + if (!param_used_p (i)) + continue; + /* Perform additional checks for used parameters. */ + if (!compatible_parm_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2))) + return false; + if (!m_checker->compare_decl (arg1, arg2)) + return return_false (); + } + if (arg1 || arg2) + return return_false_with_msg ("Mismatched number of arguments"); if (!dyn_cast (node)->has_gimple_body_p ()) return true; @@ -1439,8 +1471,6 @@ sem_function::init (void) hstate.add_flag (cnode->thunk.add_pointer_bounds_args); gcode_hash = hstate.end (); } - - parse_tree_args (); } /* Accumulate to HSTATE a hash of expression EXP. @@ -1691,37 +1721,6 @@ sem_function::parse (cgraph_node *node, bitmap_obstack *stack) return f; } -/* Parses function arguments and result type. */ - -void -sem_function::parse_tree_args (void) -{ - tree result; - - if (arg_types.exists ()) - arg_types.release (); - - arg_types.create (4); - tree fnargs = DECL_ARGUMENTS (decl); - - for (tree parm = fnargs; parm; parm = DECL_CHAIN (parm)) - arg_types.safe_push (DECL_ARG_TYPE (parm)); - - /* Function result type. */ - result = DECL_RESULT (decl); - result_type = result ? TREE_TYPE (result) : NULL; - - /* During WPA, we can get arguments by following method. */ - if (!fnargs) - { - tree type = TYPE_ARG_TYPES (TREE_TYPE (decl)); - for (tree parm = type; parm; parm = TREE_CHAIN (parm)) - arg_types.safe_push (TYPE_CANONICAL (TREE_VALUE (parm))); - - result_type = TREE_TYPE (TREE_TYPE (decl)); - } -} - /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC), return true if phi nodes are semantically equivalent in these blocks . */ diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h index a3b9ab93678..ee35ee27ac2 100644 --- a/gcc/ipa-icf.h +++ b/gcc/ipa-icf.h @@ -292,7 +292,6 @@ public: inline virtual void init_wpa (void) { - parse_tree_args (); } virtual void init (void); @@ -310,9 +309,6 @@ public: dump_function_to_file (decl, file, TDF_DETAILS); } - /* Parses function arguments and result type. */ - void parse_tree_args (void); - /* Returns cgraph_node. */ inline cgraph_node *get_node (void) { @@ -329,15 +325,13 @@ public: semantic function item. */ static sem_function *parse (cgraph_node *node, bitmap_obstack *stack); + /* Perform additional checks needed to match types of used function + paramters. */ + bool compatible_parm_types_p (tree, tree); + /* Exception handling region tree. */ eh_region region_tree; - /* Result type tree node. */ - tree result_type; - - /* Array of argument tree types. */ - vec arg_types; - /* Number of function arguments. */ unsigned int arg_count; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 89b859f0276..0e33302ea59 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-06-22 Jan Hubicka + Martin Liska + + PR ipa/65908 + * g++.dg/ipa/pr65908.C: New testcase. + 2015-06-20 Mikhail Maltsev PR c++/65882 diff --git a/gcc/testsuite/g++.dg/ipa/pr65908.C b/gcc/testsuite/g++.dg/ipa/pr65908.C new file mode 100644 index 00000000000..38730bd0b2d --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr65908.C @@ -0,0 +1,27 @@ +// PR ipa/65908 +// { dg-do compile } +// { dg-options "-O2" } +// { dg-additional-options "-fPIC" { target fpic } } + +class A +{ + A (A &); +}; +class B +{ + const A &m_fn1 () const; +}; +class C +{ + A m_fn2 () const; +}; +A +C::m_fn2 () const +{ + throw 0; +} +const A & +B::m_fn1 () const +{ + throw 0; +} -- 2.30.2