]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR ipa/69241 (ICE with noreturn and function that return non-POD)
authorJakub Jelinek <jakub@redhat.com>
Fri, 12 Feb 2016 11:59:00 +0000 (12:59 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 12 Feb 2016 11:59:00 +0000 (12:59 +0100)
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
gcc/ipa-split.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/pr69241-4.C [new file with mode: 0644]

index 3588b15362fe21fee6c6a69912d1e1a4a0802312..642f7d3a80e12c721e6d87f541e8e9a105f72b10 100644 (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
index 2528a7965022f75212dca4d3c9814313b14806c6..ac8b4787b100394845772fa0211078a1add3aeb9 100644 (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
index 79f8f5a9e4f855e52875cb6550bffb96eb11ae04..33d2f2227ba5a3344b8ea28f091867e9ee8928cc 100644 (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.
diff --git a/gcc/testsuite/g++.dg/ipa/pr69241-4.C b/gcc/testsuite/g++.dg/ipa/pr69241-4.C
new file mode 100644 (file)
index 0000000..2805b0c
--- /dev/null
@@ -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();
+}