From 9053226fd88ed71a5235cea59699cbbc765b53a4 Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Sun, 6 Oct 2024 11:34:39 +0200 Subject: [PATCH] Use the instantiation pattern to compute subsumbtion whennot depending on concept template parameters --- clang/lib/Sema/SemaTemplateDeduction.cpp | 29 ++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 65606ce7e3c744..30fb6e0e3734be 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -49,6 +49,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" @@ -6150,6 +6151,22 @@ UnresolvedSetIterator Sema::getMostSpecialized( return SpecEnd; } +static bool ConstraintHasConceptTemplateParameterConceptReference(const Expr* E) { + if(auto* ULE = dyn_cast(E); ULE && ULE->isConceptReference()) + return true; + if(auto* P = dyn_cast(E)) + return ConstraintHasConceptTemplateParameterConceptReference(P->getSubExpr()); + if(auto* B = dyn_cast(E); B && llvm::is_contained({BO_And, BO_Or}, B->getOpcode())) + return ConstraintHasConceptTemplateParameterConceptReference(B->getLHS()) || + ConstraintHasConceptTemplateParameterConceptReference(B->getRHS()); + if(auto* FE = dyn_cast(E); FE && llvm::is_contained({BO_And, BO_Or}, FE->getOperator())) { + if(FE->getInit() && ConstraintHasConceptTemplateParameterConceptReference(FE->getInit())) + return true; + return ConstraintHasConceptTemplateParameterConceptReference(FE->getPattern()); + } + return false; +} + FunctionDecl *Sema::getMoreConstrainedFunction(FunctionDecl *FD1, FunctionDecl *FD2) { assert(!FD1->getDescribedTemplate() && !FD2->getDescribedTemplate() && @@ -6160,12 +6177,16 @@ FunctionDecl *Sema::getMoreConstrainedFunction(FunctionDecl *FD1, isa(FD2)); FunctionDecl *F1 = FD1; - //if (FunctionDecl *P = FD1->getTemplateInstantiationPattern(false)) - // F1 = P; + if(!F1->getTrailingRequiresClause() || !ConstraintHasConceptTemplateParameterConceptReference(F1->getTrailingRequiresClause())) { + if (FunctionDecl *P = FD1->getTemplateInstantiationPattern(false)) + F1 = P; + } FunctionDecl *F2 = FD2; - //if (FunctionDecl *P = FD2->getTemplateInstantiationPattern(false)) - // F2 = P; + if(!F2->getTrailingRequiresClause() || !ConstraintHasConceptTemplateParameterConceptReference(F2->getTrailingRequiresClause())) { + if (FunctionDecl *P = FD2->getTemplateInstantiationPattern(false)) + F2 = P; + } llvm::SmallVector AC1, AC2; F1->getAssociatedConstraints(AC1);