From 1b65dbc4772181dea314782d18717e5397ad2354 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 22 Jan 2015 03:50:31 +0000 Subject: [PATCH] [modules] If we add an implicit special member to a class through an update record, and that class declaration is not the canonical definition of the class, be sure to add the class to the list of classes that are consulted when we look up a special member in the canonical definition. llvm-svn: 226778 --- clang/lib/Serialization/ASTReaderDecl.cpp | 14 +++++++++++++- .../test/Modules/Inputs/merge-implicit-special-members/a.h | 1 + .../test/Modules/Inputs/merge-implicit-special-members/b.h | 1 + .../test/Modules/Inputs/merge-implicit-special-members/c.h | 3 +++ .../Inputs/merge-implicit-special-members/module.modulemap | 3 +++ clang/test/Modules/merge-implicit-special-members.cpp | 5 +++++ 6 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 clang/test/Modules/Inputs/merge-implicit-special-members/a.h create mode 100644 clang/test/Modules/Inputs/merge-implicit-special-members/b.h create mode 100644 clang/test/Modules/Inputs/merge-implicit-special-members/c.h create mode 100644 clang/test/Modules/Inputs/merge-implicit-special-members/module.modulemap create mode 100644 clang/test/Modules/merge-implicit-special-members.cpp diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index b82f987..d43f3ea 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(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(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 0000000..3029e4a --- /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 0000000..3029e4a --- /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 0000000..ee0bebb --- /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 0000000..77e0a89 --- /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 0000000..a8b917c --- /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; -- 2.7.4