diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 57a464345c7144f927765f00f1ce9601f8ec30cc..c39304c465b5889c3ff93a4a9d13f7f4786efe35 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2009-12-28 Jason Merrill <jason@redhat.com> + + PR c++/42447 + * pt.c (iterative_hash_template_arg): Don't rely on TYPE_CANONICAL + for ARRAY_TYPE. + 2009-12-24 Jason Merrill <jason@redhat.com> PR c++/41305, DR 384 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 85ad539f419251881cdf2c0fbb4cf0039cf013c6..d5342a1653fd0700b486a49bb45dfb6c4a8e9bd6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1553,6 +1553,13 @@ iterative_hash_template_arg (tree arg, hashval_t val) val = iterative_hash_object (code, val); return iterative_hash_template_arg (TREE_OPERAND (arg, 2), val); + case ARRAY_TYPE: + /* layout_type sets structural equality for arrays of + incomplete type, so we can't rely on the canonical type + for hashing. */ + val = iterative_hash_template_arg (TREE_TYPE (arg), val); + return iterative_hash_template_arg (TYPE_DOMAIN (arg), val); + default: switch (tclass) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aef38ad70f5135fd473e775ea2956859087a4c2f..179b08cb36b44f8cc1c270f7e694836f72e97062 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-12-28 Jason Merrill <jason@redhat.com> + + PR c++/42447 + * g++.dg/template/array21.C: New. + 2009-12-28 Janus Weil <janus@gcc.gnu.org> PR fortran/42353 diff --git a/gcc/testsuite/g++.dg/template/array21.C b/gcc/testsuite/g++.dg/template/array21.C new file mode 100644 index 0000000000000000000000000000000000000000..5c5f2f65d6b7be412c0f7ec75b6926a4e22eb8ca --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array21.C @@ -0,0 +1,50 @@ +// PR c++/42447 + +template<int> + void* get(int); + +template<typename> + struct unique_ptr; + +template<typename _Tp> + struct unique_ptr<_Tp[]> + { + typedef int __tuple_type; + + void* + get() const + { return ::get<0>(_M_t); } + + __tuple_type _M_t; + }; + +template <typename T> class dynamic_dispatch; + +template <typename TC> + struct dynamic_dispatch<void (TC::*)(int&)> + { + struct entry { }; + unique_ptr<entry[]> m_Start; + + template <typename UC> + void attach_handler(void (UC::*m)(int&)) + { + entry* p = 0; + do { + } while(--p != m_Start.get()); + } + }; + +template <typename TC> + class request_dispatcher + : private dynamic_dispatch<void (TC::*)(int&)> + { request_dispatcher(); }; + +struct file_reader +{ + void execute_command(int&); +}; + +template <> + request_dispatcher<file_reader>::request_dispatcher() + { this->attach_handler(&file_reader::execute_command); }