From: Richard Smith Date: Wed, 30 Dec 2015 20:56:05 +0000 (+0000) Subject: Implement [temp.deduct.type]p6: if the nested-name-specifier of a type is X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=88ece4a3de8004f92e6b4c27508b0ca3e54596d3;p=clang Implement [temp.deduct.type]p6: if the nested-name-specifier of a type is dependent, the type is a non-deduced context. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@256651 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index ec0fb0b971..9482e83e81 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -395,7 +395,7 @@ struct DeclarationNameLoc { // Locations (if any) for the tilde (destructor) or operator keyword // (conversion) are stored elsewhere. struct NT { - TypeSourceInfo* TInfo; + TypeSourceInfo *TInfo; }; // The location (if any) of the operator keyword is stored elsewhere. diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index de04c8a7f0..837e0de403 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -4887,19 +4887,23 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, break; case Type::DependentTemplateSpecialization: { + // C++14 [temp.deduct.type]p5: + // The non-deduced contexts are: + // -- The nested-name-specifier of a type that was specified using a + // qualified-id + // + // C++14 [temp.deduct.type]p6: + // When a type name is specified in a way that includes a non-deduced + // context, all of the types that comprise that type name are also + // non-deduced. + if (OnlyDeduced) + break; + const DependentTemplateSpecializationType *Spec = cast(T); - if (!OnlyDeduced) - MarkUsedTemplateParameters(Ctx, Spec->getQualifier(), - OnlyDeduced, Depth, Used); - // C++0x [temp.deduct.type]p9: - // If the template argument list of P contains a pack expansion that is not - // the last template argument, the entire template argument list is a - // non-deduced context. - if (OnlyDeduced && - hasPackExpansionBeforeEnd(Spec->getArgs(), Spec->getNumArgs())) - break; + MarkUsedTemplateParameters(Ctx, Spec->getQualifier(), + OnlyDeduced, Depth, Used); for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I) MarkUsedTemplateParameters(Ctx, Spec->getArg(I), OnlyDeduced, Depth, diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp index bf0812277d..6826774a00 100644 --- a/test/SemaTemplate/deduction.cpp +++ b/test/SemaTemplate/deduction.cpp @@ -207,3 +207,14 @@ namespace PR18645 { template F Quux(F &&f); auto Baz = Quux(Quux); } + +namespace NonDeducedNestedNameSpecifier { + template struct A { + template struct B { + B(int) {} + }; + }; + + template int f(A, typename A::template B); + int k = f(A(), 0); +}