g++-10 internal compiler error In member function ‘constexpr std::strong_ordering S9::operator<=>(const S9&) const’

Bug #1998359 reported by Damien Ruscoe
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
gcc-10 (Ubuntu)
Fix Released
Undecided
Unassigned

Bug Description

Command Line:

g++-10 -std=c++20 -c strong_vs_weak_ordering.cpp

stderr:

strong_vs_weak_ordering.cpp: In member function ‘constexpr std::strong_ordering S9::operator<=>(const S9&) const’:
strong_vs_weak_ordering.cpp:69:26: internal compiler error: in finish_expr_stmt, at cp/semantics.c:681
   69 | std::strong_ordering operator<=>(const S9&) const = default;
      | ^~~~~~~~
0x7fdb22256082 __libc_start_main
 ../csu/libc-start.c:308
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <file:///usr/share/doc/gcc-10/README.Bugs> for instructions.

code:

#include<compare>

// not in our immediate control
struct Legacy
{
    bool operator==(Legacy const&) const;
    bool operator<(Legacy const&) const;
};

struct S6
{
    int x;
    Legacy l;
    // deleted because Legacy doesn't have operator<=>(), comparison category
    // can't be deduced
    auto operator<=>(const S6&) const = default;
};

struct S7
{
    int x;
    Legacy l;

    std::strong_ordering operator<=>(const S7& rhs) const = default;
    /*
    Since comparison category is provided explicitly, ordering can be
    synthesized using operator<() and operator==(). They must return exactly
    `bool` for this to work. It will work for weak and partial ordering as well.

    Here's an example of synthesized operator<=>():
    std::strong_ordering operator<=>(const S7& rhs) const
    {
        // use operator<=>() for int
        if(auto cmp = x <=> rhs.x; cmp != 0) return cmp;

        // synthesize ordering for Legacy using operator<() and operator==()
        if(l == rhs.l) return std::strong_ordering::equal;
        if(l < rhs.l) return std::strong_ordering::less;
        return std::strong_ordering::greater;
    }
    */
};

struct NoEqual
{
    bool operator<(const NoEqual&) const = default;
};

struct S8
{
    NoEqual n;
    // deleted, NoEqual doesn't have operator<=>()
    // auto operator<=>(const S8&) const = default;

    // deleted as well because NoEqual doesn't have operator==()
    std::strong_ordering operator<=>(const S8&) const = default;
};

struct W
{
    std::weak_ordering operator<=>(const W&) const = default;
};

struct S9
{
    W w;
    // ask for strong_ordering but W can provide only weak_ordering, this will
    // yield an error during instantiation
    std::strong_ordering operator<=>(const S9&) const = default;
    void f()
    {
        (S9{} <=> S9{}); // error
    }
};

Revision history for this message
Matthias Klose (doko) wrote :

this is fixed in GCC 11 and up:

tst.cc: In member function ‘void S9::f()’:
tst.cc:72:22: error: use of deleted function ‘constexpr std::strong_ordering S9::operator<=>(const S9&) const’
   72 | (S9{} <=> S9{}); // error
      | ^
tst.cc:69:26: note: ‘constexpr std::strong_ordering S9::operator<=>(const S9&) const’ is implicitly deleted because the default definition would be ill-formed:
   69 | std::strong_ordering operator<=>(const S9&) const = default;
      | ^~~~~~~~
tst.cc:66:7: error: three-way comparison of ‘S9::w’ has type ‘std::weak_ordering’, which does not convert to ‘std::strong_ordering’
   66 | W w;
      | ^

Changed in gcc-10 (Ubuntu):
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.