<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - three way comparison not able to synthesize traditional comparators when explicitly defined"
   href="https://bugs.llvm.org/show_bug.cgi?id=47007">47007</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>three way comparison not able to synthesize traditional comparators when explicitly defined
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>10.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++2a
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>gumby@henkel-wallace.org
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The following code fails to synthesize traditional comparators from the
three-way comparator.  `= default` works in this particular case.

As a side point: Per my reading of the standard: I don't believe <compare>
should be required for the three way case (not required for the == case).  I
wasn't sure if I should file this as a separate libc++ bug or if it's part of
this same issue.

#include <compare>
#include <iostream>

struct foo {
    int content;
    foo(int x) : content { x } {}

  // works: auto operator <=> (foo const& rhs) const = default;
  // works: auto operator ==  (foo const& rhs) const { return content == 
rhs.content; }
  // fails: 
            auto operator <=> (foo const& rhs) const { return content <=>
rhs.content; }
};

int main() {
  foo a { 1 };
  foo b { 2 };
  foo c { 1 };

  if (a != b) std::cout << "not ";
  std::cout  << "equal" << std::endl;


  if (!(a == c)) std::cout << "not ";
  std::cout  << "equal" << std::endl;

  return 0;
}


$ /usr/local/opt/llvm/bin/clang++ -std=c++20 foo.cc && ./a.out
foo.cc:24:9: error: invalid operands to binary expression ('foo' and 'foo')
  if (a != b) std::cout << "not ";
      ~ ^  ~
foo.cc:28:11: error: invalid operands to binary expression ('foo' and 'foo')
  if (!(a == c)) std::cout << "not ";
        ~ ^  ~</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>