]> granicus.if.org Git - clang/commitdiff
[Modules] Don't infinite recurse on implicit import of circular modules in preamble
authorBen Langmuir <blangmuir@apple.com>
Thu, 11 Feb 2016 17:04:42 +0000 (17:04 +0000)
committerBen Langmuir <blangmuir@apple.com>
Thu, 11 Feb 2016 17:04:42 +0000 (17:04 +0000)
Update the Preprocessor's VisibleModuleSet when typo-correction creates
an implicit module import so that we won't accidentally write an invalid
SourceLocation into the preamble AST.  This would later lead to infinite
recursion when loading the preamble AST because we use the value in
ImportLocs to prevent visiting a module twice.

rdar://problem/24440990

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@260543 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Basic/Module.cpp
lib/Serialization/ASTReader.cpp
test/Index/Inputs/module.map
test/Index/Inputs/preamble-with-implicit-import-A.h [new file with mode: 0644]
test/Index/Inputs/preamble-with-implicit-import-B.h [new file with mode: 0644]
test/Index/Inputs/preamble-with-implicit-import-C.h [new file with mode: 0644]
test/Index/Inputs/preamble-with-implicit-import.h [new file with mode: 0644]
test/Index/preamble-with-implicit-import.m [new file with mode: 0644]

index baeeb9edbddf8455527d8d59b22dbb2992043f56..e119c0535eb232b3263d08e8e999de57f1101741 100644 (file)
@@ -492,6 +492,7 @@ LLVM_DUMP_METHOD void Module::dump() const {
 
 void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
                                   VisibleCallback Vis, ConflictCallback Cb) {
+  assert(Loc.isValid() && "setVisible expects a valid import location");
   if (isVisible(M))
     return;
 
index 1c62b4e57b0bf8b14d61805b0ef6700ba8cc168e..b2f59d1fa6c91601452387be3571506eddd1af57 100644 (file)
@@ -4062,7 +4062,9 @@ void ASTReader::InitializeContext() {
     if (Module *Imported = getSubmodule(Import.ID)) {
       makeModuleVisible(Imported, Module::AllVisible,
                         /*ImportLoc=*/Import.ImportLoc);
-      PP.makeModuleVisible(Imported, Import.ImportLoc);
+      if (Import.ImportLoc.isValid())
+        PP.makeModuleVisible(Imported, Import.ImportLoc);
+      // FIXME: should we tell Sema to make the module visible too?
     }
   }
   ImportedModules.clear();
index 4bfc109a8b1361e5790360c4620e1ceff0e9b427..10712accb1c247fa05c4437a953ab31950dadbe3 100644 (file)
@@ -6,3 +6,17 @@ module ModuleNeedsVFS {
 framework module * { }
 
 module ModuleUndef { header "module-undef.h" }
+
+module PreambleWithImplicitImport {
+  module A {
+    header "preamble-with-implicit-import-A.h"
+  }
+  module B {
+    header "preamble-with-implicit-import-B.h"
+    export *
+  }
+  module C {
+    header "preamble-with-implicit-import-C.h"
+    export *
+  }
+}
diff --git a/test/Index/Inputs/preamble-with-implicit-import-A.h b/test/Index/Inputs/preamble-with-implicit-import-A.h
new file mode 100644 (file)
index 0000000..c683901
--- /dev/null
@@ -0,0 +1 @@
+// preamble-with-implicit-import-A
diff --git a/test/Index/Inputs/preamble-with-implicit-import-B.h b/test/Index/Inputs/preamble-with-implicit-import-B.h
new file mode 100644 (file)
index 0000000..17c138d
--- /dev/null
@@ -0,0 +1,3 @@
+#pragma once
+#include "preamble-with-implicit-import-C.h" // Circular
+typedef struct { char x; } Typo;
diff --git a/test/Index/Inputs/preamble-with-implicit-import-C.h b/test/Index/Inputs/preamble-with-implicit-import-C.h
new file mode 100644 (file)
index 0000000..a3fc1d4
--- /dev/null
@@ -0,0 +1,2 @@
+#pragma once
+#include "preamble-with-implicit-import-B.h" // Circular
diff --git a/test/Index/Inputs/preamble-with-implicit-import.h b/test/Index/Inputs/preamble-with-implicit-import.h
new file mode 100644 (file)
index 0000000..1b42967
--- /dev/null
@@ -0,0 +1,4 @@
+#include "preamble-with-implicit-import-A.h"
+
+// Typo is defined in B, which is not imported.
+void useTypeFromB(Typo *);
diff --git a/test/Index/preamble-with-implicit-import.m b/test/Index/preamble-with-implicit-import.m
new file mode 100644 (file)
index 0000000..e3d0e8b
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 2 none %s -I %S/Inputs -fmodules -fmodules-cache-path=%t -fspell-checking 2>&1 | FileCheck %s
+// CHECK: error: declaration of 'Typo' must be imported
+// CHECK: error: declaration of 'Typo' must be imported
+
+#include "preamble-with-implicit-import.h"