diff options
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 6 | ||||
-rw-r--r-- | test/SemaTemplate/friend-template.cpp | 15 |
2 files changed, 19 insertions, 2 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 7154d62d6c..0a2c5ae00e 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -1417,9 +1417,11 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, // Substitute the deduced template arguments into the function template // declaration to produce the function template specialization. + DeclContext *Owner = FunctionTemplate->getDeclContext(); + if (FunctionTemplate->getFriendObjectKind()) + Owner = FunctionTemplate->getLexicalDeclContext(); Specialization = cast_or_null<FunctionDecl>( - SubstDecl(FunctionTemplate->getTemplatedDecl(), - FunctionTemplate->getDeclContext(), + SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner, MultiLevelTemplateArgumentList(*DeducedArgumentList))); if (!Specialization) return TDK_SubstitutionFailure; diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp index 6ee30aa777..4b60a3db05 100644 --- a/test/SemaTemplate/friend-template.cpp +++ b/test/SemaTemplate/friend-template.cpp @@ -127,3 +127,18 @@ namespace PR6022 { }; } +namespace FriendTemplateDefinition { + template<unsigned > struct int_c { }; + + template<typename T> + struct X { + template<unsigned N> + friend void f(X, int_c<N>) { + int value = N; + }; + }; + + void test_X(X<int> x, int_c<5> i5) { + f(x, i5); + } +} |