summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2016-02-11 17:04:42 +0000
committerBen Langmuir <blangmuir@apple.com>2016-02-11 17:04:42 +0000
commit6d25fdc41b7444e15395f5e8f9961825f1d0a163 (patch)
tree6d668aafd4320ea590d8c594e8a7e7294a29c7a8 /clang
parentc97efa46f3b3ecfff03cbde04db9703a2886d7e9 (diff)
downloadbcm5719-llvm-6d25fdc41b7444e15395f5e8f9961825f1d0a163.tar.gz
bcm5719-llvm-6d25fdc41b7444e15395f5e8f9961825f1d0a163.zip
[Modules] Don't infinite recurse on implicit import of circular modules in preamble
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 llvm-svn: 260543
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Basic/Module.cpp1
-rw-r--r--clang/lib/Serialization/ASTReader.cpp4
-rw-r--r--clang/test/Index/Inputs/module.map14
-rw-r--r--clang/test/Index/Inputs/preamble-with-implicit-import-A.h1
-rw-r--r--clang/test/Index/Inputs/preamble-with-implicit-import-B.h3
-rw-r--r--clang/test/Index/Inputs/preamble-with-implicit-import-C.h2
-rw-r--r--clang/test/Index/Inputs/preamble-with-implicit-import.h4
-rw-r--r--clang/test/Index/preamble-with-implicit-import.m6
8 files changed, 34 insertions, 1 deletions
diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp
index baeeb9edbdd..e119c0535eb 100644
--- a/clang/lib/Basic/Module.cpp
+++ b/clang/lib/Basic/Module.cpp
@@ -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;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 1c62b4e57b0..b2f59d1fa6c 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -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();
diff --git a/clang/test/Index/Inputs/module.map b/clang/test/Index/Inputs/module.map
index 4bfc109a8b1..10712accb1c 100644
--- a/clang/test/Index/Inputs/module.map
+++ b/clang/test/Index/Inputs/module.map
@@ -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/clang/test/Index/Inputs/preamble-with-implicit-import-A.h b/clang/test/Index/Inputs/preamble-with-implicit-import-A.h
new file mode 100644
index 00000000000..c6839015909
--- /dev/null
+++ b/clang/test/Index/Inputs/preamble-with-implicit-import-A.h
@@ -0,0 +1 @@
+// preamble-with-implicit-import-A
diff --git a/clang/test/Index/Inputs/preamble-with-implicit-import-B.h b/clang/test/Index/Inputs/preamble-with-implicit-import-B.h
new file mode 100644
index 00000000000..17c138dfb5a
--- /dev/null
+++ b/clang/test/Index/Inputs/preamble-with-implicit-import-B.h
@@ -0,0 +1,3 @@
+#pragma once
+#include "preamble-with-implicit-import-C.h" // Circular
+typedef struct { char x; } Typo;
diff --git a/clang/test/Index/Inputs/preamble-with-implicit-import-C.h b/clang/test/Index/Inputs/preamble-with-implicit-import-C.h
new file mode 100644
index 00000000000..a3fc1d4fea0
--- /dev/null
+++ b/clang/test/Index/Inputs/preamble-with-implicit-import-C.h
@@ -0,0 +1,2 @@
+#pragma once
+#include "preamble-with-implicit-import-B.h" // Circular
diff --git a/clang/test/Index/Inputs/preamble-with-implicit-import.h b/clang/test/Index/Inputs/preamble-with-implicit-import.h
new file mode 100644
index 00000000000..1b429678f21
--- /dev/null
+++ b/clang/test/Index/Inputs/preamble-with-implicit-import.h
@@ -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/clang/test/Index/preamble-with-implicit-import.m b/clang/test/Index/preamble-with-implicit-import.m
new file mode 100644
index 00000000000..e3d0e8b1a62
--- /dev/null
+++ b/clang/test/Index/preamble-with-implicit-import.m
@@ -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"
OpenPOWER on IntegriCloud