diff options
author | fdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-18 20:17:57 +0000 |
---|---|---|
committer | fdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-18 20:17:57 +0000 |
commit | 5de0281d0e6f37ff1435516f3d55f22ad72279bc (patch) | |
tree | 8abd2d9719fc4e2b32085b95da5449eaee01bded /libstdc++-v3/testsuite/23_containers | |
parent | ddf9700643b02ae94180d7e6657b8afda552d65c (diff) | |
download | gcc-5de0281d0e6f37ff1435516f3d55f22ad72279bc.tar.gz |
2012-01-18 François Dumont <fdumont@gcc.gnu.org>
Roman Kononov <roman@binarylife.net>
PR libstdc++/51866
* include/bits/hashtable.h (_Hashtable<>::_M_insert(_Arg, false_type)):
Do not keep a reference to a potentially moved instance.
* testsuite/23_containers/unordered_multiset/insert/51866.cc: New.
* testsuite/23_containers/unordered_multimap/insert/51866.cc: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183285 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/testsuite/23_containers')
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/51866.cc | 87 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/51866.cc | 87 |
2 files changed, 174 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/51866.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/51866.cc new file mode 100644 index 00000000000..aa85c4b1d5a --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/51866.cc @@ -0,0 +1,87 @@ +// { dg-options "-std=gnu++0x" } +// +// Copyright (C) 2012 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <unordered_map> +#include <testsuite_hooks.h> + +struct num +{ + int value; + num(int n) : value(n) {} + num(num const&) = default; + num& operator=(num const&) = default; + num(num&& o) : value(o.value) + { o.value = -1; } + num& operator=(num&& o) + { + if (this != &o) + { + value = o.value; + o.value = -1; + } + return *this; + } +}; + +struct num_hash +{ + size_t operator()(num const& a) const + { return a.value; } +}; + +struct num_equal +{ + static bool _S_called_on_moved_instance; + bool operator()(num const& a, num const& b) const + { + if (a.value == -1 || b.value == -1) + _S_called_on_moved_instance = true; + return a.value == b.value; + } +}; + +bool num_equal::_S_called_on_moved_instance = false; + +// libstdc++/51866 +void test01() +{ + bool test __attribute__((unused)) = true; + + std::unordered_multimap<num, int, num_hash, num_equal> mmap; + mmap.insert(std::make_pair(num(1), 1)); + mmap.insert(std::make_pair(num(2), 2)); + mmap.insert(std::make_pair(num(1), 3)); + mmap.insert(std::make_pair(num(2), 4)); + VERIFY( mmap.size() == 4 ); + auto iter = mmap.cbegin(); + auto x0 = (iter++)->first.value; + auto x1 = (iter++)->first.value; + auto x2 = (iter++)->first.value; + auto x3 = (iter++)->first.value; + VERIFY( iter == mmap.cend() ); + VERIFY( (x0 == 1 && x1 == 1 && x2 == 2 && x3 == 2) + || (x0 == 2 && x1 == 2 && x2 == 1 && x3 == 1) ); + VERIFY( !num_equal::_S_called_on_moved_instance ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/51866.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/51866.cc new file mode 100644 index 00000000000..7ee0dce3a45 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/51866.cc @@ -0,0 +1,87 @@ +// { dg-options "-std=gnu++0x" } +// +// Copyright (C) 2012 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <unordered_set> +#include <testsuite_hooks.h> + +struct num +{ + int value; + num(int n) : value(n) {} + num(num const&) = default; + num& operator=(num const&) = default; + num(num&& o) : value(o.value) + { o.value = -1; } + num& operator=(num&& o) + { + if (this != &o) + { + value = o.value; + o.value = -1; + } + return *this; + } +}; + +struct num_hash +{ + size_t operator()(num const& a) const + { return a.value; } +}; + +struct num_equal +{ + static bool _S_called_on_moved_instance; + bool operator()(num const& a, num const& b) const + { + if (a.value == -1 || b.value == -1) + _S_called_on_moved_instance = true; + return a.value == b.value; + } +}; + +bool num_equal::_S_called_on_moved_instance = false; + +// libstdc++/51866 +void test01() +{ + bool test __attribute__((unused)) = true; + + std::unordered_multiset<num, num_hash, num_equal> mset; + mset.insert(num(1)); + mset.insert(num(2)); + mset.insert(num(1)); + mset.insert(num(2)); + VERIFY( mset.size() == 4 ); + auto iter = mset.cbegin(); + int x0 = (iter++)->value; + int x1 = (iter++)->value; + int x2 = (iter++)->value; + int x3 = (iter++)->value; + VERIFY( iter == mset.cend() ); + VERIFY( (x0 == 1 && x1 == 1 && x2 == 2 && x3 == 2) + || (x0 == 2 && x1 == 2 && x2 == 1 && x3 == 1) ); + VERIFY( !num_equal::_S_called_on_moved_instance ); +} + +int main() +{ + test01(); + return 0; +} |