llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangd

Author: Younan Zhang (zyn0217)

<details>
<summary>Changes</summary>

This reverts the behavior since d4cf20ca37160cb062a9db773d0e6255d6bbc31a

We still need to track the instantiated-from decl for rewritten operators, in 
order to suppress spurious warnings that suggest the spaceship was not used.

Also this fixes regressions introduced from that commit.

Fixes https://github.com/llvm/llvm-project/issues/125233
Fixes https://github.com/llvm/llvm-project/issues/104720

---
Full diff: https://github.com/llvm/llvm-project/pull/230062.diff


7 Files Affected:

- (modified) clang-tools-extra/clangd/unittests/FindTargetTests.cpp (+4-1) 
- (modified) clang-tools-extra/clangd/unittests/HoverTests.cpp (+2-2) 
- (modified) clang/docs/ReleaseNotes.md (+4) 
- (modified) clang/lib/Sema/SemaConcept.cpp (+4-1) 
- (modified) clang/lib/Sema/SemaOverload.cpp (+4) 
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+11-13) 
- (modified) clang/test/CXX/class/class.compare/class.compare.default/p4.cpp 
(+52-5) 


``````````diff
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp 
b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 87febfef753a1..b6aa62ce0d422 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -748,7 +748,10 @@ TEST_F(TargetDeclTest, RewrittenBinaryOperator) {
     bool x = (Foo(1) [[!=]] Foo(2));
   )cpp";
   EXPECT_DECLS("CXXRewrittenBinaryOperator",
-               {"bool operator==(const Foo &) const noexcept = default"});
+               {"std::strong_ordering operator<=>(const Foo &) const = 
default",
+                Rel::TemplatePattern},
+               {"bool operator==(const Foo &) const noexcept = default",
+                Rel::TemplateInstantiation});
 }
 
 TEST_F(TargetDeclTest, FunctionTemplate) {
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp 
b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index d355118f30761..28ff463008fc3 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -3322,7 +3322,7 @@ TEST(Hover, All) {
             HI.NamespaceScope = "";
             HI.Definition =
                 "bool operator==(const Foo &) const noexcept = default";
-            HI.Documentation = "";
+            HI.Documentation = "Foo spaceship";
           }},
   };
 
