89 lines
2.5 KiB
Diff
89 lines
2.5 KiB
Diff
2016-02-10 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.
|
|
|
|
* g++.dg/ipa/pr69241-4.C: New test.
|
|
|
|
--- gcc/ipa-split.c.jj 2016-02-11 12:46:15.975777652 +0100
|
|
+++ gcc/ipa-split.c 2016-02-11 13:06:57.715241871 +0100
|
|
@@ -629,7 +629,18 @@ consider_split (struct split_point *curr
|
|
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
|
|
--- gcc/testsuite/g++.dg/ipa/pr69241-4.C.jj 2016-02-11 13:00:04.160075417 +0100
|
|
+++ gcc/testsuite/g++.dg/ipa/pr69241-4.C 2016-02-11 13:00:04.160075417 +0100
|
|
@@ -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();
|
|
+}
|