aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-02-12 12:59:00 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2016-02-12 12:59:00 +0100
commit06ff700018a769b76d4ec39b487fff46738ce84b (patch)
tree0247bb31639a9cd236d1d18a2093f70a95038354 /gcc
parentb69539cbf58a1d0c918759dc12cf384922661753 (diff)
downloadgcc-06ff700018a769b76d4ec39b487fff46738ce84b.zip
gcc-06ff700018a769b76d4ec39b487fff46738ce84b.tar.gz
gcc-06ff700018a769b76d4ec39b487fff46738ce84b.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/ipa-split.c13
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr69241-4.C55
4 files changed, 74 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3588b15..642f7d3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 2528a79..ac8b478 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 79f8f5a..33d2f22 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
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 0000000..2805b0c
--- /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 <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();
+}