зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
474e46211a
Коммит
8bf778eb9c
|
@ -118,4 +118,8 @@ def err_unable_to_rename_temp : Error<
|
|||
"unable to rename temporary '%0' to output file '%1': '%2'">;
|
||||
def err_unable_to_make_temp : Error<
|
||||
"unable to make temporary file: %0">;
|
||||
|
||||
// Modules
|
||||
def err_module_file_conflict : Error<"module '%0' found in both '%1' and '%2'">;
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
struct Point {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
#ifdef IGNORED
|
||||
int *has_ignored(void);
|
||||
#endif
|
||||
|
|
@ -159,3 +159,7 @@ module autolink {
|
|||
module weird_objc {
|
||||
header "weird_objc.h"
|
||||
}
|
||||
|
||||
module ignored_macros {
|
||||
header "ignored_macros.h"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// First trial: pass -DIGNORED=1 to both. It should be ignored in both
|
||||
// RUN: rm -rf %t.modules
|
||||
// RUN: %clang_cc1 -fmodule-cache-path %t.modules -DIGNORED=1 -fmodules -I %S/Inputs -emit-pch -o %t.pch -x objective-c-header %s -verify
|
||||
// RUN: %clang_cc1 -fmodule-cache-path %t.modules -DIGNORED=1 -fmodules -I %S/Inputs -include-pch %t.pch %s -verify
|
||||
|
||||
// Second trial: pass -DIGNORED=1 only to the second invocation.
|
||||
// RUN: rm -rf %t.modules
|
||||
// RUN: %clang_cc1 -fmodule-cache-path %t.modules -fmodules -I %S/Inputs -emit-pch -o %t.pch -x objective-c-header %s -verify
|
||||
// RUN: not %clang_cc1 -fmodule-cache-path %t.modules -DIGNORED=1 -fmodules -I %S/Inputs -include-pch %t.pch %s > %t.err 2>&1
|
||||
// RUN: FileCheck -check-prefix=CHECK-CONFLICT %s < %t.err
|
||||
// CHECK-CONFLICT: module 'ignored_macros' found in both
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
@import ignored_macros;
|
||||
#endif
|
||||
|
||||
@import ignored_macros;
|
||||
|
||||
struct Point p;
|
Загрузка…
Ссылка в новой задаче