From acfcd78aec83512807718605faf698a20af26fdd Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Thu, 6 Dec 2018 09:35:04 +0000 Subject: Diagnose friend function template redefinitions. Friend function template defined in a class template becomes available if the enclosing class template is instantiated. Until the function template is used, it does not have a body, but still is considered a definition for the purpose of redeclaration checks. This change modifies redefinition check so that it can find the friend function template definitions in instantiated classes. Differential Revision: http://reviews.llvm.org/D21508 llvm-svn: 348473 --- clang/lib/Sema/SemaDecl.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'clang/lib/Sema/SemaDecl.cpp') diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 083089fc994..a4545f2ff63 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12737,6 +12737,29 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, } } } + + if (!Definition) + // Similar to friend functions a friend function template may be a + // definition and do not have a body if it is instantiated in a class + // template. + if (FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) { + for (auto I : FTD->redecls()) { + auto D = cast(I); + if (D != FTD) { + assert(!D->isThisDeclarationADefinition() && + "More than one definition in redeclaration chain"); + if (D->getFriendObjectKind() != Decl::FOK_None) + if (FunctionTemplateDecl *FT = + D->getInstantiatedFromMemberTemplate()) { + if (FT->isThisDeclarationADefinition()) { + Definition = D->getTemplatedDecl(); + break; + } + } + } + } + } + if (!Definition) return; -- cgit v1.2.3