diff options
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 9 | ||||
-rw-r--r-- | clang/test/Modules/friend-definition.cpp | 39 |
2 files changed, 48 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 62fd0207715..b358b04142f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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; diff --git a/clang/test/Modules/friend-definition.cpp b/clang/test/Modules/friend-definition.cpp new file mode 100644 index 00000000000..8588cbd9c6f --- /dev/null +++ b/clang/test/Modules/friend-definition.cpp @@ -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; +} |