Author: Matheus Izvekov Date: 2024-05-23T21:33:35-03:00 New Revision: 06aadbeb2538c3e28cca7c82db102dffc7bdc269
URL: https://github.com/llvm/llvm-project/commit/06aadbeb2538c3e28cca7c82db102dffc7bdc269 DIFF: https://github.com/llvm/llvm-project/commit/06aadbeb2538c3e28cca7c82db102dffc7bdc269.diff LOG: Revert "[clang] Implement CWG2398 provisional TTP matching to class templates" (#93258) Reverts llvm/llvm-project#92855 This is causing issues, there are still being reduced, but does look like a problem. See PR for user reports. Added: Modified: clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp clang/test/SemaTemplate/cwg2398.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 268f079980a6c..39e9dbed0c3e0 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1807,8 +1807,6 @@ static void SetNestedNameSpecifier(Sema &S, TagDecl *T, // Returns the template parameter list with all default template argument // information. static TemplateParameterList *GetTemplateParameterList(TemplateDecl *TD) { - if (TD->isImplicit()) - return TD->getTemplateParameters(); // Make sure we get the template parameter list from the most // recent declaration, since that is the only one that is guaranteed to // have all the default template argument information. @@ -1829,8 +1827,7 @@ static TemplateParameterList *GetTemplateParameterList(TemplateDecl *TD) { // template <class = void> friend struct C; // }; // template struct S<int>; - while ((D->isImplicit() || - D->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None) && + while (D->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None && D->getPreviousDecl()) D = D->getPreviousDecl(); return cast<TemplateDecl>(D)->getTemplateParameters(); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 08a69d3cb2589..f9ec34163e656 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -527,8 +527,8 @@ static NamedDecl *getTemplateParameterWithDefault(Sema &S, NamedDecl *A, R->setDefaultArgument( S.Context, S.getTrivialTemplateArgumentLoc(Default, QualType(), SourceLocation())); - if (T->hasTypeConstraint()) { - auto *C = T->getTypeConstraint(); + if (R->hasTypeConstraint()) { + auto *C = R->getTypeConstraint(); R->setTypeConstraint(C->getConceptReference(), C->getImmediatelyDeclaredConstraint()); } @@ -583,53 +583,37 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, return TemplateDeductionResult::Success; auto NewDeduced = DeducedTemplateArgument(Arg); - // Provisional resolution for CWG2398: If Arg names a template - // specialization, then we deduce a synthesized template template parameter - // based on A, but using the TS's arguments as defaults. - if (DefaultArguments.size() != 0) { + // Provisional resolution for CWG2398: If Arg is also a template template + // param, and it names a template specialization, then we deduce a + // synthesized template template parameter based on A, but using the TS's + // arguments as defaults. + if (auto *TempArg = dyn_cast_or_null<TemplateTemplateParmDecl>( + Arg.getAsTemplateDecl())) { assert(Arg.getKind() == TemplateName::Template); - TemplateDecl *TempArg = Arg.getAsTemplateDecl(); + assert(!TempArg->isExpandedParameterPack()); + TemplateParameterList *As = TempArg->getTemplateParameters(); - assert(DefaultArguments.size() <= As->size()); - - SmallVector<NamedDecl *, 4> Params(As->size()); - for (unsigned I = 0; I < DefaultArguments.size(); ++I) - Params[I] = getTemplateParameterWithDefault(S, As->getParam(I), - DefaultArguments[I]); - for (unsigned I = DefaultArguments.size(); I < As->size(); ++I) - Params[I] = As->getParam(I); - // FIXME: We could unique these, and also the parameters, but we don't - // expect programs to contain a large enough amount of these deductions - // for that to be worthwhile. - auto *TPL = TemplateParameterList::Create( - S.Context, SourceLocation(), SourceLocation(), Params, - SourceLocation(), As->getRequiresClause()); - - TemplateDecl *TD; - switch (TempArg->getKind()) { - case Decl::TemplateTemplateParm: { - auto *A = cast<TemplateTemplateParmDecl>(TempArg); - assert(!A->isExpandedParameterPack()); - TD = TemplateTemplateParmDecl::Create( - S.Context, A->getDeclContext(), SourceLocation(), A->getDepth(), - A->getPosition(), A->isParameterPack(), A->getIdentifier(), - A->wasDeclaredWithTypename(), TPL); - break; - } - case Decl::ClassTemplate: { - auto *A = cast<ClassTemplateDecl>(TempArg); - auto *CT = ClassTemplateDecl::Create(S.Context, A->getDeclContext(), - SourceLocation(), A->getDeclName(), - TPL, A->getTemplatedDecl()); - CT->setPreviousDecl(A); - TD = CT; - break; - } - default: - llvm_unreachable("Unexpected Template Kind"); + if (DefaultArguments.size() != 0) { + assert(DefaultArguments.size() <= As->size()); + SmallVector<NamedDecl *, 4> Params(As->size()); + for (unsigned I = 0; I < DefaultArguments.size(); ++I) + Params[I] = getTemplateParameterWithDefault(S, As->getParam(I), + DefaultArguments[I]); + for (unsigned I = DefaultArguments.size(); I < As->size(); ++I) + Params[I] = As->getParam(I); + // FIXME: We could unique these, and also the parameters, but we don't + // expect programs to contain a large enough amount of these deductions + // for that to be worthwhile. + auto *TPL = TemplateParameterList::Create( + S.Context, SourceLocation(), SourceLocation(), Params, + SourceLocation(), As->getRequiresClause()); + NewDeduced = DeducedTemplateArgument( + TemplateName(TemplateTemplateParmDecl::Create( + S.Context, TempArg->getDeclContext(), SourceLocation(), + TempArg->getDepth(), TempArg->getPosition(), + TempArg->isParameterPack(), TempArg->getIdentifier(), + TempArg->wasDeclaredWithTypename(), TPL))); } - TD->setImplicit(true); - NewDeduced = DeducedTemplateArgument(TemplateName(TD)); } DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context, diff --git a/clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp b/clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp index bc39431253880..a5b39fe5c51f7 100644 --- a/clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp @@ -28,14 +28,13 @@ namespace StdExample { { /* ... */ } template<template<class> class TT> - void f(TT<int>); + void f(TT<int>); // expected-note {{candidate template ignored}} template<template<class,class> class TT> void g(TT<int, Alloc<int>>); int h() { - f(v); // OK: TT = vector, Alloc<int> is used as the default argument for the - // second parameter. + f(v); // expected-error {{no matching function for call to 'f'}} g(v); // OK: TT = vector } diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp index 4cc946735a1e2..e3b5e575374d3 100644 --- a/clang/test/SemaTemplate/cwg2398.cpp +++ b/clang/test/SemaTemplate/cwg2398.cpp @@ -65,10 +65,13 @@ namespace class_template { template <class T3> struct B; template <template <class T4> class TT1, class T5> struct B<TT1<T5>>; + // new-note@-1 {{partial specialization matches}} template <class T6, class T7> struct B<A<T6, T7>> {}; + // new-note@-1 {{partial specialization matches}} template struct B<A<int>>; + // new-error@-1 {{ambiguous partial specialization}} } // namespace class_template namespace type_pack1 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits