[libcxx-commits] [libcxx] Bugfix for chosing the correct deduction guide (PR #66487)
Botond István Hprváth via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Oct 4 01:52:22 PDT 2023
https://github.com/HoBoIs updated https://github.com/llvm/llvm-project/pull/66487
>From 258462cc65403af147bb47cbeb95210df8e18cd3 Mon Sep 17 00:00:00 2001
From: hobois <horvath.botond.istvan at gmial.com>
Date: Fri, 15 Sep 2023 09:28:21 +0200
Subject: [PATCH 1/5] Choose the correct deduction guide
If there are two guides, one of them generated from a non-templated constructor
and the other from a templated constructor, then the standard gives priority to
the first. Clang detected ambiguity before, now the correct guide is chosen.
As an unrelated minor change, fix the issue #64020, which could've led to
incorrect behavior if further development inserted code after a call to
isAddressSpaceSubsetOf() which specified the two parameters in the wrong order.
---
clang/lib/Sema/SemaOverload.cpp | 17 ++++++++++++++++-
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 +-
.../over.match.class.deduct/p2.cpp | 10 ++++++++++
3 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 45a9e5dc98c032d..1bb81238520173a 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10153,6 +10153,21 @@ bool clang::isBetterOverloadCandidate(
// -- F1 is the copy deduction candidate(16.3.1.8) and F2 is not
if (Guide1->getDeductionCandidateKind() == DeductionCandidate::Copy)
return true;
+ if (Guide2->getDeductionCandidateKind() == DeductionCandidate::Copy)
+ return false;
+
+ // --F1 is generated from a non-template constructor and F2 is generated
+ // from a constructor template
+ const auto *Constructor1 = Guide1->getCorrespondingConstructor();
+ const auto *Constructor2 = Guide2->getCorrespondingConstructor();
+ if (Constructor1 && Constructor2) {
+ bool isC1Templated = Constructor1->getTemplatedKind() !=
+ FunctionDecl::TemplatedKind::TK_NonTemplate;
+ bool isC2Templated = Constructor2->getTemplatedKind() !=
+ FunctionDecl::TemplatedKind::TK_NonTemplate;
+ if (isC1Templated != isC2Templated)
+ return isC2Templated;
+ }
}
}
@@ -10196,7 +10211,7 @@ bool clang::isBetterOverloadCandidate(
if (AS1 != AS2) {
if (Qualifiers::isAddressSpaceSupersetOf(AS2, AS1))
return true;
- if (Qualifiers::isAddressSpaceSupersetOf(AS2, AS1))
+ if (Qualifiers::isAddressSpaceSupersetOf(AS1, AS2))
return false;
}
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 9e5f85b0f9166bd..b9c4a9db842b9ee 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2129,7 +2129,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
Function = CXXDeductionGuideDecl::Create(
SemaRef.Context, DC, D->getInnerLocStart(),
InstantiatedExplicitSpecifier, NameInfo, T, TInfo,
- D->getSourceRange().getEnd(), /*Ctor=*/nullptr,
+ D->getSourceRange().getEnd(), DGuide->getCorrespondingConstructor(),
DGuide->getDeductionCandidateKind());
Function->setAccess(D->getAccess());
} else {
diff --git a/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp b/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
index 4eac0a1ac510f1d..d939d724dc7a0fd 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
@@ -85,3 +85,13 @@ int main() {
}
+
+namespace deduceTemplatedConstructor{
+template <class T> struct A {
+ A(T, T, int);
+ template<class U>
+ A(int, T, U);
+};
+
+A x(1, 2, 3); // no-error
+}
>From 877678b01d05eb301ac49a2a39186a743ca9012d Mon Sep 17 00:00:00 2001
From: hobois <horvath.botond.istvan at gmial.com>
Date: Tue, 3 Oct 2023 18:20:11 +0200
Subject: [PATCH 2/5] Added the fix to relasenotes
---
clang/docs/ReleaseNotes.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6be824771c583be..84eb3301deb4b37 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -390,6 +390,11 @@ Bug Fixes to C++ Support
we now produce a diagnostic. Fixes:
(`#65522 <https://github.com/llvm/llvm-project/issues/65522>`_)
+- Fixed a bug where clang incorrectly considered implicitly generated deduction
+ guides from a non-templated constructor and a templated constructor as ambiguous,
+ rather than prefer the non-templated constructor as specified in
+ [standard.group]p3
+
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Fixed an import failure of recursive friend class template.
>From fc425a9be52b9278cd66e123019da2aaa3a0ee9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Hprv=C3=A1th?=
<56926027+HoBoIs at users.noreply.github.com>
Date: Tue, 3 Oct 2023 18:26:17 +0200
Subject: [PATCH 3/5] Update ReleaseNotes.rst
---
clang/docs/ReleaseNotes.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 84eb3301deb4b37..47984a1b385e492 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -393,7 +393,7 @@ Bug Fixes to C++ Support
- Fixed a bug where clang incorrectly considered implicitly generated deduction
guides from a non-templated constructor and a templated constructor as ambiguous,
rather than prefer the non-templated constructor as specified in
- [standard.group]p3
+ [standard.group]p3.
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
>From cb032a77662c070cb89ee959ed2f52a5f91ecd52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Hprv=C3=A1th?=
<56926027+HoBoIs at users.noreply.github.com>
Date: Tue, 3 Oct 2023 18:43:41 +0200
Subject: [PATCH 4/5] Formated ReleaseNotes.rst
---
clang/docs/ReleaseNotes.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 47984a1b385e492..f79c0fcf231187d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -392,7 +392,7 @@ Bug Fixes to C++ Support
- Fixed a bug where clang incorrectly considered implicitly generated deduction
guides from a non-templated constructor and a templated constructor as ambiguous,
- rather than prefer the non-templated constructor as specified in
+ rather than prefer the non-templated constructor as specified in
[standard.group]p3.
Bug Fixes to AST Handling
>From 289c269d9c42fc43062fcb3fb950deb0a6cb11e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Botond=20Istv=C3=A1n=20Hprv=C3=A1th?=
<56926027+HoBoIs at users.noreply.github.com>
Date: Wed, 4 Oct 2023 10:52:05 +0200
Subject: [PATCH 5/5] Added tests to p2.cpp
---
.../over.match.class.deduct/p2.cpp | 27 ++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp b/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
index d939d724dc7a0fd..57fef7d4cc7da61 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
@@ -87,11 +87,36 @@ int main() {
}
namespace deduceTemplatedConstructor{
+template <typename X, typename Y> struct IsSame {
+ static constexpr bool value = false;
+};
+
+template <typename Z> struct IsSame<Z, Z> {
+ static constexpr bool value = true;
+};
template <class T> struct A {
+ using value_type = T;
+ A(value_type);
+ A(const A&);
A(T, T, int);
template<class U>
- A(int, T, U);
+ A(int, T, U);
};
A x(1, 2, 3); // no-error
+static_assert(IsSame<decltype(x),A<int>>::value);
+
+template <class T>
+A(T) -> A<T>;
+
+A a(42);
+static_assert(IsSame<decltype(a),A<int>>::value);
+A b = a;
+static_assert(IsSame<decltype(b),A<int>>::value);
+
+template <class T>
+A(A<T>) -> A<A<T>>;
+
+A b2 = a;
+static_assert(IsSame<decltype(b2),A<A<int>>>::value);
}
More information about the libcxx-commits
mailing list