summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaDecl.cpp9
-rw-r--r--clang/test/Modules/friend-definition.cpp39
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;
+}
OpenPOWER on IntegriCloud