aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-01-16 18:09:52 +0000
committerDouglas Gregor <dgregor@apple.com>2010-01-16 18:09:52 +0000
commit5d52e47ed6a4f920723ebec371594a3fe7878d7c (patch)
treeb91a3e14dd3ccd85f4bec86c5eabf37652281b54
parent1adb082a709f7b588f03672999294e061234b2cf (diff)
Partial fix for PR6022, where we were complaining when a friend
function template declared within a class template did not match a function in another scope. We really need to rework how friends-in-templates are semantically checked. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93642 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDecl.cpp3
-rw-r--r--test/SemaTemplate/friend-template.cpp18
2 files changed, 19 insertions, 2 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index b308613a46..101cae84be 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3362,7 +3362,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
Diag(NewFD->getLocation(), diag::err_out_of_line_declaration)
<< D.getCXXScopeSpec().getRange();
NewFD->setInvalidDecl();
- } else if (!Redeclaration) {
+ } else if (!Redeclaration &&
+ !(isFriend && CurContext->isDependentContext())) {
// The user tried to provide an out-of-line definition for a
// function that is a member of a class or namespace, but there
// was no such member function declared (C++ [class.mfct]p2,
diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp
index 05289b10d2..8bc2631e11 100644
--- a/test/SemaTemplate/friend-template.cpp
+++ b/test/SemaTemplate/friend-template.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-
// PR5057
namespace test0 {
namespace std {
@@ -107,3 +106,20 @@ namespace test5 {
template <typename T> friend struct cache;
};
}
+
+// PR6022
+namespace PR6022 {
+ template <class T1, class T2 , class T3 > class A;
+
+ namespace inner {
+ template<class T1, class T2, class T3, class T>
+ A<T1, T2, T3>& f0(A<T1, T2, T3>&, T);
+ }
+
+ template<class T1, class T2, class T3>
+ class A {
+ template<class U1, class U2, class U3, class T>
+ friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T);
+ };
+}
+