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

Conversation

shafik
Copy link
Collaborator

@shafik shafik commented Sep 13, 2023

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

@shafik shafik requested a review from a team as a code owner September 13, 2023 18:23
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Sep 13, 2023
@llvmbot
Copy link
Member

llvmbot commented Sep 13, 2023

@llvm/pr-subscribers-clang

Changes 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

--
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)
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; }
+}

…ase 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
@shafik shafik force-pushed the fix_unexpected_rewritten_operator_form branch from ed43ed6 to b934841 Compare September 13, 2023 23:41
@shafik shafik requested a review from zygoloid September 14, 2023 00:30
Copy link
Contributor

@Fznamznon Fznamznon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it needs a release note?

@Fznamznon Fznamznon requested a review from a team September 14, 2023 07:58
…ase 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
@shafik
Copy link
Collaborator Author

shafik commented Sep 14, 2023

Perhaps it needs a release note?

You would think I would remember this by now.

Copy link
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - I was trying to find some hope in the standard that this was ill-formed. Alas.

@tbaederr
Copy link
Contributor

Ping @shafik, just needs a rebase :)

…ase 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clang ICE: unexpected rewritten operator form
5 participants