Skip to content

Commit 7ac737e

Browse files
committed
[HeaderSearch] Fix processing #import-ed headers multiple times with modules enabled.
HeaderSearch was marking requested HeaderFileInfo as Resolved only based on the presence of ExternalSource. As the result, using any module was enough to set ExternalSource and headers unknown to this module would have HeaderFileInfo with empty fields, including `isImport = 0`, `NumIncludes = 0`. Such HeaderFileInfo was preserved without changes regardless of how the header was used in other modules and caused incorrect result in `HeaderSearch::ShouldEnterIncludeFile`. Fix by marking HeaderFileInfo as Resolved only if ExternalSource knows about this header. rdar://problem/62126911 Reviewed By: bruno Differential Revision: https://reviews.llvm.org/D80263
1 parent ea9bf46 commit 7ac737e

File tree

8 files changed

+45
-10
lines changed

8 files changed

+45
-10
lines changed

clang/lib/Lex/HeaderSearch.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,12 +1167,12 @@ HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
11671167
HeaderFileInfo *HFI = &FileInfo[FE->getUID()];
11681168
// FIXME: Use a generation count to check whether this is really up to date.
11691169
if (ExternalSource && !HFI->Resolved) {
1170-
HFI->Resolved = true;
11711170
auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1172-
1173-
HFI = &FileInfo[FE->getUID()];
1174-
if (ExternalHFI.External)
1175-
mergeHeaderFileInfo(*HFI, ExternalHFI);
1171+
if (ExternalHFI.IsValid) {
1172+
HFI->Resolved = true;
1173+
if (ExternalHFI.External)
1174+
mergeHeaderFileInfo(*HFI, ExternalHFI);
1175+
}
11761176
}
11771177

11781178
HFI->IsValid = true;
@@ -1199,12 +1199,12 @@ HeaderSearch::getExistingFileInfo(const FileEntry *FE,
11991199
if (!WantExternal && (!HFI->IsValid || HFI->External))
12001200
return nullptr;
12011201
if (!HFI->Resolved) {
1202-
HFI->Resolved = true;
12031202
auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1204-
1205-
HFI = &FileInfo[FE->getUID()];
1206-
if (ExternalHFI.External)
1207-
mergeHeaderFileInfo(*HFI, ExternalHFI);
1203+
if (ExternalHFI.IsValid) {
1204+
HFI->Resolved = true;
1205+
if (ExternalHFI.External)
1206+
mergeHeaderFileInfo(*HFI, ExternalHFI);
1207+
}
12081208
}
12091209
} else if (FE->getUID() >= FileInfo.size()) {
12101210
return nullptr;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// No header guards on purpose.
2+
3+
enum SomeSimpleEnum {
4+
SomeSimpleEnumCase,
5+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
framework module ImportOnce {
2+
umbrella header "ImportOnce.h"
3+
export *
4+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#import <Unrelated/Unrelated.h>
2+
#import <ImportOnce/ImportOnce.h>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
framework module IndirectImporter {
2+
umbrella header "IndirectImporter.h"
3+
export *
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
void foo(void);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
framework module Unrelated {
2+
umbrella header "Unrelated.h"
3+
export *
4+
}

clang/test/Modules/import-once.m

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: rm -rf %t
2+
// RUN: %clang_cc1 -fmodules -fmodule-name=ImportOnce -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/import-once %s
3+
4+
// Test #import-ed headers are processed only once, even without header guards.
5+
// Dependency graph is
6+
//
7+
// Unrelated ImportOnce
8+
// ^ ^ ^
9+
// \ / |
10+
// IndirectImporter |
11+
// ^ |
12+
// \ |
13+
// import-once.m
14+
#import <IndirectImporter/IndirectImporter.h>
15+
#import <ImportOnce/ImportOnce.h>

0 commit comments

Comments
 (0)