https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102064
Bug ID: 102064 Summary: Wrong assignable check in uninitialized_fill and uninitialized_fill_n Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- In r204615 I added assignable checks to various algos to fix PR libstdc++/58982. The checks in uninitialized_fill and uninitialized_fill_n use is_copy_assignable, which is wrong because the value being filled doesn't have to be the value type of the output range. This valid code fails to compile with libstdc++: #include <memory> #include <algorithm> struct X { X() = default; X(int) { } X(const X&) = default; X& operator=(const X&) = default; X& operator=(int) = delete; }; static_assert( std::is_trivial<X>::value, "" ); int main() { unsigned char buf[sizeof(X)]; std::uninitialized_fill_n((X*)buf, 1, 99); } /usr/include/c++/11/bits/stl_algobase.h:924:18: error: use of deleted function ‘X& X::operator=(int)’ 924 | *__first = __tmp; | ~~~~~~~~~^~~~~~~ The problem is that we decide it's OK to use std::fill_n because X is trivial and is_copy_assignable<X> is true, but then std::fill_n assigns int to X. We need to check is_assignable<X&, const int&> instead.