When computing the template arguments for the instantiation of a
friend function template, be sure to adjust the computed template
argument lists based on the location of the definition of the function
template: it's possible that the definition we're instantiating with
and the template declaration that we found when creating the
specialization are in different contexts, which meant that we would
end up using the wrong template arguments for instantiation.
Fixes PR7013; all Boost.DynamicBitset tests now pass.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102974 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp
index 4b60a3d..1d62804 100644
--- a/test/SemaTemplate/friend-template.cpp
+++ b/test/SemaTemplate/friend-template.cpp
@@ -142,3 +142,68 @@
f(x, i5);
}
}
+
+namespace PR7013a {
+ template<class > struct X0
+ {
+ typedef int type;
+ };
+ template<typename > struct X1
+ {
+ };
+ template<typename , typename T> struct X2
+ {
+ typename T::type e;
+ };
+ namespace N
+ {
+ template <typename = int, typename = X1<int> > struct X3
+ {
+ template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
+ };
+ template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
+ {
+ X2<int, Tr> s;
+ }
+ }
+ int n()
+ {
+ X2<int, X0<int> > ngs;
+ N::X3<> b;
+ op(ngs, b);
+ return 0;
+ }
+}
+
+namespace PR7013b {
+ template<class > struct X0
+ {
+ typedef int type;
+ };
+ template<typename > struct X1
+ {
+ };
+ template<typename , typename T> struct X2
+ {
+ typename T::type e;
+ };
+ namespace N
+ {
+ template <typename = X1<int> > struct X3
+ {
+ template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
+ };
+ template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
+ {
+ X2<int, Tr> s;
+ }
+ }
+ int n()
+ {
+ X2<int, X0<int> > ngs;
+ N::X3<> b;
+ op(ngs, b);
+ return 0;
+ }
+
+}