diff options
author | Kirill Yukhin <kirill.yukhin@intel.com> | 2011-07-08 13:12:03 +0000 |
---|---|---|
committer | H.J. Lu <hjl@gcc.gnu.org> | 2011-07-08 06:12:03 -0700 |
commit | 6c3cb698c53a85548621eeb871011b6d7774051c (patch) | |
tree | 12985c1b71115046191bb5215bc72531f64397e2 /gcc/testsuite | |
parent | 7d8d6d7359822490c1a14cfcde0c736c4d220d34 (diff) | |
download | gcc-6c3cb698c53a85548621eeb871011b6d7774051c.zip gcc-6c3cb698c53a85548621eeb871011b6d7774051c.tar.gz gcc-6c3cb698c53a85548621eeb871011b6d7774051c.tar.bz2 |
re PR middle-end/49519 (Revision 175272 miscompiled 447.dealII in SPEC CPU 2006)
Fix PR middle-end/49519.
gcc/
2011-07-08 Kirill Yukhin <kirill.yukhin@intel.com>
PR middle-end/49519
* calls.c (mem_overlaps_already_clobbered_arg_p): Additional
check if address is stored in register. If so - give up.
(check_sibcall_argument_overlap_1): Do not perform check of
overlapping when it is call to address.
gcc/tessuite/
2011-07-08 Kirill Yukhin <kirill.yukhin@intel.com>
PR middle-end/49519
* g++.dg/torture/pr49519.C: New test.
From-SVN: r176042
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr49519.C | 135 |
2 files changed, 140 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 93d7c82..360c0aa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-07-08 Kirill Yukhin <kirill.yukhin@intel.com> + + PR middle-end/49519 + * g++.dg/torture/pr49519.C: New test. + 2011-07-08 Martin Jambor <mjambor@suse.cz> * gcc.dg/tree-ssa/sra-12.c: Skip dump scan on avr targets. diff --git a/gcc/testsuite/g++.dg/torture/pr49519.C b/gcc/testsuite/g++.dg/torture/pr49519.C new file mode 100644 index 0000000..2888709 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr49519.C @@ -0,0 +1,135 @@ +/* { dg-do run } */ + +#include <stdlib.h> + +struct null_type {}; + +inline const null_type cnull() { return null_type(); } + +template <class TT> struct cons; +class tuple; + +template< int N > +struct get_class { + template<class TT > + inline static int& get(cons<TT>& t) + { + return get_class<N-1>::template get(t.tail); + } +}; + +template<> +struct get_class<0> { + template<class TT> + inline static int& get(cons<TT>& t) + { + return t.head; + } +}; + +template<int N, class T> +struct element +{ +private: + typedef typename T::tail_type Next; +public: + typedef typename element<N-1, Next>::type type; +}; + +template<class T> +struct element<0,T> +{ + typedef int type; +}; + +template<int N, class TT> +inline int& get(cons<TT>& c) { + return get_class<N>::template get(c); +} + +template <class TT> +struct cons { + typedef TT tail_type; + + int head; + tail_type tail; + + cons() : head(), tail() {} + + template <class T1, class T2, class T3, class T4> + cons( T1& t1, T2& t2, T3& t3, T4& t4 ) + : head (t1), + tail (t2, t3, t4, cnull()) + {} +}; + +template <> +struct cons<null_type> { + typedef null_type tail_type; + + int head; + + cons() : head() {} + + template<class T1> + cons(T1& t1, const null_type&, const null_type&, const null_type&) + : head (t1) {} +}; + +template <class T0, class T1, class T2, class T3> +struct map_tuple_to_cons +{ + typedef cons<typename map_tuple_to_cons<T1, T2, T3, null_type>::type> type; +}; + +template <> +struct map_tuple_to_cons<null_type, null_type, null_type, null_type> +{ + typedef null_type type; +}; + +class tuple : + public map_tuple_to_cons<int, int, int, int>::type +{ +public: + typedef typename + map_tuple_to_cons<int, int, int, int>::type inherited; + + tuple(const int &t0, + const int &t1, + const int &t2, + const int &t3) + : inherited(t0, t1, t2, t3) {} +}; + +void foo(void (*boo)(int, int, int, int), tuple t) +{ + boo(get<0>(t), get<1>(t), get<2>(t), get<3>(t)); +} + +int tailcalled_t1; +int tailcalled_t2; +int tailcalled_t3; +int tailcalled_t4; + +void print(int t1, int t2, int t3, int t4) +{ + tailcalled_t1 = t1; + tailcalled_t2 = t2; + tailcalled_t3 = t3; + tailcalled_t4 = t4; +} + +int main () +{ + tuple t(1,2,3,4); + foo(print, t); + + if( (get<0>(t) != tailcalled_t1) + ||(get<1>(t) != tailcalled_t2) + ||(get<2>(t) != tailcalled_t3) + ||(get<3>(t) != tailcalled_t4)) + abort(); + + return 0; +} |