Author: rsmith Date: Thu Mar 1 14:20:13 2018 New Revision: 326496 URL: http://llvm.org/viewvc/llvm-project?rev=326496&view=rev Log: [modules] Don't diagnose "redefinition" of a friend with a pending definition if the other definition is a merged copy of the same function.
Added: cfe/trunk/test/Modules/friend-definition.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=326496&r1=326495&r2=326496&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Mar 1 14:20:13 2018 @@ -12303,6 +12303,15 @@ Sema::CheckForFunctionRedefinition(Funct if (I != FD && !I->isInvalidDecl() && I->getFriendObjectKind() != Decl::FOK_None) { if (FunctionDecl *Original = I->getInstantiatedFromMemberFunction()) { + if (FunctionDecl *OrigFD = FD->getInstantiatedFromMemberFunction()) { + // A merged copy of the same function, instantiated as a member of + // the same class, is OK. + if (declaresSameEntity(OrigFD, Original) && + declaresSameEntity(cast<Decl>(I->getLexicalDeclContext()), + cast<Decl>(FD->getLexicalDeclContext()))) + continue; + } + if (Original->isThisDeclarationADefinition()) { Definition = I; break; Added: cfe/trunk/test/Modules/friend-definition.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/friend-definition.cpp?rev=326496&view=auto ============================================================================== --- cfe/trunk/test/Modules/friend-definition.cpp (added) +++ cfe/trunk/test/Modules/friend-definition.cpp Thu Mar 1 14:20:13 2018 @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -fmodules -std=c++14 %s -verify +// expected-no-diagnostics + +#pragma clang module build A +module A {} +#pragma clang module contents +#pragma clang module begin A +template<typename T> struct A { + friend A operator+(const A&, const A&) { return {}; } +}; +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build B +module B {} +#pragma clang module contents +#pragma clang module begin B +#pragma clang module import A +inline void f() { A<int> a; } +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build C +module C {} +#pragma clang module contents +#pragma clang module begin C +#pragma clang module import A +inline void g() { A<int> a; } +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module import A +#pragma clang module import B +#pragma clang module import C + +void h() { + A<int> a; + a + a; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits