[modules] Don't diagnose "redefinition" of a friend with a pending definition

if the other definition is a merged copy of the same function.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326496 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Smith 2018-03-01 22:20:13 +00:00
parent 022231bce0
commit a5a02bcb34
2 changed files with 48 additions and 0 deletions

View File

@ -12303,6 +12303,15 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD,
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;

View File

@ -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;
}