[llvm-bugs] [Bug 49850] New: no viable overloaded '=' when assigning a map with non-move/copy-assignable key

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Apr 5 18:24:32 PDT 2021


https://bugs.llvm.org/show_bug.cgi?id=49850

            Bug ID: 49850
           Summary: no viable overloaded '=' when assigning a map with
                    non-move/copy-assignable key
           Product: libc++
           Version: unspecified
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: All Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: yichen.yan at inf.ethz.ch
                CC: llvm-bugs at lists.llvm.org, mclow.lists at gmail.com

Error message and source:


root at cc6f61d60963:/test# /llvm-install/bin/clang++ -stdlib=libc++ test.cc -c -o
/dev/null
In file included from test.cc:35:
/llvm-install/bin/../include/c++/v1/map:710:17: error: no viable overloaded '='
        __ref() = __v.__get_value();
        ~~~~~~~ ^ ~~~~~~~~~~~~~~~~~
/llvm-install/bin/../include/c++/v1/__tree:1660:39: note: in instantiation of
member function 'std::__value_type<const int, int>::operator=' requested here
            __cache.__get()->__value_ = *__first;
                                      ^
/llvm-install/bin/../include/c++/v1/__tree:1617:9: note: in instantiation of
function template specialization 'std::__tree<std::__value_type<const int,
int>, std::__map_value_compare<const int, std::__value_type<const int, int>,
std::less<const int>, true>, std::allocator<std::__value_type<const int,
int>>>::__assign_multi<std::__tree_const_iterator<std::__value_type<const int,
int>, std::__tree_node<std::__value_type<const int, int>, void *> *, long>>'
requested here
        __assign_multi(__t.begin(), __t.end());
        ^
/llvm-install/bin/../include/c++/v1/map:1016:21: note: in instantiation of
member function 'std::__tree<std::__value_type<const int, int>,
std::__map_value_compare<const int, std::__value_type<const int, int>,
std::less<const int>, true>, std::allocator<std::__value_type<const int,
int>>>::operator=' requested here
            __tree_ = __m.__tree_;
                    ^
test.cc:38:10: note: in instantiation of member function 'std::map<const int,
int>::operator=' requested here
  map[0] = m0;
         ^
/llvm-install/bin/../include/c++/v1/utility:516:11: note: candidate function
not viable: no known conversion from 'const std::__value_type<const int,
int>::value_type' (aka 'const pair<const int, int>') to 'const typename
conditional<is_copy_assignable<first_type>::value &&
is_copy_assignable<second_type>::value, pair<const int &, int &>, __nat>::type'
(aka 'const std::__nat') for 1st argument
    pair& operator=(typename conditional<
          ^
/llvm-install/bin/../include/c++/v1/utility:529:11: note: candidate function
not viable: no known conversion from 'const std::__value_type<const int,
int>::value_type' (aka 'const pair<const int, int>') to 'typename
conditional<is_move_assignable<first_type>::value &&
is_move_assignable<second_type>::value, pair<const int &, int &>, __nat>::type'
(aka 'std::__nat') for 1st argument
    pair& operator=(typename conditional<
          ^
/llvm-install/bin/../include/c++/v1/utility:338:62: note: candidate template
ignored: disabled by 'enable_if' [with _Tuple = const std::pair<const int, int>
&]
    using _EnableB _LIBCPP_NODEBUG_TYPE = typename enable_if<_Val, bool>::type;
                                                             ^
/llvm-install/bin/../include/c++/v1/utility:301:29: note: candidate function
(the implicit copy assignment operator) not viable: no known conversion from
'const pair<const std::__value_type<const int, int>::key_type,
std::__value_type<const int, int>::mapped_type>' to 'const pair<const int &,
int &>' for 1st argument
struct _LIBCPP_TEMPLATE_VIS pair
                            ^
1 error generated.
root at cc6f61d60963:/test# cat test.cc
#include <map>
void foo(std::map< int, std::map<const int, int>>& map) {
  std::map<const int, int> m0;
  map[0] = m0;
// or equivalently,
//   _map.try_emplace(0).first->second = m0;
}

void foo2() {
  std::map<const int, int> m;
  std::pair<int, std::map<const int, int>> p0{0, m};
  std::pair<int, std::map<const int, int>> p1(p0);
  std::pair<int, std::map<const int, int>> p2(std::move(p0));
}
root at cc6f61d60963:/test# /llvm-install/bin/clang++ --version
clang version 13.0.0 (https://github.com/llvm/llvm-project.git
4020932706f6f8538b48b9b8439a7ec1266a7ae5)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /llvm-install/bin


I checked the standard but did not find specification about assigning to
`pair->second`, is this an UB?
In `foo2` the move/copy constructors seem both fine so I don't get it why it
failed to assign the value of a map.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210406/9a503343/attachment.html>


More information about the llvm-bugs mailing list