https://github.com/HoBoIs created https://github.com/llvm/llvm-project/pull/66487
If there is 2 guides one of them generated from a non-templated constructor and one of them from a templated constructor the standard gives priority to the first. Clang detected ambiguity before, now the correct guide is chosen. Example for the bug: https://godbolt.org/z/ee3e9qG78 Also a minor fix for issue #64020 I'm a new developer, can someone with more experience in clang check if the change in file "clang/lib/Sema/SemaTemplateInstantiateDecl.cpp" can never cause a use after free. >From 5abc9393bf68d14b8cb9cc5cc86a854e3a2aeae5 Mon Sep 17 00:00:00 2001 From: hobois <horvath.botond.ist...@gmial.com> Date: Fri, 15 Sep 2023 09:28:21 +0200 Subject: [PATCH] Bugfix for chosing the correct deduction guide If there is 2 guides one of them generated from a non-templated constructor and one of them from a templated constructor the standard gives priority to the first. Clang detected ambiguity before, now the correct guide is chosen. Also a minor fix for issue #64020 --- clang/lib/Sema/SemaOverload.cpp | 14 +++++++++++++- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 45a9e5dc98c032d..ec902fcad817e76 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -10153,6 +10153,18 @@ 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 +10208,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 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits