diff options
author | Douglas Gregor <dgregor@apple.com> | 2013-02-06 22:40:31 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2013-02-06 22:40:31 +0000 |
commit | 8bf778eb9c0afb0a4c63a97ce504f50759c08d5f (patch) | |
tree | c2103331a484b301473ecab3ca98e6bb174ee222 /lib | |
parent | 474e46211a141e4566c399b80ae26e3580b70c90 (diff) |
Detect when we end up trying to load conflicting module files.
This can happen when one abuses precompiled headers by passing more -D
options when using a precompiled hedaer than when it was built. This
is intentionally permitted by precompiled headers (and is exploited by
some build environments), but causes problems for modules.
First part of <rdar://problem/13165109>, detecting when something when
horribly wrong.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174554 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 21 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 13 |
2 files changed, 30 insertions, 4 deletions
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index d4a351394a..b6115ec6ff 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -915,9 +915,9 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, // Search for a module with the given name. Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); std::string ModuleFileName; - if (Module) + if (Module) { ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); - else + } else ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName); if (ModuleFileName.empty()) { @@ -987,6 +987,20 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, return ModuleLoadResult(); } + // If there is already a module file associated with this module, make sure + // it is the same as the module file we're looking for. Otherwise, we + // have two module files for the same module. + if (const FileEntry *CurModuleFile = Module? Module->getASTFile() : 0) { + if (CurModuleFile != ModuleFile) { + getDiagnostics().Report(ModuleNameLoc, diag::err_module_file_conflict) + << ModuleName + << CurModuleFile->getName() + << ModuleFile->getName(); + ModuleBuildFailed = true; + return ModuleLoadResult(); + } + } + // If we don't already have an ASTReader, create one now. if (!ModuleManager) { if (!hasASTContext()) @@ -1085,8 +1099,9 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, .findModule((Path[0].first->getName())); } - if (Module) + if (Module) { Module->setASTFile(ModuleFile); + } // Cache the result of this top-level module lookup for later. Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index dd2d5d12bc..aa4c448e98 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -3408,7 +3408,18 @@ bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) { Error("too many submodules"); return true; } - + + if (const FileEntry *CurFile = CurrentModule->getASTFile()) { + if (CurFile != F.File) { + if (!Diags.isDiagnosticInFlight()) { + Diag(diag::err_module_file_conflict) + << CurrentModule->getTopLevelModuleName() + << CurFile->getName() + << F.File->getName(); + } + return true; + } + } CurrentModule->setASTFile(F.File); CurrentModule->IsFromModuleFile = true; CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem; |