Skip to content

Commit

Permalink
Revert "[clang] Implement CWG2398 provisional TTP matching to class t…
Browse files Browse the repository at this point in the history
…emplates" (#93258)

Reverts #92855

This is causing issues, there are still being reduced, but does look
like a problem.

See PR for user reports.
  • Loading branch information
mizvekov authored May 24, 2024
1 parent ddee8ef commit 06aadbe
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 53 deletions.
5 changes: 1 addition & 4 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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();
Expand Down
76 changes: 30 additions & 46 deletions clang/lib/Sema/SemaTemplateDeduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 2 additions & 3 deletions clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
3 changes: 3 additions & 0 deletions clang/test/SemaTemplate/cwg2398.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 06aadbe

Please sign in to comment.