Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -1520,6 +1520,10 @@ if (OldD->isFromASTFile() && isFromASTFile()) return false; + // Do not replace a declaration with a friend. + if (getFriendObjectKind() != FOK_None) + return false; + // A kind mismatch implies that the declaration is not replaced. if (OldD->getKind() != getKind()) return false; Index: test/SemaTemplate/friend-template.cpp =================================================================== --- test/SemaTemplate/friend-template.cpp +++ test/SemaTemplate/friend-template.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s // PR5057 namespace test0 { namespace std { @@ -69,16 +69,13 @@ template struct X2a; - template struct X2b; + template struct X2b; // expected-note {{previous non-type template parameter with type 'int' is here}} template class X3 { template friend struct X2a; - // FIXME: the redeclaration note ends up here because redeclaration - // lookup ends up finding the friend target from X3. - template friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \ - // expected-note {{previous non-type template parameter with type 'int' is here}} + template friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} }; X3 x3i; // okay @@ -297,14 +294,10 @@ int n = C::D().f(); struct F { - template struct G; + template struct G; // expected-note {{previous non-type template parameter with type 'int' is here}} }; template struct H { - // FIXME: As with cases above, the note here is on an unhelpful declaration, - // and should point to the declaration of G within F. - template friend struct F::G; // \ - // expected-error {{different type 'char' in template redeclaration}} \ - // expected-note {{previous}} + template friend struct F::G; // expected-error {{different type 'char' in template redeclaration}} }; H h1; // ok H h2; // expected-note {{instantiation}} @@ -329,3 +322,16 @@ foo(b); // expected-note {{in instantiation}} } } + +namespace PR26962 { +template struct Type { + template friend Type makeType(); +}; + +template Type makeType(); + +void f() { + Type t; + PR26962::makeType<>(); +} +} // end PR26962