Fix tracking of merged definitions when the merge target is also merged

into something else.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@342017 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Smith 2018-09-12 02:13:46 +00:00
parent 8b92e51e54
commit eba34ceb25
3 changed files with 38 additions and 3 deletions

View File

@ -997,7 +997,8 @@ public:
/// Get the additional modules in which the definition \p Def has
/// been merged.
ArrayRef<Module*> getModulesWithMergedDefinition(const NamedDecl *Def) {
auto MergedIt = MergedDefModules.find(Def);
auto MergedIt =
MergedDefModules.find(cast<NamedDecl>(Def->getCanonicalDecl()));
if (MergedIt == MergedDefModules.end())
return None;
return MergedIt->second;

View File

@ -933,13 +933,13 @@ void ASTContext::mergeDefinitionIntoModule(NamedDecl *ND, Module *M,
Listener->RedefinedHiddenDefinition(ND, M);
if (getLangOpts().ModulesLocalVisibility)
MergedDefModules[ND].push_back(M);
MergedDefModules[cast<NamedDecl>(ND->getCanonicalDecl())].push_back(M);
else
ND->setVisibleDespiteOwningModule();
}
void ASTContext::deduplicateMergedDefinitonsFor(NamedDecl *ND) {
auto It = MergedDefModules.find(ND);
auto It = MergedDefModules.find(cast<NamedDecl>(ND->getCanonicalDecl()));
if (It == MergedDefModules.end())
return;

View File

@ -0,0 +1,34 @@
// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility %s -verify -Werror=undefined-inline
#pragma clang module build A1
module A1 { export * }
#pragma clang module contents
#pragma clang module begin A1
template<typename T> class A {};
template<typename T> inline bool f(const A<T>&) { return T::error; }
#pragma clang module end
#pragma clang module endbuild
#pragma clang module build A2
module A2 { export * }
#pragma clang module contents
#pragma clang module begin A2
#pragma clang module load A1
template<typename T> class A {};
template<typename T> inline bool f(const A<T>&) { return T::error; }
#pragma clang module end
#pragma clang module endbuild
#pragma clang module build A3
module A3 { export * }
#pragma clang module contents
#pragma clang module begin A3
template<typename T> class A {};
template<typename T> inline bool f(const A<T>&) { return T::error; }
#pragma clang module end
#pragma clang module endbuild
#pragma clang module load A3
#pragma clang module import A2
// expected-error@* {{cannot be used prior to}}
bool y(A<int> o) { return f(o); } // expected-note {{instantiation of}}