-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Open
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"diverges-from:gccDoes the clang frontend diverge from gcc on this issueDoes the clang frontend diverge from gcc on this issuespaceshipissues related to <=>issues related to <=>
Description
The following failed to compile on Clang but works with GCC.
#include <memory>
struct UDT
{
};
template <class T>
struct Base {
public:
T* cbegin() const { return t_; }
T* cend() const { return t_; }
friend inline auto operator<=>(const Base& lhs,
const Base& rhs) {
return std::lexicographical_compare_three_way(
lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(),
[](auto&& lhs, auto&& rhs) {
return std::forward_as_tuple(lhs) <=> std::forward_as_tuple(rhs);
});
}
T* t_;
};
template <class T>
class Wrapper {
public:
friend inline auto operator<=>(const Wrapper& lhs,
const Wrapper& rhs) = default;
private:
Base<T> impl_;
};
int main()
{
Wrapper<UDT> c;
}
The compile and output:
$ clang++ --version && clang++ -std=c++20 -c t.cpp
clang version 16.0.6 (Red Hat 16.0.6-2.module+el8.9.0+19521+190d7aba)
Target: x86_64-redhat-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
t.cpp:17:45: error: invalid operands to binary expression ('tuple<UDT &>' and 'tuple<UDT &>')
return std::forward_as_tuple(lhs) <=> std::forward_as_tuple(rhs);
~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/stl_algobase.h:1826:17: note: in instantiation of function template specialization 'operator<=>(const Base<UDT> &, const Base<UDT> &)::(anonymous class)::operator()<UDT &, UDT &>' requested here
-> decltype(__comp(*__first1, *__first2))
^
t.cpp:14:12: note: while substituting deduced template arguments into function template 'lexicographical_compare_three_way' [with _InputIter1 = UDT *, _InputIter2 = UDT *, _Comp = (lambda at t.cpp:16:9)]
return std::lexicographical_compare_three_way(
^
t.cpp:26:22: note: in instantiation of member function 'operator<=>' requested here
friend inline auto operator<=>(const Wrapper& lhs,
^
t.cpp:36:16: note: in instantiation of template class 'Wrapper<UDT>' requested here
Wrapper<UDT> c;
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/system_error:316:3: note: candidate function not viable: no known conversion from 'tuple<UDT &>' to 'const error_code' for 1st argument
operator<=>(const error_code& __lhs, const error_code& __rhs) noexcept
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/system_error:498:3: note: candidate function not viable: no known conversion from 'tuple<UDT &>' to 'const error_condition' for 1st argument
operator<=>(const error_condition& __lhs,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/stl_pair.h:819:5: note: candidate template ignored: could not match 'pair' against 'tuple'
operator<=>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/stl_iterator.h:583:5: note: candidate template ignored: could not match 'reverse_iterator' against 'tuple'
operator<=>(const reverse_iterator<_IteratorL>& __x,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/stl_iterator.h:583:5: note: candidate template ignored: could not match 'reverse_iterator' against 'tuple'
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/stl_iterator.h:601:5: note: candidate template ignored: could not match 'reverse_iterator' against 'tuple'
operator<=>(const reverse_iterator<_Iterator>& __x,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/stl_iterator.h:1690:5: note: candidate template ignored: could not match 'move_iterator' against 'tuple'
operator<=>(const move_iterator<_IteratorL>& __x,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/stl_iterator.h:1690:5: note: candidate template ignored: could not match 'move_iterator' against 'tuple'
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/stl_iterator.h:1756:5: note: candidate template ignored: could not match 'move_iterator' against 'tuple'
operator<=>(const move_iterator<_Iterator>& __x,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/tuple:1938:5: note: candidate template ignored: substitution failure [with _Tps = <UDT &>, _Ups = <UDT &>]: no matching function for call to object of type 'const struct _Synth3way'
operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u)
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/tuple:1938:5: note: candidate template ignored: substitution failure [with _Tps = <UDT &>, _Ups = <UDT &>]: no matching function for call to object of type 'const struct _Synth3way'
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/string_view:624:5: note: candidate template ignored: could not match 'basic_string_view' against 'tuple'
operator<=>(basic_string_view<_CharT, _Traits> __x,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/string_view:632:5: note: candidate template ignored: could not match 'basic_string_view' against 'tuple'
operator<=>(basic_string_view<_CharT, _Traits> __x,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/string_view:632:5: note: candidate template ignored: could not match 'basic_string_view' against 'tuple'
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/basic_string.h:3733:5: note: candidate template ignored: could not match 'basic_string' against 'tuple'
operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/basic_string.h:3748:5: note: candidate template ignored: could not match 'basic_string' against 'tuple'
operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/basic_string.h:3748:5: note: candidate template ignored: could not match 'basic_string' against 'tuple'
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/unique_ptr.h:988:5: note: candidate template ignored: could not match 'unique_ptr' against 'tuple'
operator<=>(const unique_ptr<_Tp, _Dp>& __x,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/unique_ptr.h:988:5: note: candidate template ignored: could not match 'unique_ptr' against 'tuple'
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/unique_ptr.h:997:5: note: candidate template ignored: could not match 'unique_ptr' against 'tuple'
operator<=>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/unique_ptr.h:997:5: note: candidate template ignored: could not match 'unique_ptr' against 'tuple'
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/shared_ptr_base.h:1805:5: note: candidate template ignored: could not match '__shared_ptr' against 'tuple'
operator<=>(const __shared_ptr<_Tp, _Lp>& __a,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/shared_ptr_base.h:1805:5: note: candidate template ignored: could not match '__shared_ptr' against 'tuple'
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/shared_ptr_base.h:1811:5: note: candidate template ignored: could not match '__shared_ptr' against 'tuple'
operator<=>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/shared_ptr_base.h:1811:5: note: candidate template ignored: could not match '__shared_ptr' against 'tuple'
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/shared_ptr.h:567:5: note: candidate template ignored: could not match 'shared_ptr' against 'tuple'
operator<=>(const shared_ptr<_Tp>& __a,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/shared_ptr.h:567:5: note: candidate template ignored: could not match 'shared_ptr' against 'tuple'
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/shared_ptr.h:573:5: note: candidate template ignored: could not match 'shared_ptr' against 'tuple'
operator<=>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/shared_ptr.h:573:5: note: candidate template ignored: could not match 'shared_ptr' against 'tuple'
t.cpp:14:12: error: no matching function for call to 'lexicographical_compare_three_way'
return std::lexicographical_compare_three_way(
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.cpp:26:22: note: in instantiation of member function 'operator<=>' requested here
friend inline auto operator<=>(const Wrapper& lhs,
^
t.cpp:36:16: note: in instantiation of template class 'Wrapper<UDT>' requested here
Wrapper<UDT> c;
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/stl_algobase.h:1821:5: note: candidate template ignored: substitution failure [with _InputIter1 = UDT *, _InputIter2 = UDT *, _Comp = (lambda at t.cpp:16:9)]
lexicographical_compare_three_way(_InputIter1 __first1,
^
/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13/../../../../include/c++/13/bits/stl_algobase.h:1869:5: note: candidate function template not viable: requires 4 arguments, but 5 were provided
lexicographical_compare_three_way(_InputIter1 __first1,
^
t.cpp:26:22: error: return type of defaulted 'operator<=>' cannot be deduced because three-way comparison for member 'impl_' has a deduced return type and is not yet defined
friend inline auto operator<=>(const Wrapper& lhs,
^
t.cpp:36:16: note: in instantiation of template class 'Wrapper<UDT>' requested here
Wrapper<UDT> c;
^
t.cpp:30:11: note: member 'impl_' declared here
Base<T> impl_;
^
t.cpp:12:22: note: selected 'operator<=>' for member 'impl_' declared here
friend inline auto operator<=>(const Base& lhs,
^
3 errors generated.
Same failure occurs with Clang 19.1.7. The testcase isn't calling any functions that would call the comparison operator, and it shouldn't have failed to compile.
Interestingly, changing the default three-way to the following compiles without any errors.
friend inline auto operator<=>(const Wrapper& lhs,
const Wrapper& rhs) {
return lhs.impl_ <=> rhs.impl_;
}
Metadata
Metadata
Assignees
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"diverges-from:gccDoes the clang frontend diverge from gcc on this issueDoes the clang frontend diverge from gcc on this issuespaceshipissues related to <=>issues related to <=>