Skip to content

Commit b934841

Browse files
committed
[Clang] Fix CXXRewrittenBinaryOperator::getDecomposedForm to handle case when spaceship operator returns comparison category by reference
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: llvm#64162
1 parent 705f24c commit b934841

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

clang/lib/AST/ExprCXX.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ CXXRewrittenBinaryOperator::getDecomposedForm() const {
111111
return Result;
112112

113113
// Otherwise, we expect a <=> to now be on the LHS.
114-
E = Result.LHS->IgnoreImplicitAsWritten();
114+
E = Result.LHS->IgnoreUnlessSpelledInSource();
115115
if (auto *BO = dyn_cast<BinaryOperator>(E)) {
116116
assert(BO->getOpcode() == BO_Cmp);
117117
Result.LHS = BO->getLHS();

clang/test/SemaCXX/compare-cxx2a.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,3 +479,26 @@ void DoSomething() {
479479
// expected-note {{undefined function 'operator++' cannot be used in a constant expression}}
480480
}
481481
}
482+
483+
namespace GH64162 {
484+
struct S {
485+
const std::strong_ordering& operator<=>(const S&) const = default;
486+
};
487+
bool test(S s) {
488+
return s < s; // We expect this not to crash anymore
489+
}
490+
491+
// Following example never crashed but worth adding in because it is related
492+
struct A {};
493+
bool operator<(A, int);
494+
495+
struct B {
496+
operator A();
497+
};
498+
499+
struct C {
500+
B operator<=>(C);
501+
};
502+
503+
bool f(C c) { return c < c; }
504+
}

0 commit comments

Comments
 (0)