@@ -740,6 +740,28 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
740740 return false ;
741741}
742742
743+ // Returns all source deduction guides associated with the declared
744+ // deduction guides that have the specified deduction guide name.
745+ llvm::DenseSet<const NamedDecl *> getSourceDeductionGuides (DeclarationName Name,
746+ DeclContext *DC) {
747+ assert (Name.getNameKind () ==
748+ DeclarationName::NameKind::CXXDeductionGuideName &&
749+ " name must be a deduction guide name" );
750+ llvm::DenseSet<const NamedDecl *> Result;
751+ for (auto *D : DC->lookup (Name)) {
752+ if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
753+ D = FTD->getTemplatedDecl ();
754+
755+ if (const auto *GD = dyn_cast<CXXDeductionGuideDecl>(D)) {
756+ assert (GD->getSourceDeductionGuide () &&
757+ " deduction guide for alias template must have a source deduction "
758+ " guide" );
759+ Result.insert (GD->getSourceDeductionGuide ());
760+ }
761+ }
762+ return Result;
763+ }
764+
743765// Build the associated constraints for the alias deduction guides.
744766// C++ [over.match.class.deduct]p3.3:
745767// The associated constraints ([temp.constr.decl]) are the conjunction of the
@@ -1191,17 +1213,14 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
11911213 if (AliasTemplate->isInvalidDecl ())
11921214 return ;
11931215 auto &Context = SemaRef.Context ;
1194- // FIXME: if there is an explicit deduction guide after the first use of the
1195- // type alias usage, we will not cover this explicit deduction guide. fix this
1196- // case.
1197- if (hasDeclaredDeductionGuides (
1198- Context.DeclarationNames .getCXXDeductionGuideName (AliasTemplate),
1199- AliasTemplate->getDeclContext ()))
1200- return ;
12011216 auto [Template, AliasRhsTemplateArgs] =
12021217 getRHSTemplateDeclAndArgs (SemaRef, AliasTemplate);
12031218 if (!Template)
12041219 return ;
1220+ auto SourceDeductionGuides = getSourceDeductionGuides (
1221+ Context.DeclarationNames .getCXXDeductionGuideName (AliasTemplate),
1222+ AliasTemplate->getDeclContext ());
1223+
12051224 DeclarationNameInfo NameInfo (
12061225 Context.DeclarationNames .getCXXDeductionGuideName (Template), Loc);
12071226 LookupResult Guides (SemaRef, NameInfo, clang::Sema::LookupOrdinaryName);
@@ -1210,6 +1229,8 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
12101229
12111230 for (auto *G : Guides) {
12121231 if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) {
1232+ if (SourceDeductionGuides.contains (DG))
1233+ continue ;
12131234 // The deduction guide is a non-template function decl, we just clone it.
12141235 auto *FunctionType =
12151236 SemaRef.Context .getTrivialTypeSourceInfo (DG->getType ());
@@ -1252,7 +1273,7 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
12521273 continue ;
12531274 }
12541275 FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(G);
1255- if (!F)
1276+ if (!F || SourceDeductionGuides. contains (F-> getTemplatedDecl ()) )
12561277 continue ;
12571278 // The **aggregate** deduction guides are handled in a different code path
12581279 // (DeclareAggregateDeductionGuideFromInitList), which involves the tricky
0 commit comments