summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp14
-rw-r--r--clang/test/Modules/Inputs/merge-implicit-special-members/a.h1
-rw-r--r--clang/test/Modules/Inputs/merge-implicit-special-members/b.h1
-rw-r--r--clang/test/Modules/Inputs/merge-implicit-special-members/c.h3
-rw-r--r--clang/test/Modules/Inputs/merge-implicit-special-members/module.modulemap3
-rw-r--r--clang/test/Modules/merge-implicit-special-members.cpp5
6 files changed, 26 insertions, 1 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index b82f987210f..d43f3eaacb7 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3523,13 +3523,25 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
while (Idx < Record.size()) {
switch ((DeclUpdateKind)Record[Idx++]) {
case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
+ auto *RD = cast<CXXRecordDecl>(D);
// FIXME: If we also have an update record for instantiating the
// definition of D, we need that to happen before we get here.
Decl *MD = Reader.ReadDecl(ModuleFile, Record, Idx);
assert(MD && "couldn't read decl from update record");
// FIXME: We should call addHiddenDecl instead, to add the member
// to its DeclContext.
- cast<CXXRecordDecl>(D)->addedMember(MD);
+ RD->addedMember(MD);
+
+ // If we've added a new special member to a class definition that is not
+ // the canonical definition, then we need special member lookups in the
+ // canonical definition to also look into our class.
+ auto *DD = RD->DefinitionData.getNotUpdated();
+ if (DD && DD->Definition != RD) {
+ auto &Merged = Reader.MergedLookups[DD->Definition];
+ // FIXME: Avoid the linear-time scan here.
+ if (std::find(Merged.begin(), Merged.end(), RD) == Merged.end())
+ Merged.push_back(RD);
+ }
break;
}
diff --git a/clang/test/Modules/Inputs/merge-implicit-special-members/a.h b/clang/test/Modules/Inputs/merge-implicit-special-members/a.h
new file mode 100644
index 00000000000..3029e4afb85
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-implicit-special-members/a.h
@@ -0,0 +1 @@
+struct pthread_mutex_t { int lock; };
diff --git a/clang/test/Modules/Inputs/merge-implicit-special-members/b.h b/clang/test/Modules/Inputs/merge-implicit-special-members/b.h
new file mode 100644
index 00000000000..3029e4afb85
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-implicit-special-members/b.h
@@ -0,0 +1 @@
+struct pthread_mutex_t { int lock; };
diff --git a/clang/test/Modules/Inputs/merge-implicit-special-members/c.h b/clang/test/Modules/Inputs/merge-implicit-special-members/c.h
new file mode 100644
index 00000000000..ee0bebb2ee7
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-implicit-special-members/c.h
@@ -0,0 +1,3 @@
+#include "a.h"
+#include "b.h"
+int k = pthread_mutex_t().lock;
diff --git a/clang/test/Modules/Inputs/merge-implicit-special-members/module.modulemap b/clang/test/Modules/Inputs/merge-implicit-special-members/module.modulemap
new file mode 100644
index 00000000000..77e0a89e39a
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-implicit-special-members/module.modulemap
@@ -0,0 +1,3 @@
+module a { header "a.h" export * }
+module b { header "b.h" export * }
+module c { header "c.h" export * }
diff --git a/clang/test/Modules/merge-implicit-special-members.cpp b/clang/test/Modules/merge-implicit-special-members.cpp
new file mode 100644
index 00000000000..a8b917cb01b
--- /dev/null
+++ b/clang/test/Modules/merge-implicit-special-members.cpp
@@ -0,0 +1,5 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/merge-implicit-special-members -verify %s
+// expected-no-diagnostics
+#include "c.h"
+int n = pthread_mutex_t().lock;
OpenPOWER on IntegriCloud