From 8a5d50bd4837528ad014f967f5c92022b129c6b1 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 15 Dec 2009 13:57:39 -0500 Subject: [PATCH] re PR c++/42358 ([C++0x] Assembler failure on libstdc++-v3/testsuite/23_containers/multimap/init-list.cc with -O0) PR c++/42358 * pt.c (iterative_hash_template_arg): Completely ignore ARGUMENT_PACK_SELECT. From-SVN: r155267 --- gcc/cp/ChangeLog | 6 + gcc/cp/pt.c | 10 +- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/g++.dg/cpp0x/variadic98.C | 411 ++++++++++++++++++++++++ 4 files changed, 427 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic98.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d9d758ff3a74..f00ef8451582 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2009-12-15 Jason Merrill + + PR c++/42358 + * pt.c (iterative_hash_template_arg): Completely ignore + ARGUMENT_PACK_SELECT. + 2009-12-15 Jakub Jelinek PR c++/41183 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index dfd2399bfc5c..24852dd22553 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1457,6 +1457,11 @@ iterative_hash_template_arg (tree arg, hashval_t val) if (!TYPE_P (arg)) STRIP_NOPS (arg); + if (TREE_CODE (arg) == ARGUMENT_PACK_SELECT) + /* We can get one of these when re-hashing a previous entry in the middle + of substituting into a pack expansion. Just look through it. */ + arg = ARGUMENT_PACK_SELECT_FROM_PACK (arg); + code = TREE_CODE (arg); tclass = TREE_CODE_CLASS (code); @@ -1482,11 +1487,6 @@ iterative_hash_template_arg (tree arg, hashval_t val) case EXPR_PACK_EXPANSION: return iterative_hash_template_arg (PACK_EXPANSION_PATTERN (arg), val); - case ARGUMENT_PACK_SELECT: - /* We can get one of these when re-hashing a previous entry in the middle - of substituting into a pack expansion. Just look through it... */ - arg = ARGUMENT_PACK_SELECT_FROM_PACK (arg); - /* ...and fall through. */ case TYPE_ARGUMENT_PACK: case NONTYPE_ARGUMENT_PACK: return iterative_hash_template_arg (ARGUMENT_PACK_ARGS (arg), val); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d2694286518f..154942416685 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-12-15 Jason Merrill + + PR c++/42358 + * g++.dg/cpp0x/variadic98.C: New. + 2009-12-14 Jason Merrill PR c++/42373 diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic98.C b/gcc/testsuite/g++.dg/cpp0x/variadic98.C new file mode 100644 index 000000000000..6af599fcaa00 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic98.C @@ -0,0 +1,411 @@ +// PR c++/42358 +// { dg-do assemble } +// { dg-options -std=c++0x } + +typedef __PTRDIFF_TYPE__ ptrdiff_t; +typedef __SIZE_TYPE__ size_t; +namespace std __attribute__ ((__visibility__ ("default"))) { + using ::size_t; +} +namespace std __attribute__ ((__visibility__ ("default"))) { + struct __sfinae_types { + typedef char __one; + typedef struct { + } __two; + }; + template struct integral_constant { + static const _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant<_Tp, __v> type; + }; + typedef integral_constant false_type; + template struct remove_cv; + template struct __is_void_helper : public false_type { + }; + template struct is_void : public integral_constant::type>::value)> { + }; + template struct is_array : public false_type { + }; + template struct is_function : public false_type { + }; + template struct extent : public integral_constant { + }; + template struct remove_const { + typedef _Tp type; + }; + template struct remove_volatile { + typedef _Tp type; + }; + template struct remove_cv { + typedef typename remove_const::type>::type type; + }; + template struct is_lvalue_reference : public false_type { + }; + template struct is_rvalue_reference : public false_type { + }; + template struct is_reference : public integral_constant::value || is_rvalue_reference<_Tp>::value)> { + }; + template struct remove_reference { + typedef _Tp type; + }; + template::value && !is_void<_Tp>::value> struct __add_rvalue_reference_helper { + typedef _Tp type; + }; + template struct add_rvalue_reference : public __add_rvalue_reference_helper<_Tp> { + }; + template typename add_rvalue_reference<_Tp>::type declval(); + template::value || is_void<_To>::value || is_function<_To>::value || is_array<_To>::value)> struct __is_convertible_helper { + }; + template struct __is_convertible_helper<_From, _To, false> : public __sfinae_types { + static __one __test(_To); + static __two __test(...); + static const bool __value = sizeof(__test(declval<_From>())) == 1; + }; + template struct is_convertible : public integral_constant::__value> { + }; + template struct enable_if { + }; + template struct enable_if { + typedef _Tp type; + }; + template struct identity { + typedef _Tp type; + }; + template inline typename enable_if::value, _Tp&&>::type forward(typename std::identity<_Tp>::type& __t) { + } + template inline typename enable_if::value, _Tp>::type forward(typename std::identity<_Tp>::type __t) { + } + template inline typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) { + } + template struct pair { + typedef _T1 first_type; + typedef _T2 second_type; + _T1 first; + _T2 second; + template::value>::type> pair(_U1&& __x, const _T2& __y) : first(std::forward<_U1>(__x)), second(__y) { + } + template::value>::type> pair(const _T1& __x, _U2&& __y) : first(__x), second(std::forward<_U2>(__y)) { + } + template::value && std::is_convertible<_U2, _T2>::value>::type> pair(_U1&& __x, _U2&& __y) : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { + } + template pair(pair<_U1, _U2>&& __p) : first(std::move(__p.first)), second(std::move(__p.second)) { + } + template pair& operator=(pair<_U1, _U2>&& __p) { + } + }; + struct input_iterator_tag { + }; + struct output_iterator_tag { + }; + struct forward_iterator_tag : public input_iterator_tag { + }; + struct bidirectional_iterator_tag : public forward_iterator_tag { + }; + template struct iterator { + typedef _Category iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Pointer pointer; + typedef _Reference reference; + }; + template struct iterator_traits { + typedef typename _Iterator::iterator_category iterator_category; + typedef typename _Iterator::value_type value_type; + typedef typename _Iterator::difference_type difference_type; + typedef typename _Iterator::pointer pointer; + typedef typename _Iterator::reference reference; + }; + template inline typename iterator_traits<_Iter>::iterator_category __iterator_category(const _Iter&) { + } + template inline typename iterator_traits<_InputIterator>::difference_type __distance(_InputIterator __first, _InputIterator __last, input_iterator_tag) { + } + template inline typename iterator_traits<_InputIterator>::difference_type distance(_InputIterator __first, _InputIterator __last) { + return std::__distance(__first, __last, std::__iterator_category(__first)); + } + template class reverse_iterator : public iterator::iterator_category, typename iterator_traits<_Iterator>::value_type, typename iterator_traits<_Iterator>::difference_type, typename iterator_traits<_Iterator>::pointer, typename iterator_traits<_Iterator>::reference> { + }; + template class back_insert_iterator : public iterator { + }; +} +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) { + template class new_allocator { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + new_allocator() throw() { + } + new_allocator(const new_allocator&) throw() { + } + template new_allocator(const new_allocator<_Tp1>&) throw() { + } + template void construct(pointer __p, _Args&&... __args) { + } + }; +} +namespace std __attribute__ ((__visibility__ ("default"))) { + template class allocator: public __gnu_cxx::new_allocator<_Tp> { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + template struct rebind { + typedef allocator<_Tp1> other; + }; + allocator() throw() { + } + template allocator(const allocator<_Tp1>&) throw() { + } + }; + extern template class allocator; + extern template class allocator; + template struct unary_function { + typedef _Arg argument_type; + typedef _Result result_type; + }; + template struct binary_function { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; + }; + template struct less : public binary_function<_Tp, _Tp, bool> { + bool operator()(const _Tp& __x, const _Tp& __y) const { + } + }; + template struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { + const typename _Pair::first_type& operator()(const _Pair& __x) const { + } + }; + struct _Rb_tree_node_base { + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + }; + template struct _Rb_tree_node : public _Rb_tree_node_base { + typedef _Rb_tree_node<_Val>* _Link_type; + _Val _M_value_field; + template _Rb_tree_node(_Args&&... __args) : _Rb_tree_node_base(), _M_value_field(std::forward<_Args>(__args)...) { + } + }; + template struct _Rb_tree_iterator { + typedef _Tp value_type; + typedef _Tp& reference; + typedef _Tp* pointer; + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + typedef _Rb_tree_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; + typedef _Rb_tree_node<_Tp>* _Link_type; + _Base_ptr _M_node; + }; + template struct _Rb_tree_const_iterator { + typedef _Tp value_type; + typedef const _Tp& reference; + typedef const _Tp* pointer; + typedef _Rb_tree_iterator<_Tp> iterator; + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + typedef _Rb_tree_const_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; + typedef const _Rb_tree_node<_Tp>* _Link_type; + explicit _Rb_tree_const_iterator(_Link_type __x) : _M_node(__x) { + } + _Rb_tree_const_iterator(const iterator& __it) : _M_node(__it._M_node) { + } + _Base_ptr _M_node; + }; + template > class _Rb_tree { + typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other _Node_allocator; + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + public: + typedef _Key key_type; + typedef _Val value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _Rb_tree_node<_Val>* _Link_type; + typedef const _Rb_tree_node<_Val>* _Const_Link_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + _Node_allocator& _M_get_Node_allocator() { + } + _Link_type _M_get_node() { + } + template _Link_type _M_create_node(_Args&&... __args) { + _Link_type __tmp = _M_get_node(); + try { + _M_get_Node_allocator().construct(__tmp, std::forward<_Args>(__args)...); + } + catch(...) { + } + } + template struct _Rb_tree_impl : public _Node_allocator { + _Key_compare _M_key_compare; + _Rb_tree_node_base _M_header; + size_type _M_node_count; + _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a) : _Node_allocator(__a), _M_key_compare(__comp), _M_header(), _M_node_count(0) { + } + void _M_initialize() { + } + }; + _Rb_tree_impl<_Compare> _M_impl; + _Base_ptr& _M_rightmost() { + } + _Link_type _M_begin() { + } + _Link_type _M_end() { + } + _Const_Link_type _M_end() const { + } + static _Link_type _S_right(_Base_ptr __x) { + } + static const_reference _S_value(_Const_Base_ptr __x) { + } + static const _Key& _S_key(_Const_Base_ptr __x) { + return _KeyOfValue()(_S_value(__x)); + } + typedef _Rb_tree_iterator iterator; + typedef _Rb_tree_const_iterator const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + iterator _M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __y, const value_type& __v); + iterator _M_insert_lower(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + iterator _M_insert_equal_lower(const value_type& __x); + iterator _M_lower_bound(_Link_type __x, _Link_type __y, const _Key& __k); + iterator _M_upper_bound(_Link_type __x, _Link_type __y, const _Key& __k); + _Rb_tree(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_impl(__comp, __a) { + } + iterator end() { + } + iterator _M_insert_equal_(const_iterator __position, const value_type& __x); + template void _M_insert_unique(_InputIterator __first, _InputIterator __last); + template void _M_insert_equal(_InputIterator __first, _InputIterator __last); + size_type count(const key_type& __k) const; + pair equal_range(const key_type& __k); + pair equal_range(const key_type& __k) const; + }; + template typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v) { + _Link_type __z = _M_create_node(__v); + } + template typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_insert_lower(_Base_ptr __x, _Base_ptr __p, const _Val& __v) { + _Link_type __z = _M_create_node(__v); + } + template typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_insert_equal_lower(const _Val& __v) { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + return _M_insert_lower(__x, __y, __v); + } + template pair::iterator, typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: equal_range(const _Key& __k) { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) { + if (_M_impl._M_key_compare(_S_key(__x), __k)) __x = _S_right(__x); + else { + _Link_type __xu(__x), __yu(__y); + return pair(_M_lower_bound(__x, __y, __k), _M_upper_bound(__xu, __yu, __k)); + } + } + } + template pair::const_iterator, typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: equal_range(const _Key& __k) const { + _Const_Link_type __y = _M_end(); + return pair(const_iterator(__y), const_iterator(__y)); + } + template typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_insert_equal_(const_iterator __position, const _Val& __v) { + if (__position._M_node == _M_end()) { + if (__position._M_node == _M_rightmost()) return _M_insert_(0, _M_rightmost(), __v); + else return _M_insert_equal_lower(__v); + } + } + template template void _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: _M_insert_equal(_II __first, _II __last) { + for (; + __first != __last; + ++__first) _M_insert_equal_(end(), *__first); + } + template typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: count(const _Key& __k) const { + pair __p = equal_range(__k); + const size_type __n = std::distance(__p.first, __p.second); + } + template class initializer_list { + public: + typedef _E value_type; + typedef const _E& reference; + typedef const _E& const_reference; + typedef size_t size_type; + typedef const _E* iterator; + typedef const _E* const_iterator; + iterator _M_array; + size_type _M_len; + initializer_list(const_iterator __a, size_type __l) : _M_array(__a), _M_len(__l) { + } + const_iterator begin() const { + } + const_iterator end() const { + } + }; + template , typename _Alloc = std::allocator > > class multimap { + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair value_type; + typedef _Compare key_compare; + typedef _Alloc allocator_type; + typedef typename _Alloc::value_type _Alloc_value_type; + typedef typename _Alloc::template rebind::other _Pair_alloc_type; + typedef _Rb_tree, key_compare, _Pair_alloc_type> _Rep_type; + _Rep_type _M_t; + public: + typedef typename _Pair_alloc_type::pointer pointer; + typedef typename _Pair_alloc_type::const_pointer const_pointer; + typedef typename _Pair_alloc_type::reference reference; + typedef typename _Pair_alloc_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + multimap(initializer_list __l, const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { + _M_t._M_insert_equal(__l.begin(), __l.end()); + } + template multimap(_InputIterator __first, _InputIterator __last) : _M_t() { + } + template multimap(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { + } + template void insert(_InputIterator __first, _InputIterator __last) { + } + size_type count(const key_type& __x) const { + return _M_t.count(__x); + } + std::pair equal_range(const key_type& __x) { + return _M_t.equal_range(__x); + } + template friend bool operator==(const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); + template friend bool operator<(const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); + }; +} +extern "C" { + extern void __assert_fail (__const char *__assertion, __const char *__file, unsigned int __line, __const char *__function) throw () __attribute__ ((__noreturn__)); +} +using namespace std; +int test01() { + typedef multimap Container; + typedef Container::iterator iterator; + typedef pair itpair; + Container m({ + { + 1, 1.0 } + } + ); + itpair ip = m.equal_range(1); + ((distance(ip.first, ip.second) == 3) ? static_cast (0) : __assert_fail ("distance(ip.first, ip.second) == 3", "/home/richard/src/trunk/libstdc++-v3/testsuite/23_containers/multimap/init-list.cc", 36, __PRETTY_FUNCTION__)); + ((m.count(7) == 2) ? static_cast (0) : __assert_fail ("m.count(7) == 2", "/home/richard/src/trunk/libstdc++-v3/testsuite/23_containers/multimap/init-list.cc", 54, __PRETTY_FUNCTION__)); +} -- 2.43.5