[clang] [clang-tools-extra] [Clang][Sema] Don't set instantiated from function when rewriting operator<=> (PR #91339)
Krystian Stasiowski via cfe-commits
cfe-commits at lists.llvm.org
Tue May 7 10:36:06 PDT 2024
https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/91339
>From b199345e93410ad4e7f7f4b37f09c7e66572d43a Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 7 May 2024 10:07:26 -0400
Subject: [PATCH 1/6] [Clang][Sema] Don't set instantiated from function when
rewriting operator<=>
---
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 24 ++++++++++---------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index d544cfac55ba..37d5d3face08 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2269,16 +2269,18 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
TemplateArgumentList::CreateCopy(SemaRef.Context,
Innermost),
/*InsertPos=*/nullptr);
- } 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);
+ } 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);
+ }
}
if (isFriend) {
@@ -2669,7 +2671,7 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
TemplateArgumentList::CreateCopy(SemaRef.Context,
Innermost),
/*InsertPos=*/nullptr);
- } else if (!isFriend) {
+ } else if (!isFriend && FunctionRewriteKind == RewriteKind::None) {
// Record that this is an instantiation of a member function.
Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
}
>From 53eef8ed177edef5c4c861472d0a5a7e4bedb072 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 7 May 2024 10:20:14 -0400
Subject: [PATCH 2/6] [FOLD] add test and release note
---
clang/docs/ReleaseNotes.rst | 3 +++
.../class/class.compare/class.compare.default/p4.cpp | 11 +++++++++++
2 files changed, 14 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a85095e424b6..87c4489114c8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -683,6 +683,9 @@ Bug Fixes to C++ Support
- Fix an assertion failure when parsing an invalid members of an anonymous class. (#GH85447)
- Fixed a misuse of ``UnresolvedLookupExpr`` for ill-formed templated expressions. Fixes (#GH48673), (#GH63243)
and (#GH88832).
+- Fix a crash when an implicitly declared ``operator==`` function with a trailing requires-clause has its
+ constraints compared to that of another declaration.
+
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
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 534c3b34d883..a9b2fd2b2230 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
@@ -161,3 +161,14 @@ struct non_constexpr_type {
my_struct<non_constexpr_type> obj; // cxx2a-note {{in instantiation of template class 'GH61238::my_struct<GH61238::non_constexpr_type>' requested here}}
}
+
+namespace Constrained {
+ template<typename T>
+ struct A {
+ std::strong_ordering operator<=>(const A&) const requires true = default;
+ };
+
+ bool f(A<int> a) {
+ return a != A<int>();
+ }
+}
>From 35140102cade777fffe0abc63c7170039e6b18f4 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 7 May 2024 10:20:34 -0400
Subject: [PATCH 3/6] [FOLD] format
---
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 37d5d3face08..fde2d920c785 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2277,8 +2277,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
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.
+ // this is a locally declared function), save the instantiation
+ // relationship for the purposes of constraint instantiation.
Function->setInstantiatedFromDecl(D);
}
}
>From f30702bbf5a33c28c0544c46b87c46dd7165f87b Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 7 May 2024 11:00:56 -0400
Subject: [PATCH 4/6] [FOLD] update test
---
.../class.compare/class.compare.default/p4.cpp | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
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 a9b2fd2b2230..c89718dd71bb 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
@@ -18,14 +18,22 @@ namespace std {
namespace N {
struct A {
- friend constexpr std::strong_ordering operator<=>(const A&, const A&) = default;
+ friend constexpr std::strong_ordering operator<=>(const A&, const A&) = default; // expected-note 2{{declared here}}
};
- constexpr bool (*test_a_not_found)(const A&, const A&) = &operator==; // expected-error {{undeclared}}
+ constexpr std::strong_ordering (*test_a_threeway_not_found)(const A&, const A&) = &operator<=>; // expected-error {{undeclared}}
+
+ constexpr std::strong_ordering operator<=>(const A&, const A&) noexcept;
+ constexpr std::strong_ordering (*test_a_threeway)(const A&, const A&) = &operator<=>;
+ static_assert((*test_a_threeway)(A(), A())); // expected-error {{static assertion expression is not an integral constant expression}}
+ // expected-note at -1 {{undefined function 'operator<=>' cannot be used in a constant expression}}
+
+ constexpr bool (*test_a_equal_not_found)(const A&, const A&) = &operator==; // expected-error {{undeclared}}
constexpr bool operator==(const A&, const A&) noexcept;
- constexpr bool (*test_a)(const A&, const A&) noexcept = &operator==;
- static_assert((*test_a)(A(), A()));
+ 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 at -1 {{undefined function 'operator==' cannot be used in a constant expression}}
}
struct B1 {
>From 47f8b3ae301522b77b6a60e1c2685b60a4c19d6b Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 7 May 2024 11:15:00 -0400
Subject: [PATCH 5/6] [FOLD] fix test
---
clang/test/CXX/class/class.compare/class.compare.default/p4.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 c89718dd71bb..53a8bfc9a4f4 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
@@ -25,7 +25,7 @@ namespace N {
constexpr std::strong_ordering operator<=>(const A&, const A&) noexcept;
constexpr std::strong_ordering (*test_a_threeway)(const A&, const A&) = &operator<=>;
- static_assert((*test_a_threeway)(A(), A())); // expected-error {{static assertion expression is not an integral constant expression}}
+ static_assert(!(*test_a_threeway)(A(), A())); // expected-error {{static assertion expression is not an integral constant expression}}
// expected-note at -1 {{undefined function 'operator<=>' cannot be used in a constant expression}}
constexpr bool (*test_a_equal_not_found)(const A&, const A&) = &operator==; // expected-error {{undeclared}}
>From fc3166503380593ca0c6197bd1d9a7e5cd09f5c6 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Tue, 7 May 2024 13:35:51 -0400
Subject: [PATCH 6/6] [FOLD] fix clangd tests
---
clang-tools-extra/clangd/unittests/FindTargetTests.cpp | 5 +----
clang-tools-extra/clangd/unittests/HoverTests.cpp | 4 ++--
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 94437857cecc..0b2273f0a9a6 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -642,10 +642,7 @@ TEST_F(TargetDeclTest, RewrittenBinaryOperator) {
bool x = (Foo(1) [[!=]] Foo(2));
)cpp";
EXPECT_DECLS("CXXRewrittenBinaryOperator",
- {"std::strong_ordering operator<=>(const Foo &) const = default",
- Rel::TemplatePattern},
- {"bool operator==(const Foo &) const noexcept = default",
- Rel::TemplateInstantiation});
+ {"bool operator==(const Foo &) const noexcept = default"});
}
TEST_F(TargetDeclTest, FunctionTemplate) {
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 28df24f34827..d9e97e5215a2 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -3091,7 +3091,7 @@ TEST(Hover, All) {
HI.NamespaceScope = "";
HI.Definition =
"bool operator==(const Foo &) const noexcept = default";
- HI.Documentation = "Foo spaceship";
+ HI.Documentation = "";
}},
};
@@ -3894,7 +3894,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, "Foo bar baz");
+ EXPECT_EQ(HI->Documentation, "");
}
TEST(Hover, ForwardStructNoCrash) {
More information about the cfe-commits
mailing list