Skip to content

Commit

Permalink
[Clang] Fix CXXRewrittenBinaryOperator::getDecomposedForm to handle c…
Browse files Browse the repository at this point in the history
…ase when spaceship operator returns comparison category by reference (#66270)

Currently CXXRewrittenBinaryOperator::getDecomposedForm(...) may crash
if the spaceship operator returns a comparison category by reference. This
because IgnoreImplicitAsWritten() does not look through CXXConstructExpr. The
fix is to use IgnoreUnlessSpelledInSource() which will look though
CXXConstructExpr.

This fixes: #64162
  • Loading branch information
shafik committed Sep 25, 2023
1 parent a677a17 commit bb764ec
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 1 deletion.
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; }
}

0 comments on commit bb764ec

Please sign in to comment.