r174554 - Detect when we end up trying to load conflicting module files.

Douglas Gregor dgregor at apple.com
Wed Feb 6 14:40:31 PST 2013


Author: dgregor
Date: Wed Feb  6 16:40:31 2013
New Revision: 174554

URL: http://llvm.org/viewvc/llvm-project?rev=174554&view=rev
Log:
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.

Added:
    cfe/trunk/test/Modules/Inputs/ignored_macros.h
    cfe/trunk/test/Modules/ignored_macros.m
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/test/Modules/Inputs/module.map

Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=174554&r1=174553&r2=174554&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Wed Feb  6 16:40:31 2013
@@ -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'">;
+
 }

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=174554&r1=174553&r2=174554&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Wed Feb  6 16:40:31 2013
@@ -915,9 +915,9 @@ CompilerInstance::loadModule(SourceLocat
     // 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(SourceLocat
       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(SourceLocat
                  .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;

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=174554&r1=174553&r2=174554&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Feb  6 16:40:31 2013
@@ -3408,7 +3408,18 @@ bool ASTReader::ReadSubmoduleBlock(Modul
         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;

Added: cfe/trunk/test/Modules/Inputs/ignored_macros.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/ignored_macros.h?rev=174554&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/ignored_macros.h (added)
+++ cfe/trunk/test/Modules/Inputs/ignored_macros.h Wed Feb  6 16:40:31 2013
@@ -0,0 +1,8 @@
+struct Point {
+  double x, y;
+};
+
+#ifdef IGNORED
+int *has_ignored(void);
+#endif
+

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=174554&r1=174553&r2=174554&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Wed Feb  6 16:40:31 2013
@@ -159,3 +159,7 @@ module autolink {
 module weird_objc {
   header "weird_objc.h"
 }
+
+module ignored_macros {
+  header "ignored_macros.h"
+}

Added: cfe/trunk/test/Modules/ignored_macros.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ignored_macros.m?rev=174554&view=auto
==============================================================================
--- cfe/trunk/test/Modules/ignored_macros.m (added)
+++ cfe/trunk/test/Modules/ignored_macros.m Wed Feb  6 16:40:31 2013
@@ -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
+ at import ignored_macros;
+#endif
+
+ at import ignored_macros;
+
+struct Point p;





More information about the cfe-commits mailing list