diff options
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; |

