https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116342

            Bug ID: 116342
           Summary: The compiler doesn't respect customised
                    strong_order/weak_order for floating point types.
           Product: gcc
           Version: 14.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: daidodo at gmail dot com
  Target Milestone: ---

The following code customises `strong_order` for `float`, but the compiler
still uses `std::strong_order`:

```
#include <compare>

// Customization for float.
// NaN is greater than any other numbers, regardless the sign bit.              
constexpr std::strong_ordering strong_order(float a, float b) noexcept {
    if(__builtin_isnan(a))
        return __builtin_isnan(b) ? std::strong_ordering::equivalent :
std::strong_ordering::greater;
    if(__builtin_isnan(b))
        return std::strong_ordering::less;
    const auto c = a <=> b;
    return c < 0 ? std::strong_ordering::less : c > 0 ?
std::strong_ordering::greater : std::strong_ordering::equivalent;
}

int main() {
    using std::strong_order;
    constexpr float NEG_NAN = -std::numeric_limits<float>::quiet_NaN();
    // Expected, but error
    static_assert(std::strong_ordering::less == strong_order(3.0f, NEG_NAN));
}
```

I checked the source and believe the problem is in
libstdc++-v3/libsupc++/compare
(https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/compare#L965).
The library makes its own customisation (_S_fp_cmp) and calls it before ADL
branch, which means user-defined code will be ignored.

The same problem can happen for `weak_order`
(https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/compare#L1011),
while `partial_order` is fine because it checks ADL at the top.

And I think the latest G++ should have the same problem as shown in the latest
source.

Regards,
Zhao

Reply via email to