diff options
author | Richard Biener <rguenther@suse.de> | 2015-01-13 08:32:13 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-01-13 08:32:13 +0000 |
commit | a2d429ac5e450845f3febbfba21d3bb486fcf7ce (patch) | |
tree | 71d4302bbc8f858c29bcf76ecec98e40ee75f40f /gcc | |
parent | 0d7a9dbdd23c58761a85f22e18982242e2dc9621 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr64568.C | 111 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 7 |
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 |