re PR tree-optimization/63595 (Segmentation faults inside kernel)
authorMartin Liska <mliska@suse.cz>
Fri, 7 Nov 2014 12:32:30 +0000 (13:32 +0100)
committerMartin Liska <marxin@gcc.gnu.org>
Fri, 7 Nov 2014 12:32:30 +0000 (12:32 +0000)
PR ipa/63595
* g++.dg/ipa/pr63595.C: New test.

* cgraphunit.c (cgraph_node::expand_thunk): DECL_BY_REFERENCE
is correctly handled for thunks created by IPA ICF.

From-SVN: r217218

gcc/ChangeLog
gcc/cgraphunit.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/pr63595.C [new file with mode: 0644]

index 7535286f915d6739a09255b2c716169c9bb67bc5..6fc91b5d66db3d37d701109ea048c2df9811d8cd 100644 (file)
@@ -1,3 +1,9 @@
+2014-11-07  Martin Liska  <mliska@suse.cz>
+
+       PR ipa/63595
+       * cgraphunit.c (cgraph_node::expand_thunk): DECL_BY_REFERENCE
+       is correctly handled for thunks created by IPA ICF.
+
 2014-11-07  Jiong Wang  <jiong.wang@arm.com>
 2014-11-07  Richard Biener  <rguenther@suse.de>
 
index d2e884745947ca130ddbe309a64325e3d2045263..75d414024a74974697e78a3ebf50d9b0048703a7 100644 (file)
@@ -1555,7 +1555,15 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
       if (!VOID_TYPE_P (restype))
        {
          if (DECL_BY_REFERENCE (resdecl))
-           restmp = gimple_fold_indirect_ref (resdecl);
+           {
+             restmp = gimple_fold_indirect_ref (resdecl);
+             if (!restmp)
+               restmp = build2 (MEM_REF,
+                                TREE_TYPE (TREE_TYPE (DECL_RESULT (alias))),
+                                resdecl,
+                                build_int_cst (TREE_TYPE
+                                  (DECL_RESULT (alias)), 0));
+           }
          else if (!is_gimple_reg_type (restype))
            {
              restmp = resdecl;
@@ -1651,7 +1659,11 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
            gimple_call_set_tail (call, true);
 
          /* Build return value.  */
-         ret = gimple_build_return (restmp);
+         if (!DECL_BY_REFERENCE (resdecl))
+           ret = gimple_build_return (restmp);
+         else
+           ret = gimple_build_return (resdecl);
+
          gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
        }
       else
index 5e1581439b8ae590085f290554f7bf558e284c7e..8575ba3e18028fc871f472d4043db29186ff1e1c 100644 (file)
@@ -1,3 +1,8 @@
+2014-11-07  Martin Liska  <mliska@suse.cz>
+
+       PR ipa/63595
+       * g++.dg/ipa/pr63595.C: New test.
+
 2014-11-07  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/63770
diff --git a/gcc/testsuite/g++.dg/ipa/pr63595.C b/gcc/testsuite/g++.dg/ipa/pr63595.C
new file mode 100644 (file)
index 0000000..30e9303
--- /dev/null
@@ -0,0 +1,80 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-icf-details"  } */
+
+template <int dim> class B;
+template <int, int dim> class TriaObjectAccessor;
+template <int, typename Accessor> class A;
+template <int dim> class TriaDimensionInfo {
+public:
+  typedef A<3, TriaObjectAccessor<2, 3> > raw_quad_iterator;
+  typedef A<3, B<3> > raw_hex_iterator;
+  typedef raw_hex_iterator raw_cell_iterator;
+};
+template <int dim> class Triangulation : public TriaDimensionInfo<1> {
+  public:
+  typedef typename TriaDimensionInfo<dim>::raw_quad_iterator raw_quad_iterator;
+  TriaDimensionInfo::raw_cell_iterator end() const;
+  raw_quad_iterator end_quad() const {
+    return raw_quad_iterator(const_cast<Triangulation *>(this), 0, 0);
+  }
+};
+template <int dim> class TriaAccessor {
+public:
+  typedef void AccessorData;
+  TriaAccessor(const Triangulation<dim> * = 0);
+  Triangulation<1> *tria;
+
+  int a, b, c;
+};
+template <int dim> class TriaObjectAccessor<2, dim> : public TriaAccessor<dim> {
+public:
+  typedef typename TriaAccessor<dim>::AccessorData AccessorData;
+  TriaObjectAccessor(const Triangulation<dim> * = 0);
+};
+template <int dim> class TriaObjectAccessor<3, dim> : public TriaAccessor<dim> {
+public:
+  typedef typename TriaAccessor<dim>::AccessorData AccessorData;
+  TriaObjectAccessor(const Triangulation<dim> * = 0);
+};
+template <int dim> class B : public TriaObjectAccessor<dim, dim> {
+public:
+  typedef typename TriaObjectAccessor<dim, dim>::AccessorData AccessorData;
+  B(const Triangulation<dim> * = 0);
+};
+template <int dim, typename Accessor> class A {
+public:
+  A(const A &);
+  A(const Triangulation<dim> *, int, int);
+  Accessor accessor;
+};
+template class Triangulation<3>;
+template <int dim, typename Accessor>
+A<dim, Accessor>::A(const Triangulation<dim> *, int, int) {}
+template <int dim>
+TriaAccessor<dim>::TriaAccessor(const Triangulation<dim> *)
+    : tria(), a(-1), b(-2), c(-3) {}
+template <int dim>
+TriaObjectAccessor<2, dim>::TriaObjectAccessor(const Triangulation<dim> *) {}
+template <int dim>
+TriaObjectAccessor<3, dim>::TriaObjectAccessor(const Triangulation<dim> *) {}
+template <int dim> B<dim>::B(const Triangulation<dim> *) {}
+template <>
+TriaDimensionInfo<3>::raw_cell_iterator Triangulation<3>::end() const {
+  return raw_hex_iterator(const_cast<Triangulation *>(this), 0, 0);
+}
+
+#pragma GCC optimize ("-O0")
+int main()
+{
+  Triangulation <3> t;
+  Triangulation<3>::raw_quad_iterator i1 = t.end_quad();
+  TriaDimensionInfo<3>::raw_cell_iterator i2 = t.end();
+
+  if(i2.accessor.c != -3)
+    return 1;
+
+  return 0;
+}
+
+/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf"  } } */
+/* { dg-final { cleanup-ipa-dump "icf" } } */