[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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@260543 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ben Langmuir 2016-02-11 17:04:42 +00:00
parent bad77a8763
commit 0ebc3ae333
8 changed files with 34 additions and 1 deletions

View 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;

View 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();

View 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 *
}
}

View File

@ -0,0 +1 @@
// preamble-with-implicit-import-A

View File

@ -0,0 +1,3 @@
#pragma once
#include "preamble-with-implicit-import-C.h" // Circular
typedef struct { char x; } Typo;

View File

@ -0,0 +1,2 @@
#pragma once
#include "preamble-with-implicit-import-B.h" // Circular

View File

@ -0,0 +1,4 @@
#include "preamble-with-implicit-import-A.h"
// Typo is defined in B, which is not imported.
void useTypeFromB(Typo *);

View File

@ -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"