]> granicus.if.org Git - clang/commitdiff
A friend template specialization is also dependent if any of its
authorDouglas Gregor <dgregor@apple.com>
Sun, 9 Oct 2011 20:59:17 +0000 (20:59 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sun, 9 Oct 2011 20:59:17 +0000 (20:59 +0000)
template arguments are dependent. Fixes PR10913.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141515 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
test/CXX/temp/temp.decls/temp.friend/p1.cpp

index 451751f14308849d82f7602eba28d2eb1f1c23ff..5ba38ee9f2376f31346bcca328a07ae4b10ac0e0 100644 (file)
@@ -4987,8 +4987,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
     // that either the specialized function type or the specialized
     // template is dependent, and therefore matching will fail.  In
     // this case, don't check the specialization yet.
+    bool InstantiationDependent = false;
     if (isFunctionTemplateSpecialization && isFriend &&
-        (NewFD->getType()->isDependentType() || DC->isDependentContext())) {
+        (NewFD->getType()->isDependentType() || DC->isDependentContext() ||
+         TemplateSpecializationType::anyDependentTemplateArguments(
+            TemplateArgs.getArgumentArray(), TemplateArgs.size(),
+            InstantiationDependent))) {
       assert(HasExplicitTemplateArgs &&
              "friend function specialization without template args");
       if (CheckDependentFunctionTemplateSpecialization(NewFD, TemplateArgs,
index 578de2952d94497491ce2bd1a190b4cdb38ce5c4..63f569be0861da05c3b4c7c428ac0c856623f37b 100644 (file)
@@ -332,3 +332,27 @@ namespace test15 {
 
   template class B<int>; // expected-note {{in instantiation}}
 }
+
+namespace PR10913 {
+  template<class T> class X;
+
+  template<class T> void f(X<T> *x) {
+    x->member = 0;
+  }
+
+  template<class U, class T> void f2(X<T> *x) {
+    x->member = 0; // expected-error{{'member' is a protected member of 'PR10913::X<int>'}}
+  }
+
+  template<class T> class X {
+    friend void f<T>(X<T> *x);
+    friend void f2<T>(X<int> *x);
+
+  protected:
+    int member; // expected-note{{declared protected here}}
+  };
+
+  template void f(X<int> *);
+  template void f2<int>(X<int> *);
+  template void f2<float>(X<int> *); // expected-note{{in instantiation of function template specialization 'PR10913::f2<float, int>' requested here}}
+}