Description
The following translation unit
#include <compare>
struct s {
[[gnu::const]] friend auto operator<=>(s const lhs, s const rhs) {
return std::strong_ordering::equal;
}
};
void f(s const x) {
__builtin_assume(x <=> x == 0);
}
causes clang to warn
<source>:10:19: warning: the argument to '__builtin_assume' has side effects that will be discarded [-Wassume]
__builtin_assume(x <=> x == 0);
^~~~~~~~~~~~
1 warning generated.
Compiler returned: 0
See it live: https://godbolt.org/z/docxWvcM6
This in turn causes __builtin_assume(x <= x);
to also fail to be assumed.
I suspect this is because the comparison categories do not have their functions marked [[gnu::const]]
. However, one of the functions that would need to be so marked is the helper type that's constructible from a literal 0, and it's unclear whether you are allowed to mark constructors gnu::const
or gnu::pure
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51971). Furthermore, libc++ annotating its code won't help if the user is using libstdc++ or MSVC's standard library.
You can also get the same behavior with no user types defined at all:
#include <compare>
void f() {
__builtin_assume(0 <=> 0 == 0);
}
Warns about
<source>:4:19: warning: the argument to '__builtin_assume' has side effects that will be discarded [-Wassume]
__builtin_assume(0 <=> 0 == 0);
^~~~~~~~~~~~
1 warning generated.
Compiler returned: 0
See it live: https://godbolt.org/z/EseTasTY3