Created attachment 1852624 [details] Code that triggers the error Description of problem: The libsemigroups package failed the mass rebuild (https://koji.fedoraproject.org/koji/taskinfo?taskID=81537706). I will attach a small reproducer. If an unordered_map is declared with a const key type, the compiler complains that mapped_type is undefined. If the key type is non-const, compilation is successful. This isn't necessarily a bug, but I don't understand why having a const key type is wrong. Will you please explain it to me, so I can explain it to libsemigroups upstream? The attached code compiles successfully with gcc 11, by the way. Version-Release number of selected component (if applicable): gcc-12.0.0-0.5.fc36.x86_64 How reproducible: Always Steps to Reproduce: 1. g++ -c unordered_map_const_key.cpp (the attachment) Actual results: In file included from /usr/include/c++/12/unordered_map:47, from unordered_map_const_key.cpp:3: /usr/include/c++/12/bits/unordered_map.h: In instantiation of 'class std::unordered_map<const BitSet, long unsigned int, Action<BitSet, ActionTraits<BitSet> >::InternalHash, Action<BitSet, ActionTraits<BitSet> >::InternalEqualTo, std::allocator<std::pair<const BitSet, long unsigned int> > >': unordered_map_const_key.cpp:33:39: required from 'class Action<BitSet, ActionTraits<BitSet> >' unordered_map_const_key.cpp:44:38: required from here /usr/include/c++/12/bits/unordered_map.h:113:49: error: no type named 'mapped_type' in 'class std::_Hashtable<const BitSet, std::pair<const BitSet, long unsigned int>, std::allocator<std::pair<const BitSet, long unsigned int> >, std::__detail::_Select1st, Action<BitSet, ActionTraits<BitSet> >::InternalEqualTo, Action<BitSet, ActionTraits<BitSet> >::InternalHash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >' 113 | typedef typename _Hashtable::mapped_type mapped_type; | ^~~~~~~~~~~ Expected results: Successful compilation, unless the code is actually wrong, of course. Additional info:
This is caused by https://gcc.gnu.org/g:d87105d697ced10e1f7af3f1f80ef6c9890c8585 and should be fixed. I didn't consider anybody would use unordered_map<const T, U> because that's just dumb and pointless. It's not wrong, but it hurts performance for zero benefit. For example, these APIa that are supposed to be able to move the key: mapped_type& operator[](key_type&& __k) { return _M_h[std::move(__k)]; } template <typename... _Args> pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) { return _M_h.try_emplace(cend(), std::move(__k), std::forward<_Args>(__args)...); } If the key_type is const, it can't be moved. There is zero benefit to using a const key_type, because it's already stored as const inside the pair anyway, so the only thing it does is prevent move semantics.
It turns out that the cvc4 package does this, too. I will submit PRs to both upstreams to remove the const. Thank you for the explanation!
One more note on this: with both libsemigroups and cvc4, removing the const on the key type leads to compiler errors on every call to map.find(). The upstreams are making those calls from contexts where the available references are const, and both upstreams are still on C++11. This means that I have to approach both upstreams and say, "Hey, I've got this great patch that removes the const from your unordered_map key types, but you either have to convert your entire code base to C++20, or add a const_cast to the argument of every map.find() call!" I suspect that isn't going to go over well.
What do those find calls look like? I don't see why you'd get errors for them.
Or why converting anything to C++20 would help.
Please retry against gcc-12.0.1-0.3.fc36 and annobin-10.51-2.fc36 now in rawhide.
(In reply to Jonathan Wakely from comment #4) > What do those find calls look like? I don't see why you'd get errors for > them. If I only remove the const from the key type and make no other changes, I get errors like this (this one from libsemigroups): libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./config -DNDEBUG -I/builddir/build/BUILD/libsemigroups-1.3.7/include -I/builddir/build/BUILD/libsemigroups-1.3.7/extern -std=gnu++11 -O3 -Wall -Wextra -I/usr/include/eigen3 -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fwrapv -c src/knuth-bendix.cpp -fPIC -DPIC -o src/.libs/libsemigroups_la-knuth-bendix.o In file included from /builddir/build/BUILD/libsemigroups-1.3.7/include/libsemigroups/froidure-pin.hpp:935, from src/knuth-bendix.cpp:26: /builddir/build/BUILD/libsemigroups-1.3.7/include/libsemigroups/froidure-pin-impl.hpp: In instantiation of 'libsemigroups::element_index_type libsemigroups::FroidurePin<TElementType, TTraits>::position(const_reference) [with TElementType = libsemigroups::detail::KBE; TTraits = libsemigroups::FroidurePinTraits<libsemigroups::detail::KBE, libsemigroups::fpsemigroup::KnuthBendix>; libsemigroups::element_index_type = long unsigned int; const_reference = const libsemigroups::detail::KBE&]': src/knuth-bendix.cpp:461:31: required from here /builddir/build/BUILD/libsemigroups-1.3.7/include/libsemigroups/froidure-pin-impl.hpp:322:50: error: invalid conversion from 'libsemigroups::detail::BruidhinnTraits<libsemigroups::detail::KBE, void>::internal_const_value_type' {aka 'const libsemigroups::detail::KBE*'} to 'std::unordered_map<libsemigroups::detail::KBE*, long unsigned int, libsemigroups::FroidurePin<libsemigroups::detail::KBE, libsemigroups::FroidurePinTraits<libsemigroups::detail::KBE, libsemigroups::fpsemigroup::KnuthBendix> >::InternalHash, libsemigroups::FroidurePin<libsemigroups::detail::KBE, libsemigroups::FroidurePinTraits<libsemigroups::detail::KBE, libsemigroups::fpsemigroup::KnuthBendix> >::InternalEqualTo, std::allocator<std::pair<libsemigroups::detail::KBE* const, long unsigned int> > >::key_type' {aka 'libsemigroups::detail::KBE*'} [-fpermissive] 322 | auto it = _map.find(this->to_internal_const(x)); | ~~~~~~~~~~~~~~~~~~~~~~~^~~ | | | libsemigroups::detail::BruidhinnTraits<libsemigroups::detail::KBE, void>::internal_const_value_type {aka const libsemigroups::detail::KBE*} (In reply to Jonathan Wakely from comment #5) > Or why converting anything to C++20 would help. You're right. It wouldn't. I was looking at the new templated versions of find() in C++20 and misinterpreted what I saw. (In reply to Jakub Jelinek from comment #6) > Please retry against gcc-12.0.1-0.3.fc36 and annobin-10.51-2.fc36 now in > rawhide. I get the same error showed above if I just remove const from the key type. If I keep my grubby fingers off of the code, then it builds successfully. Thank you for the fix!
(In reply to Jerry James from comment #7) > (In reply to Jonathan Wakely from comment #4) > > What do those find calls look like? I don't see why you'd get errors for > > them. > > If I only remove the const from the key type and make no other changes, I > get errors like this (this one from libsemigroups): > > libtool: compile: g++ -DHAVE_CONFIG_H -I. -I./config -DNDEBUG > -I/builddir/build/BUILD/libsemigroups-1.3.7/include > -I/builddir/build/BUILD/libsemigroups-1.3.7/extern -std=gnu++11 -O3 -Wall > -Wextra -I/usr/include/eigen3 -O2 -flto=auto -ffat-lto-objects -fexceptions > -g -grecord-gcc-switches -pipe -Wall -Werror=format-security > -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS > -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong > -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic > -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection > -fwrapv -c src/knuth-bendix.cpp -fPIC -DPIC -o > src/.libs/libsemigroups_la-knuth-bendix.o > In file included from > /builddir/build/BUILD/libsemigroups-1.3.7/include/libsemigroups/froidure-pin. > hpp:935, > from src/knuth-bendix.cpp:26: > /builddir/build/BUILD/libsemigroups-1.3.7/include/libsemigroups/froidure-pin- > impl.hpp: In instantiation of 'libsemigroups::element_index_type > libsemigroups::FroidurePin<TElementType, TTraits>::position(const_reference) > [with TElementType = libsemigroups::detail::KBE; TTraits = > libsemigroups::FroidurePinTraits<libsemigroups::detail::KBE, > libsemigroups::fpsemigroup::KnuthBendix>; libsemigroups::element_index_type > = long unsigned int; const_reference = const libsemigroups::detail::KBE&]': > src/knuth-bendix.cpp:461:31: required from here > /builddir/build/BUILD/libsemigroups-1.3.7/include/libsemigroups/froidure-pin- > impl.hpp:322:50: error: invalid conversion from > 'libsemigroups::detail::BruidhinnTraits<libsemigroups::detail::KBE, > void>::internal_const_value_type' {aka 'const libsemigroups::detail::KBE*'} > to 'std::unordered_map<libsemigroups::detail::KBE*, long unsigned int, > libsemigroups::FroidurePin<libsemigroups::detail::KBE, > libsemigroups::FroidurePinTraits<libsemigroups::detail::KBE, > libsemigroups::fpsemigroup::KnuthBendix> >::InternalHash, > libsemigroups::FroidurePin<libsemigroups::detail::KBE, > libsemigroups::FroidurePinTraits<libsemigroups::detail::KBE, > libsemigroups::fpsemigroup::KnuthBendix> >::InternalEqualTo, > std::allocator<std::pair<libsemigroups::detail::KBE* const, long unsigned > int> > >::key_type' {aka 'libsemigroups::detail::KBE*'} [-fpermissive] > 322 | auto it = _map.find(this->to_internal_const(x)); > | ~~~~~~~~~~~~~~~~~~~~~~~^~~ > | | > | > libsemigroups::detail::BruidhinnTraits<libsemigroups::detail::KBE, > void>::internal_const_value_type {aka const libsemigroups::detail::KBE*} This looks like something is doing: using Map = unordered_map<const A, B>; Map m; Map::key_type& k = m.begin().first; i.e. expecting the type of the key to be key_type, which is wrong. It's const key_type. Which is why using unordered_map<const A, B> is dumb in the first place: the objects in the map are const anyway.
Ah, no, it's trying to use const T* as the key to lookup in an unordered_map<T*, U>. Are you sure you've changed unordered_map<const T, U> to unordered_map<T, U>, rather than changing unordered_map<const T*, U> to unordered_map<T*, U>?
*** Bug 2045799 has been marked as a duplicate of this bug. ***
This bug appears to have been reported against 'rawhide' during the Fedora 36 development cycle. Changing version to 36.
My proposal as blocker due to gcc is a critical component. We'd should not promise something as new feature aka Change that we can't deliver.
(In reply to Raphael Groner from comment #12) > My proposal as blocker due to gcc is a critical component. We'd should not > promise something as new feature aka Change that we can't deliver. I'm not sure what you mean, but the GCC bug was fixed in January.
why this bug has still status new?
Because nobody confirmed that all the problems are fixed with it. Anyway, will close now, please reopen if you have other issues.