diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 294b77a3e2609..688454d6b562e 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -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 `_) + Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed an import failure of recursive friend class template. diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index efb64842fb6d9..06163255f9b5e 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -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(E)) { assert(BO->getOpcode() == BO_Cmp); Result.LHS = BO->getLHS(); diff --git a/clang/test/SemaCXX/compare-cxx2a.cpp b/clang/test/SemaCXX/compare-cxx2a.cpp index 619e16aa74581..15a0baccfca17 100644 --- a/clang/test/SemaCXX/compare-cxx2a.cpp +++ b/clang/test/SemaCXX/compare-cxx2a.cpp @@ -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; } +}