From 5cf18d250f37b6c86b26d17e0cbb22a0c0d18e03 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 29 Oct 2014 16:17:42 +0100 Subject: [PATCH] re PR ipa/63587 (ICE : tree check: expected var_decl, have result_decl in add_local_variables, at tree-inline.c:4112) PR ipa/63587 * g++.dg/ipa/pr63587-1.C: New test * g++.dg/ipa/pr63587-2.C: New test. * cgraphunit.c (cgraph_node::expand_thunk): Only VAR_DECLs are put to local declarations. * function.c (add_local_decl): Implementation moved from header file, assert introduced for tree type. * function.h: Likewise. From-SVN: r216841 --- gcc/ChangeLog | 9 + gcc/cgraphunit.c | 4 +- gcc/function.c | 9 + gcc/function.h | 6 +- gcc/testsuite/ChangeLog | 6 + gcc/testsuite/g++.dg/ipa/pr63587-1.C | 92 ++++++++++ gcc/testsuite/g++.dg/ipa/pr63587-2.C | 250 +++++++++++++++++++++++++++ 7 files changed, 370 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ipa/pr63587-1.C create mode 100644 gcc/testsuite/g++.dg/ipa/pr63587-2.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index da384989dcbe..59e562c111b8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2014-10-29 Martin Liska + + PR ipa/63587 + * cgraphunit.c (cgraph_node::expand_thunk): Only VAR_DECLs are put + to local declarations. + * function.c (add_local_decl): Implementation moved from header + file, assert introduced for tree type. + * function.h: Likewise. + 2014-10-29 Dominik Vogt * godump.c (go_format_type): Represent "float _Complex" and diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index a86bd1bcd035..6f61f5c339ff 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1550,7 +1550,9 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) else if (!is_gimple_reg_type (restype)) { restmp = resdecl; - add_local_decl (cfun, restmp); + + if (TREE_CODE (restmp) == VAR_DECL) + add_local_decl (cfun, restmp); BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp; } else diff --git a/gcc/function.c b/gcc/function.c index 85cf10388d47..1ef43c4dea7d 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -6441,6 +6441,15 @@ match_asm_constraints_1 (rtx_insn *insn, rtx *p_sets, int noutputs) df_insn_rescan (insn); } +/* Add the decl D to the local_decls list of FUN. */ + +void +add_local_decl (struct function *fun, tree d) +{ + gcc_assert (TREE_CODE (d) == VAR_DECL); + vec_safe_push (fun->local_decls, d); +} + namespace { const pass_data pass_data_match_asm_constraints = diff --git a/gcc/function.h b/gcc/function.h index 4dfc5bc0f655..08ab761ae76f 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -668,11 +668,7 @@ struct GTY(()) function { /* Add the decl D to the local_decls list of FUN. */ -static inline void -add_local_decl (struct function *fun, tree d) -{ - vec_safe_push (fun->local_decls, d); -} +void add_local_decl (struct function *fun, tree d); #define FOR_EACH_LOCAL_DECL(FUN, I, D) \ FOR_EACH_VEC_SAFE_ELT_REVERSE ((FUN)->local_decls, I, D) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 45114fa0a6a9..2e4073fa08c2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-10-29 Martin Liska + + PR ipa/63587 + * g++.dg/ipa/pr63587-1.C: New test. + * g++.dg/ipa/pr63587-2.C: New test. + 2014-10-29 Dominik Vogt * gcc.misc-tests/godump-1.c: Add tests for complex types. diff --git a/gcc/testsuite/g++.dg/ipa/pr63587-1.C b/gcc/testsuite/g++.dg/ipa/pr63587-1.C new file mode 100644 index 000000000000..cbf872e2969b --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr63587-1.C @@ -0,0 +1,92 @@ +// PR ipa/63587 +// { dg-do compile { target c++11 } } +// { dg-options "-O2 -fno-strict-aliasing" } + +template struct A +{ +}; +template struct B +{ + template struct C; +}; +class D; +template class F; +struct G +{ + void operator()(const D &, D); +}; +class D +{ +public: + D (int); +}; +struct H +{ + H (int); +}; +template +class I +{ + typedef _Key key_type; + template struct J + { + _Key_compare _M_key_compare; + }; + J<_Compare> _M_impl; + +public: + A _M_get_insert_unique_pos (const key_type &); + A _M_get_insert_hint_unique_pos (H &); + template int _M_emplace_hint_unique (H, _Args &&...); +}; +template > > +class K +{ + typedef _Key key_type; + typedef _Key value_type; + typedef typename B<_Alloc>::template C _Pair_alloc_type; + I _M_t; + +public: + void operator[](key_type) + { + _M_t._M_emplace_hint_unique (0); + } +}; +template +A +I<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos ( + const key_type &p1) +{ + _M_impl._M_key_compare (p1, 0); +} +template +A +I<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_hint_unique_pos ( + H &) +{ + _M_get_insert_unique_pos (0); +} +template +template +int +I<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique ( + H p1, _Args &&...) +{ + _M_get_insert_hint_unique_pos (p1); +} +namespace { +struct L; +} +void +fn1 () +{ + K a; + a[0]; + K b; + b[0]; +} diff --git a/gcc/testsuite/g++.dg/ipa/pr63587-2.C b/gcc/testsuite/g++.dg/ipa/pr63587-2.C new file mode 100644 index 000000000000..f31c5bdee446 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr63587-2.C @@ -0,0 +1,250 @@ +// PR ipa/63587 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +namespace boost { +class basic_cstring +{ +public: + basic_cstring (char *); +}; +template struct identity +{ +}; +struct make_identity; +struct function_buffer +{ +}; +template struct function_obj_invoker0 +{ + static int + invoke (function_buffer &) + { + FunctionObj f; + f (); + } +}; +template struct get_function_obj_invoker0 +{ + typedef function_obj_invoker0 type; +}; +template struct apply +{ + typedef typename get_function_obj_invoker0::type invoker_type; +}; +struct basic_vtable0 +{ + typedef int (*invoker_type)(function_buffer &); + template void assign_to (F, function_buffer); + invoker_type invoker; +}; +class function0 +{ +public: + template function0 (Functor) + { + typedef typename apply::invoker_type invoker_type; + basic_vtable0 stored_vtable { invoker_type::invoke }; + stored_vtable.assign_to (0, functor); + } + function_buffer functor; +}; +class function : function0 +{ +public: + template function (Functor f) : function0 (f) {} +}; +class test_unit_generator +{ +}; +class test_case +{ +public: + test_case (basic_cstring, basic_cstring, int, function); +}; +struct auto_test_unit_registrar +{ + auto_test_unit_registrar (test_unit_generator); +}; +template F unwrap (F, int); +struct for_each_impl +{ + template + static void + execute (Iterator, LastIterator, TransformFunc, F f) + { + identity __trans_tmp_1; + unwrap (f, 0)(__trans_tmp_1); + } +}; +template +void +for_each (F f) +{ + for_each_impl::execute (0, 0, 0, f); +} +template class test_case_template_invoker +{ +public: + void operator()() + { + TestCaseTemplate::run (0); + } +}; +template +struct generate_test_case_4_type +{ + generate_test_case_4_type (basic_cstring, basic_cstring, int, Generator G) + : m_test_case_name (0), m_test_case_file (0), m_holder (G) + { + } + template void operator()(identity) + { + test_case (0, 0, 0, test_case_template_invoker ()); + } + basic_cstring m_test_case_name; + basic_cstring m_test_case_file; + Generator m_holder; +}; +template +class template_test_case_gen : public test_unit_generator +{ +public: + template_test_case_gen (basic_cstring, basic_cstring, int) + { + for_each ( + generate_test_case_4_type ( + 0, 0, 0, *this)); + } +}; +class attribute_name +{ + int m_id; + +public: + attribute_name (char); +}; +template struct term; +namespace exprns_ { +template struct expr; +} +using exprns_::expr; +template struct Trans_NS_proto_terminal +{ + typedef expr > type; +}; +namespace exprns_ { +template struct expr > +{ + Arg0 child0; +}; +} +template struct actor +{ + typename Trans_NS_proto_terminal::type proto_expr_; +}; +template