@@ -4743,7 +4743,7 @@ TEST(Hover, SpaceshipTemplateNoCrash) {
   TU.ExtraArgs.push_back("-std=c++20");
   auto AST = TU.build();
   auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
-  EXPECT_EQ(HI->Documentation, "");
+  EXPECT_EQ(HI->Documentation, "Foo bar baz");
 }
 
 TEST(Hover, ForwardStructNoCrash) {
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 756722bcd2d1b..f1ce646249902 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -620,6 +620,10 @@ features cannot lower the translation-unit ABI level;
   parsed where a nested-name-specifier could appear (e.g. ``int decltype = 
0;``).
   Clang now diagnoses the error instead of asserting. (#GH211207)
 
+- Fixed a bogus unused function warning when using `operator<=>` within an 
anonymous namespace. (#GH125233)
+
+- Fixed a regression where the rewritten comparison operator was not 
instantiated properly. (#GH104720)
+
 - Fixed an assertion failure when a parenthesized structured binding declarator
   was followed by a function declarator and body (e.g. ``([a, b])() {}``).
   (#GH218144, #GH193687)
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index fb66bdd6d2bd0..ad49a2ec94a04 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -2586,7 +2586,10 @@ bool Sema::IsAtLeastAsConstrained(const NamedDecl *D1,
     auto IsExpectedEntity = [](const FunctionDecl *FD) {
       FunctionDecl::TemplatedKind Kind = FD->getTemplatedKind();
       return Kind == FunctionDecl::TK_NonTemplate ||
-             Kind == FunctionDecl::TK_FunctionTemplate;
+             Kind == FunctionDecl::TK_FunctionTemplate ||
+             (Kind == FunctionDecl::TK_MemberSpecialization &&
+              FD->getInstantiatedFromMemberFunction()
+                      ->getOverloadedOperator() == OO_Spaceship);
     };
     const auto *FD2 = dyn_cast<FunctionDecl>(D2);
     assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 963f0e93bd651..74bd66a94aec9 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -15806,6 +15806,10 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation 
OpLoc,
         if (FnExpr.isInvalid())
           return ExprError();
 
+        if (auto *Pattern = FnDecl->getInstantiatedFromMemberFunction();
+            Pattern && Pattern->getOverloadedOperator() == OO_Spaceship)
+          Pattern->setIsUsed();
+
         // Determine the result type.
         QualType ResultTy = FnDecl->getReturnType();
         ExprValueKind VK = Expr::getValueKindForType(ResultTy);
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 7668b75e836e4..0d027113f8d50 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3156,18 +3156,16 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
         FunctionTemplate,
         TemplateArgumentList::CreateCopy(SemaRef.Context, Innermost),
         /*InsertToken=*/{});
-  } else if (FunctionRewriteKind == RewriteKind::None) {
-    if (isFriend && D->isThisDeclarationADefinition()) {
-      // Do not connect the friend to the template unless it's actually a
-      // definition. We don't want non-template functions to be marked as being
-      // template instantiations.
-      Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
-    } else if (!isFriend) {
-      // If this is not a function template, and this is not a friend (that is,
-      // this is a locally declared function), save the instantiation
-      // relationship for the purposes of constraint instantiation.
-      Function->setInstantiatedFromDecl(D);
-    }
+  } else if (isFriend && D->isThisDeclarationADefinition()) {
+    // Do not connect the friend to the template unless it's actually a
+    // definition. We don't want non-template functions to be marked as being
+    // template instantiations.
+    Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
+  } else if (!isFriend) {
+    // If this is not a function template, and this is not a friend (that is,
+    // this is a locally declared function), save the instantiation
+    // relationship for the purposes of constraint instantiation.
+    Function->setInstantiatedFromDecl(D);
   }
 
   if (isFriend) {
@@ -3566,7 +3564,7 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
         FunctionTemplate,
         TemplateArgumentList::CreateCopy(SemaRef.Context, Innermost),
         /*InsertToken=*/{});
-  } else if (!isFriend && FunctionRewriteKind == RewriteKind::None) {
+  } else if (!isFriend) {
     // Record that this is an instantiation of a member function.
     Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
   }
diff --git a/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp 
b/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp
index 53a8bfc9a4f4a..ac16aa64111fc 100644
--- a/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp
+++ b/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx2a %s
-// RUN: %clang_cc1 -std=c++23 -verify=expected %s
+// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx2a -Wunused-function %s
+// RUN: %clang_cc1 -std=c++23 -verify=expected -Wunused-function %s
 
 // This test is for [class.compare.default]p3 as modified and renumbered to p4
 // by P2002R0.
@@ -18,7 +18,7 @@ namespace std {
 
 namespace N {
   struct A {
-    friend constexpr std::strong_ordering operator<=>(const A&, const A&) = 
default; // expected-note 2{{declared here}}
+    friend constexpr std::strong_ordering operator<=>(const A&, const A&) = 
default; // expected-note {{declared here}}
   };
 
   constexpr std::strong_ordering (*test_a_threeway_not_found)(const A&, const 
A&) = &operator<=>; // expected-error {{undeclared}}
@@ -32,8 +32,7 @@ namespace N {
 
   constexpr bool operator==(const A&, const A&) noexcept;
   constexpr bool (*test_a_equal)(const A&, const A&) noexcept = &operator==;
-  static_assert((*test_a_equal)(A(), A())); // expected-error {{static 
assertion expression is not an integral constant expression}}
-                                            // expected-note@-1 {{undefined 
function 'operator==' cannot be used in a constant expression}}
+  static_assert((*test_a_equal)(A(), A()));
 }
 
 struct B1 {
@@ -180,3 +179,51 @@ namespace Constrained {
     return a != A<int>();
   }
 }
+
+namespace GH104720 {
+
+struct A {
+  friend constexpr auto operator<=>(const A &, const A &) = default;
+};
+
+constexpr bool operator ==(const A &, const A &) noexcept;
+
+static_assert( ((bool(*)(const A &, const A &))&operator==)( A{}, A{} ) );
+
+}
+
+namespace GH104720_2 {
+
+struct A {
+  friend constexpr bool operator==(const A &, const A &) = default; // 
#GH104720_2_A
+};
+
+// FIXME: This should probably be accepted - we only look at the recent 
declaration when defining a default function.
+//
+// bool foo() {
+//   return A() == A();
+// }
+//
+// ^^^ activating this function would make the assertion valid!
+
+constexpr bool operator ==(const A &, const A &) noexcept;
+static_assert( ((bool(*)(const A &, const A &))&operator==)( A{}, A{} ) );
+// expected-error@-1 {{not an integral}}
+// expected-note@-2 {{undefined function}} expected-note@#GH104720_2_A {{here}}
+
+}
+
+namespace GH125233 {
+
+namespace {
+
+struct S {
+    friend auto operator<=>(const S&, const S&) = default;
+};
+
+[[maybe_unused]] bool awoo(S a, S b) { return a == b; }
+
+}
+
+}
+

``````````

</details>


https://github.com/llvm/llvm-project/pull/230062
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to