From 9ade9945a07c47abf2d1d5ad3a5de504e9f37b73 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 19 Jan 2017 20:29:07 +0000 Subject: [PATCH] Fix unsafe moves inside loops PR libstdc++/67085 * include/bits/stl_heap.h (__is_heap): Use _GLIBCXX_MOVE. (__make_heap, __sort_heap): Don't use _GLIBCXX_MOVE inside loops. * testsuite/23_containers/priority_queue/67085.cc: Adjust expected number of copies. * testsuite/25_algorithms/make_heap/movable.cc: New test. From-SVN: r244650 --- libstdc++-v3/ChangeLog | 7 ++++ libstdc++-v3/include/bits/stl_heap.h | 9 +++-- .../23_containers/priority_queue/67085.cc | 4 +- .../25_algorithms/make_heap/movable.cc | 38 +++++++++++++++++++ 4 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 libstdc++-v3/testsuite/25_algorithms/make_heap/movable.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7fd289dfd08..0106c23a3ef 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,12 @@ 2017-01-19 Jonathan Wakely + PR libstdc++/67085 + * include/bits/stl_heap.h (__is_heap): Use _GLIBCXX_MOVE. + (__make_heap, __sort_heap): Don't use _GLIBCXX_MOVE inside loops. + * testsuite/23_containers/priority_queue/67085.cc: Adjust expected + number of copies. + * testsuite/25_algorithms/make_heap/movable.cc: New test. + PR libstdc++/67085 * include/bits/stl_heap.h (push_heap, __adjust_heap, __pop_heap) (pop_heap, __make_heap, make_heap, __sort_heap, sort_heap): Use diff --git a/libstdc++-v3/include/bits/stl_heap.h b/libstdc++-v3/include/bits/stl_heap.h index c82ce7753ed..b19c9f499b8 100644 --- a/libstdc++-v3/include/bits/stl_heap.h +++ b/libstdc++-v3/include/bits/stl_heap.h @@ -113,7 +113,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline bool __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) - { return std::__is_heap(__first, __comp, std::distance(__first, __last)); } + { + return std::__is_heap(__first, _GLIBCXX_MOVE(__comp), + std::distance(__first, __last)); + } // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap, // + is_heap and is_heap_until in C++0x. @@ -336,7 +339,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent)); std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value), - _GLIBCXX_MOVE(__comp)); + __comp); if (__parent == 0) return; __parent--; @@ -401,7 +404,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION while (__last - __first > 1) { --__last; - std::__pop_heap(__first, __last, __last, _GLIBCXX_MOVE(__comp)); + std::__pop_heap(__first, __last, __last, __comp); } } diff --git a/libstdc++-v3/testsuite/23_containers/priority_queue/67085.cc b/libstdc++-v3/testsuite/23_containers/priority_queue/67085.cc index 5a3ca32c3a8..4ccea309fcf 100644 --- a/libstdc++-v3/testsuite/23_containers/priority_queue/67085.cc +++ b/libstdc++-v3/testsuite/23_containers/priority_queue/67085.cc @@ -34,9 +34,9 @@ test01() { int v[] = {1, 2, 3, 4}; std::priority_queue, CopyCounter> q{v, v+4}; - VERIFY(count == 2); + VERIFY(count == 4); q.push(1); - VERIFY(count == 3); + VERIFY(count == 5); } int diff --git a/libstdc++-v3/testsuite/25_algorithms/make_heap/movable.cc b/libstdc++-v3/testsuite/25_algorithms/make_heap/movable.cc new file mode 100644 index 00000000000..f6738f1d6db --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/make_heap/movable.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2017 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include +#include + +void +test01() +{ + int i[] = { 1, 2, 3, 4 }; + std::function f = std::less<>{}; + // If this uses a moved-from std::function we'll get an exception: + std::make_heap(std::begin(i), std::end(i), f); + std::sort_heap(std::begin(i), std::end(i), f); +} + +int +main() +{ + test01(); +} -- 2.30.2