From 06ff700018a769b76d4ec39b487fff46738ce84b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 12 Feb 2016 12:59:00 +0100 Subject: [PATCH] re PR ipa/69241 (ICE with noreturn and function that return non-POD) PR ipa/69241 * ipa-split.c (split_function): If split part returns TREE_ADDRESSABLE type by reference, force lhs on the call. * g++.dg/ipa/pr69241-4.C: New test. From-SVN: r233375 --- gcc/ChangeLog | 4 ++ gcc/ipa-split.c | 13 ++++++- gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/g++.dg/ipa/pr69241-4.C | 55 ++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/ipa/pr69241-4.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3588b15362f..642f7d3a80e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2016-02-12 Jakub Jelinek + PR ipa/69241 + * ipa-split.c (split_function): If split part returns TREE_ADDRESSABLE + type by reference, force lhs on the call. + PR ipa/68672 * ipa-split.c (split_function): Don't compute/use main_part_return_p. Compute retval and retbnd early in all cases if split_part_return_p diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 2528a796502..ac8b4787b10 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -629,7 +629,18 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, 4) For non-SSA we need to look where the var is computed. */ retval = find_retval (return_bb); if (!retval) - current->split_part_set_retval = true; + { + /* If there is a return_bb with no return value in function returning + value by reference, also make the split part return void, otherwise + we expansion would try to create a non-POD temporary, which is + invalid. */ + if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun) + && DECL_RESULT (current_function_decl) + && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) + current->split_part_set_retval = false; + else + current->split_part_set_retval = true; + } else if (is_gimple_min_invariant (retval)) current->split_part_set_retval = false; /* Special case is value returned by reference we record as if it was non-ssa diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 79f8f5a9e4f..33d2f2227ba 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2016-02-12 Jakub Jelinek + PR ipa/69241 + * g++.dg/ipa/pr69241-4.C: New test. + PR ipa/68672 * g++.dg/ipa/pr68672-1.C: New test. * g++.dg/ipa/pr68672-2.C: New test. diff --git a/gcc/testsuite/g++.dg/ipa/pr69241-4.C b/gcc/testsuite/g++.dg/ipa/pr69241-4.C new file mode 100644 index 00000000000..2805b0cd675 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr69241-4.C @@ -0,0 +1,55 @@ +// PR ipa/69241 +// { dg-do compile { target c++11 } } +// { dg-options "-O2 -Wno-return-type" } + +template class A; +struct B { + using pointer = int *; +}; +template > class basic_string { + long _M_string_length; + enum { _S_local_capacity = 15 } _M_local_buf[_S_local_capacity]; + B::pointer _M_local_data; + +public: + ~basic_string(); +}; +template +int operator<<(_Traits, basic_string<_CharT, _Alloc>); +class C { + basic_string> _M_string; +}; +class D { + C _M_stringbuf; +}; +class F { + int stream; + D stream_; +}; +class G { +public: + void operator&(int); +}; +class H { +public: + H(unsigned); + H(H &&); + bool m_fn1(); +}; +class I { + void m_fn2(const int &&); + static H m_fn3(const int &); +}; +template void Bind(Functor); +class J { +public: + static basic_string m_fn4(); +}; +int a; +void I::m_fn2(const int &&) { Bind(m_fn3); } +H I::m_fn3(const int &) { + !false ? (void)0 : G() & F() << J::m_fn4(); + H b(a); + if (b.m_fn1()) + F(); +}