aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-01-13 08:32:13 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-01-13 08:32:13 +0000
commita2d429ac5e450845f3febbfba21d3bb486fcf7ce (patch)
tree71d4302bbc8f858c29bcf76ecec98e40ee75f40f /gcc
parent0d7a9dbdd23c58761a85f22e18982242e2dc9621 (diff)
downloadgcc-a2d429ac5e450845f3febbfba21d3bb486fcf7ce.zip
gcc-a2d429ac5e450845f3febbfba21d3bb486fcf7ce.tar.gz
gcc-a2d429ac5e450845f3febbfba21d3bb486fcf7ce.tar.bz2
re PR middle-end/64568 (error: invalid reference prefix)
2014-01-13 Richard Biener <rguenther@suse.de> PR tree-optimization/64568 * tree-ssa-forwprop.c (pass_forwprop::execute): Properly release defs of removed stmts, avoid splitting TARGET_MEM_REFs. * g++.dg/torture/pr64568.C: New testcase. From-SVN: r219520
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr64568.C111
-rw-r--r--gcc/tree-ssa-forwprop.c7
4 files changed, 128 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d358973..a3126a7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2014-01-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/64568
+ * tree-ssa-forwprop.c (pass_forwprop::execute): Properly
+ release defs of removed stmts, avoid splitting TARGET_MEM_REFs.
+
2015-01-13 Chung-Ju Wu <jasonwucj@gmail.com>
* config/nds32/nds32.c (nds32_legitimate_address_p): Consider
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ba472c5..bd4d1d0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-01-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/64568
+ * g++.dg/torture/pr64568.C: New testcase.
+
2015-01-12 David Malcolm <dmalcolm@redhat.com>
* jit.dg/test-error-local-used-from-other-function.c: New test
diff --git a/gcc/testsuite/g++.dg/torture/pr64568.C b/gcc/testsuite/g++.dg/torture/pr64568.C
new file mode 100644
index 0000000..15a89df
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr64568.C
@@ -0,0 +1,111 @@
+// { dg-do compile }
+// { dg-additional-options "-std=c++11" }
+
+namespace std
+{
+typedef long unsigned size_t;
+template <typename> class complex;
+template <typename _Tp> complex<_Tp> operator+(complex<_Tp>, complex<_Tp>)
+{
+ complex<_Tp> a = 0;
+ a += 0;
+ return a;
+}
+template <> struct complex<double>
+{
+ complex (int __i) : _M_value{ __i } {}
+ int imag ();
+ void operator+=(complex __z) { _M_value = __z.imag (); }
+ _Complex double _M_value;
+};
+}
+class A
+{
+public:
+ A (int);
+ std::complex<double> &operator[](int i) { return data_[i]; }
+ std::complex<double> *data_;
+};
+struct B
+{
+ static std::complex<double>
+ apply (std::complex<double> t1, std::complex<double> t2)
+ {
+ return t1 + t2;
+ }
+};
+template <class T1, class> struct C
+{
+ static void
+ apply (T1 t1, std::complex<double> t2)
+ {
+ t1 = t2;
+ }
+};
+template <class E> class D
+{
+public:
+ E operator()();
+};
+class G : public D<G>
+{
+public:
+ typedef std::complex<double> value_type;
+ value_type operator()(int) { return B::apply (0, 0); }
+};
+template <class E1, class E2> G operator+(D<E1>, D<E2>);
+template <template <class, class> class F, class V, class E>
+void
+indexing_vector_assign (V v, D<E> e)
+{
+ for (int i;; ++i)
+ F<typename V::reference, typename E::value_type>::apply (v (i), e ()(0));
+}
+template <template <class, class> class F, class V, class E>
+void
+vector_assign (V v, D<E> e, int)
+{
+ indexing_vector_assign<F> (v, e);
+}
+template <template <class, class> class F, class V, class E>
+void
+vector_assign (V v, D<E> e)
+{
+ vector_assign<F> (v, e, typename V::storage_category ());
+}
+class H : public D<int>
+{
+public:
+ typedef std::complex<double> &reference;
+ typedef int storage_category;
+ H (int);
+ template <class AE> H (D<AE> ae) : data_ (0)
+ {
+ vector_assign<C> (*this, ae);
+ }
+ A
+ data ()
+ {
+ return data_;
+ }
+ reference operator()(int i) { return data ()[i]; }
+ A data_;
+};
+template <class T1, class V1, class T2, class V2>
+void
+rot (T1, V1 v1, T2, V2 v2)
+{
+ H (v1 + v2);
+}
+template <class, unsigned long> struct F
+{
+ void test ();
+};
+template struct F<H, 3>;
+template <class V, std::size_t N>
+void
+F<V, N>::test ()
+{
+ V b (0), c (0);
+ rot (0, b, 0, c);
+}
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 6054ef4..aa82ec0 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2267,6 +2267,8 @@ pass_forwprop::execute (function *fun)
gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
}
+
+ release_defs (stmt);
gsi_remove (&gsi, true);
}
else
@@ -2281,7 +2283,9 @@ pass_forwprop::execute (function *fun)
if (single_imm_use (lhs, &use_p, &use_stmt)
&& gimple_store_p (use_stmt)
&& !gimple_has_volatile_ops (use_stmt)
- && is_gimple_assign (use_stmt))
+ && is_gimple_assign (use_stmt)
+ && (TREE_CODE (gimple_assign_lhs (use_stmt))
+ != TARGET_MEM_REF))
{
tree use_lhs = gimple_assign_lhs (use_stmt);
tree new_lhs = build1 (REALPART_EXPR,
@@ -2302,6 +2306,7 @@ pass_forwprop::execute (function *fun)
gimple_assign_set_rhs1 (use_stmt, gimple_assign_rhs2 (stmt));
update_stmt (use_stmt);
+ release_defs (stmt);
gsi_remove (&gsi, true);
}
else