public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/101587] New: uninitialized_copy/move incorrectly uses std::min
@ 2021-07-23 2:09 hewillk at gmail dot com
2021-07-23 8:33 ` [Bug libstdc++/101587] ranges::uninitialized_copy/move " redi at gcc dot gnu.org
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: hewillk at gmail dot com @ 2021-07-23 2:09 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101587
Bug ID: 101587
Summary: uninitialized_copy/move incorrectly uses std::min
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: hewillk at gmail dot com
Target Milestone: ---
ranges_uninitialized.h#L269:
if constexpr (sized_sentinel_for<_ISent, _Iter>
&& sized_sentinel_for<_OSent, _Out>
&& is_trivial_v<_OutType>
&& is_nothrow_assignable_v<_OutType&,
iter_reference_t<_Iter>>)
{
auto __d1 = __ilast - __ifirst;
auto __d2 = __olast - __ofirst;
return ranges::copy_n(std::move(__ifirst), std::min(__d1, __d2),
__ofirst);
}
We should make sure that __d1 and __d2 are the same types before calling
std::min, the same goes for uninitialized_copy_n/move_n.
#include <memory>
#include <ranges>
int main() {
auto r = std::views::iota(0l, 5l);
std::array<long, 5> o;
std::ranges::uninitialized_copy(r, o);
}
https://godbolt.org/z/fj7hM8qdx
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/101587] ranges::uninitialized_copy/move incorrectly uses std::min
2021-07-23 2:09 [Bug libstdc++/101587] New: uninitialized_copy/move incorrectly uses std::min hewillk at gmail dot com
@ 2021-07-23 8:33 ` redi at gcc dot gnu.org
2021-07-23 9:04 ` redi at gcc dot gnu.org
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2021-07-23 8:33 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101587
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Ever confirmed|0 |1
Status|UNCONFIRMED |NEW
Last reconfirmed| |2021-07-23
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/101587] ranges::uninitialized_copy/move incorrectly uses std::min
2021-07-23 2:09 [Bug libstdc++/101587] New: uninitialized_copy/move incorrectly uses std::min hewillk at gmail dot com
2021-07-23 8:33 ` [Bug libstdc++/101587] ranges::uninitialized_copy/move " redi at gcc dot gnu.org
@ 2021-07-23 9:04 ` redi at gcc dot gnu.org
2021-07-23 9:16 ` redi at gcc dot gnu.org
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2021-07-23 9:04 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101587
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Maybe we should add this somewhere and just stop using std::min for integers:
struct __min_fn
{
template<typename _Tp, typename _Up>
typename common_type<_Tp, _Up>::type
operator()(_Tp __t, _Up __u) const noexcept
{ return std::min<typename common_type<_Tp, _Up>::type>(__t, __u); }
};
_GLIBCXX17_INLINE constexpr __min_fn __min{};
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/101587] ranges::uninitialized_copy/move incorrectly uses std::min
2021-07-23 2:09 [Bug libstdc++/101587] New: uninitialized_copy/move incorrectly uses std::min hewillk at gmail dot com
2021-07-23 8:33 ` [Bug libstdc++/101587] ranges::uninitialized_copy/move " redi at gcc dot gnu.org
2021-07-23 9:04 ` redi at gcc dot gnu.org
@ 2021-07-23 9:16 ` redi at gcc dot gnu.org
2021-07-23 9:56 ` hewillk at gmail dot com
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2021-07-23 9:16 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101587
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |ASSIGNED
Assignee|unassigned at gcc dot gnu.org |redi at gcc dot gnu.org
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/101587] ranges::uninitialized_copy/move incorrectly uses std::min
2021-07-23 2:09 [Bug libstdc++/101587] New: uninitialized_copy/move incorrectly uses std::min hewillk at gmail dot com
` (2 preceding siblings ...)
2021-07-23 9:16 ` redi at gcc dot gnu.org
@ 2021-07-23 9:56 ` hewillk at gmail dot com
2021-07-23 10:34 ` redi at gcc dot gnu.org
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: hewillk at gmail dot com @ 2021-07-23 9:56 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101587
--- Comment #2 from 康桓瑋 <hewillk at gmail dot com> ---
(In reply to Jonathan Wakely from comment #1)
> Maybe we should add this somewhere and just stop using std::min for integers:
>
> struct __min_fn
> {
> template<typename _Tp, typename _Up>
> typename common_type<_Tp, _Up>::type
> operator()(_Tp __t, _Up __u) const noexcept
> { return std::min<typename common_type<_Tp, _Up>::type>(__t, __u); }
> };
> _GLIBCXX17_INLINE constexpr __min_fn __min{};
It may cause problems when comparing integers with different signedness.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/101587] ranges::uninitialized_copy/move incorrectly uses std::min
2021-07-23 2:09 [Bug libstdc++/101587] New: uninitialized_copy/move incorrectly uses std::min hewillk at gmail dot com
` (3 preceding siblings ...)
2021-07-23 9:56 ` hewillk at gmail dot com
@ 2021-07-23 10:34 ` redi at gcc dot gnu.org
2021-07-23 11:50 ` hewillk at gmail dot com
2021-07-23 12:12 ` redi at gcc dot gnu.org
6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2021-07-23 10:34 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101587
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
In theory yes, but it's unlikely to be a problem in practice because the
library doesn't need to compare unsigned types with negative values. If it does
need to do that, it is either already doing so carefully and correctly, or this
helper wouldn't make things worse.
I'm not suggesting designing a general purpose replacement for std::min that
handles all the possible corner cases, I'm just suggesting a convenience
function for our own internal needs.
All the uses in <bits/ranges_uninitialized.h> are with iterator difference
types, which had better be signed, and distance(first, last) had better be
non-negative too.
include/bits/hashtable_policy.h does:
const auto __max_width = std::min<size_t>(sizeof(size_t), 8);
This is mixing unsigned and signed, but both positive.
include/bits/locale_conv.h:
auto __nn = std::min<streamsize>(this->epptr() - this->pptr(),
__n - __done);
This compares ptrdiff_t with streamsize, which are both signed (and both values
here are guaranteed to be non-negative by construction).
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/101587] ranges::uninitialized_copy/move incorrectly uses std::min
2021-07-23 2:09 [Bug libstdc++/101587] New: uninitialized_copy/move incorrectly uses std::min hewillk at gmail dot com
` (4 preceding siblings ...)
2021-07-23 10:34 ` redi at gcc dot gnu.org
@ 2021-07-23 11:50 ` hewillk at gmail dot com
2021-07-23 12:12 ` redi at gcc dot gnu.org
6 siblings, 0 replies; 8+ messages in thread
From: hewillk at gmail dot com @ 2021-07-23 11:50 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101587
--- Comment #4 from 康桓瑋 <hewillk at gmail dot com> ---
(In reply to Jonathan Wakely from comment #3)
>
> I'm not suggesting designing a general purpose replacement for std::min that
> handles all the possible corner cases, I'm just suggesting a convenience
> function for our own internal needs.
Yep, this is reasonable, just like std::__memcmp does, and it is obviously
simpler than something like std::min<std::conditional_t<(sizeof(__d1) >
sizeof(__d1)), decltype(__d1), decltype(__d2)>>(__d1, __d2), and thank you for
your detailed explanation BTW.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/101587] ranges::uninitialized_copy/move incorrectly uses std::min
2021-07-23 2:09 [Bug libstdc++/101587] New: uninitialized_copy/move incorrectly uses std::min hewillk at gmail dot com
` (5 preceding siblings ...)
2021-07-23 11:50 ` hewillk at gmail dot com
@ 2021-07-23 12:12 ` redi at gcc dot gnu.org
6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2021-07-23 12:12 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101587
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Yes, much simpler than that! :-)
There are lots of uses of std::min and std::max with explicit template argument
lists in the Parallel Mode headers, but I have no intention of touching them,
and they need to work as C++98 so couldn't use the function above anyway.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-07-23 12:12 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-23 2:09 [Bug libstdc++/101587] New: uninitialized_copy/move incorrectly uses std::min hewillk at gmail dot com
2021-07-23 8:33 ` [Bug libstdc++/101587] ranges::uninitialized_copy/move " redi at gcc dot gnu.org
2021-07-23 9:04 ` redi at gcc dot gnu.org
2021-07-23 9:16 ` redi at gcc dot gnu.org
2021-07-23 9:56 ` hewillk at gmail dot com
2021-07-23 10:34 ` redi at gcc dot gnu.org
2021-07-23 11:50 ` hewillk at gmail dot com
2021-07-23 12:12 ` redi at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).