Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard.
2014-12-15 Richard Biener <rguent...@suse.de> PR tree-optimization/64312 * tree-ssa-sccvn.c (vn_reference_lookup_pieces): Use vuse_ssa_val as callback to walk_non_aliased_vuses. (vn_reference_lookup): Likewise. * g++.dg/torture/pr64312.C: New testcase. Index: gcc/tree-ssa-sccvn.c =================================================================== --- gcc/tree-ssa-sccvn.c (revision 218749) +++ gcc/tree-ssa-sccvn.c (working copy) @@ -2161,7 +2161,7 @@ vn_reference_lookup_pieces (tree vuse, a (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse, vn_reference_lookup_2, vn_reference_lookup_3, - vn_valueize, &vr1); + vuse_ssa_val, &vr1); gcc_checking_assert (vr1.operands == shared_lookup_references); } @@ -2214,7 +2214,7 @@ vn_reference_lookup (tree op, tree vuse, (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse, vn_reference_lookup_2, vn_reference_lookup_3, - vn_valueize, &vr1); + vuse_ssa_val, &vr1); gcc_checking_assert (vr1.operands == shared_lookup_references); if (wvnresult) { Index: gcc/testsuite/g++.dg/torture/pr64312.C =================================================================== --- gcc/testsuite/g++.dg/torture/pr64312.C (revision 0) +++ gcc/testsuite/g++.dg/torture/pr64312.C (working copy) @@ -0,0 +1,123 @@ +// { dg-do compile } + +template <typename C> struct A +{ + typedef typename C::iterator type; +}; +template <typename T2> struct B +{ + typedef T2 type; +}; +template <typename F2> struct L +{ + typedef typename B<F2>::type::type type; +}; +template <typename C> struct M +{ + typedef typename L<A<C> >::type type; +}; +class C +{ +public: + typedef int iterator; +}; +template <class IteratorT> class D +{ +public: + typedef IteratorT iterator; + template <class Iterator> D (Iterator p1, Iterator) : m_Begin (p1), m_End (0) + { + } + IteratorT m_Begin; + IteratorT m_End; +}; +template <class IteratorT> class I : public D<IteratorT> +{ +protected: + template <class Iterator> + I (Iterator p1, Iterator p2) + : D<IteratorT> (p1, p2) + { + } +}; +class F +{ +public: + int elems[]; + int * + m_fn1 () + { + return elems; + } +}; +class G +{ +public: + void * + m_fn2 (int) + { + return m_buffer.m_fn1 (); + } + F m_buffer; +}; +struct any_incrementable_iterator_interface +{ + virtual ~any_incrementable_iterator_interface () {} +}; +class J : public any_incrementable_iterator_interface +{ +public: + J (int) : m_it () {} + int m_it; +}; +void *operator new(unsigned long, void *p2) { return p2; } +template <class T> typename M<T>::type begin (T) { return 0; } +template <class T> typename M<T>::type end (T) {} +template <class> class any_iterator +{ +public: + template <class WrappedIterator> any_iterator (WrappedIterator) + { + void *ptr = m_buffer.m_fn2 (0); + m_impl = new (ptr) J (0); + } + ~any_iterator () + { + if (m_impl) + m_impl->~any_incrementable_iterator_interface (); + } + G m_buffer; + any_incrementable_iterator_interface *m_impl; +}; +template <class Reference> class K : public I<any_iterator<Reference> > +{ +public: + template <class WrappedRange> + K (WrappedRange p1) + : I<any_iterator<Reference> > (begin (p1), end (p1)) + { + } +}; +template <class Reference> struct H +{ + typedef K<Reference> type; +}; +template <class, class, class, class, class, class TargetReference> +void +mix_values_impl () +{ + C test_data; + H<int>::type source_data (test_data); + typename H<TargetReference>::type t2 = source_data; +} +template <class> +void +mix_values_driver () +{ + mix_values_impl<int, int, int, int, int, int &> (); +} +void +mix_values () +{ + mix_values_driver<int> (); +}