[clang] [Clang] Fix CXXRewrittenBinaryOperator::getDecomposedForm to handle case when spaceship operator returns comparison category by reference (PR #66270)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 13 11:24:25 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
<details>
<summary>Changes</summary>
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: https://github.com/llvm/llvm-project/issues/64162
--
Full diff: https://github.com/llvm/llvm-project/pull/66270.diff
2 Files Affected:
- (modified) clang/lib/AST/ExprCXX.cpp (+1-1)
- (modified) clang/test/SemaCXX/compare-cxx2a.cpp (+23)
<pre>
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index efb64842fb6d96d..06163255f9b5e54 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<BinaryOperator>(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 619e16aa7458179..15a0baccfca17a2 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; }
+}
</pre>
</details>
https://github.com/llvm/llvm-project/pull/66270
More information about the cfe-commits
mailing list