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
This commit is contained in:
Jakub Jelinek 2016-02-12 12:59:00 +01:00 committed by Jakub Jelinek
parent b69539cbf5
commit 06ff700018
4 changed files with 74 additions and 1 deletions

View File

@ -1,5 +1,9 @@
2016-02-12 Jakub Jelinek <jakub@redhat.com>
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

View File

@ -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

View File

@ -1,5 +1,8 @@
2016-02-12 Jakub Jelinek <jakub@redhat.com>
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.

View File

@ -0,0 +1,55 @@
// PR ipa/69241
// { dg-do compile { target c++11 } }
// { dg-options "-O2 -Wno-return-type" }
template <typename> class A;
struct B {
using pointer = int *;
};
template <typename _CharT, typename = A<_CharT>> 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 <typename _CharT, typename _Traits, typename _Alloc>
int operator<<(_Traits, basic_string<_CharT, _Alloc>);
class C {
basic_string<A<char>> _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 <typename Functor> void Bind(Functor);
class J {
public:
static basic_string<char> 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();
}