re PR c++/71210 (internal compiler error: in assign_temp, at function.c:961)
authorJakub Jelinek <jakub@redhat.com>
Fri, 20 May 2016 11:58:49 +0000 (13:58 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 20 May 2016 11:58:49 +0000 (13:58 +0200)
PR c++/71210
* gimple-fold.c (gimple_fold_call): Do not remove lhs of noreturn
calls if the LHS is variable length or has addressable type.
If targets[0]->decl is a noreturn call with void return type and
zero arguments, adjust fntype and remove lhs in that case.

* g++.dg/opt/pr71210-1.C: New test.
* g++.dg/opt/pr71210-2.C: New test.

From-SVN: r236506

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr71210-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/opt/pr71210-2.C [new file with mode: 0644]

index f874a6ca1c5c548c2cd8b7d5d1cecb08d74238cf..403c01fa9972a811d410fab34f60a6aaf7db7fba 100644 (file)
@@ -1,3 +1,11 @@
+2016-05-20  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/71210
+       * gimple-fold.c (gimple_fold_call): Do not remove lhs of noreturn
+       calls if the LHS is variable length or has addressable type.
+       If targets[0]->decl is a noreturn call with void return type and
+       zero arguments, adjust fntype and remove lhs in that case.
+
 2016-05-20  Marc Glisse  <marc.glisse@inria.fr>
 
        PR tree-optimization/71079
index d3968e98620c121c42d32f06548ba73ac622214d..858f484442635090c7c625b313aed80a430769d6 100644 (file)
@@ -3039,10 +3039,25 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
                }
              if (targets.length () == 1)
                {
-                 gimple_call_set_fndecl (stmt, targets[0]->decl);
+                 tree fndecl = targets[0]->decl;
+                 gimple_call_set_fndecl (stmt, fndecl);
                  changed = true;
+                 /* If changing the call to __cxa_pure_virtual
+                    or similar noreturn function, adjust gimple_call_fntype
+                    too.  */
+                 if ((gimple_call_flags (stmt) & ECF_NORETURN)
+                     && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
+                     && TYPE_ARG_TYPES (TREE_TYPE (fndecl))
+                     && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
+                         == void_type_node))
+                   gimple_call_set_fntype (stmt, TREE_TYPE (fndecl));
                  /* If the call becomes noreturn, remove the lhs.  */
-                 if (lhs && (gimple_call_flags (stmt) & ECF_NORETURN))
+                 if (lhs
+                     && (gimple_call_flags (stmt) & ECF_NORETURN)
+                     && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (stmt)))
+                         || ((TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))
+                              == INTEGER_CST)
+                             && !TREE_ADDRESSABLE (TREE_TYPE (lhs)))))
                    {
                      if (TREE_CODE (lhs) == SSA_NAME)
                        {
index 94080ab6921a0d19dc2f0d2f9a76c26a5c61d6bf..fe4727a5e3cfc4d2ec179a5d4a6304af2c864e4d 100644 (file)
@@ -1,5 +1,9 @@
 2016-05-20  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/71210
+       * g++.dg/opt/pr71210-1.C: New test.
+       * g++.dg/opt/pr71210-2.C: New test.
+
        PR tree-optimization/29756
        gcc.dg/tree-ssa/vector-6.c: Add -Wno-psabi -w to dg-options.
        Add -msse2 for x86 and -maltivec for powerpc.  Use scan-tree-dump-times
diff --git a/gcc/testsuite/g++.dg/opt/pr71210-1.C b/gcc/testsuite/g++.dg/opt/pr71210-1.C
new file mode 100644 (file)
index 0000000..03b1fb5
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/71210
+// { dg-do compile }
+// { dg-options "-O2" }
+
+#include <typeinfo>
+
+void f1 (const std::type_info&) __attribute__((noreturn));
+struct S1 { ~S1 (); };
+struct S2
+{
+  virtual S1 f2 () const { f1 (typeid (*this)); }
+  S1 f3 () const { return f2 (); }
+};
+void f4 () { S2 a; a.f3 (); }
diff --git a/gcc/testsuite/g++.dg/opt/pr71210-2.C b/gcc/testsuite/g++.dg/opt/pr71210-2.C
new file mode 100644 (file)
index 0000000..02a31bd
--- /dev/null
@@ -0,0 +1,23 @@
+// PR c++/71210
+// { dg-do compile }
+// { dg-options "-O2" }
+
+struct C { int a; int b; C (); ~C (); };
+
+namespace
+{
+  struct A
+  {
+    A () {}
+    virtual C bar (int) = 0;
+    C baz (int x) { return bar (x); }
+  };
+}
+
+A *a;
+
+void
+foo ()
+{
+  C c = a->baz (0);
+}