Skip to content

[Clang] Fix CXXRewrittenBinaryOperator::getDecomposedForm to handle case when spaceship operator returns comparison category by reference #66270

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 25, 2023
Merged
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ Bug Fixes to C++ Support
NTTP types are compared with the 'diff' method.
(`#66744 https://github.com/llvm/llvm-project/issues/66744`)

- Fix crash caused by a spaceship operator returning a comparision category by
reference. Fixes:
(`#64162 <https://github.com/llvm/llvm-project/issues/64162>`_)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Fixed an import failure of recursive friend class template.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ CXXRewrittenBinaryOperator::getDecomposedForm() const {
return Result;

// Otherwise, we expect a <=> to now be on the LHS.
E = Result.LHS->IgnoreImplicitAsWritten();
E = Result.LHS->IgnoreUnlessSpelledInSource();
if (auto *BO = dyn_cast<BinaryOperator>(E)) {
assert(BO->getOpcode() == BO_Cmp);
Result.LHS = BO->getLHS();
Expand Down
23 changes: 23 additions & 0 deletions clang/test/SemaCXX/compare-cxx2a.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,3 +479,26 @@ void DoSomething() {
// expected-note {{undefined function 'operator++' cannot be used in a constant expression}}
}
}

namespace GH64162 {
struct S {
const std::strong_ordering& operator<=>(const S&) const = default;
};
bool test(S s) {
return s < s; // We expect this not to crash anymore
}

// Following example never crashed but worth adding in because it is related
struct A {};
bool operator<(A, int);

struct B {
operator A();
};

struct C {
B operator<=>(C);
};

bool f(C c) { return c < c; }
}