Skip to content

Commit f0c3870

Browse files
authored
[Modules] [HeaderSearch] Don't reenter headers if it is pragma once (#76119)
Close #73023 The direct issue of #73023 is that we entered a header which is marked as pragma once since the compiler think it is OK if there is controlling macro. It doesn't make sense. I feel like it should be sufficient to skip it after we see the '#pragma once'. From the context, it looks like the workaround is primarily for ObjectiveC. So we might need reviewers from OC.
1 parent ecde13b commit f0c3870

File tree

2 files changed

+58
-39
lines changed

2 files changed

+58
-39
lines changed

clang/lib/Lex/HeaderSearch.cpp

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,57 +1408,57 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
14081408
// Get information about this file.
14091409
HeaderFileInfo &FileInfo = getFileInfo(File);
14101410

1411-
// FIXME: this is a workaround for the lack of proper modules-aware support
1412-
// for #import / #pragma once
1413-
auto TryEnterImported = [&]() -> bool {
1414-
if (!ModulesEnabled)
1415-
return false;
1416-
// Ensure FileInfo bits are up to date.
1417-
ModMap.resolveHeaderDirectives(File);
1418-
// Modules with builtins are special; multiple modules use builtins as
1419-
// modular headers, example:
1420-
//
1421-
// module stddef { header "stddef.h" export * }
1422-
//
1423-
// After module map parsing, this expands to:
1424-
//
1425-
// module stddef {
1426-
// header "/path_to_builtin_dirs/stddef.h"
1427-
// textual "stddef.h"
1428-
// }
1429-
//
1430-
// It's common that libc++ and system modules will both define such
1431-
// submodules. Make sure cached results for a builtin header won't
1432-
// prevent other builtin modules from potentially entering the builtin
1433-
// header. Note that builtins are header guarded and the decision to
1434-
// actually enter them is postponed to the controlling macros logic below.
1435-
bool TryEnterHdr = false;
1436-
if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
1437-
TryEnterHdr = ModMap.isBuiltinHeader(File);
1438-
1439-
// Textual headers can be #imported from different modules. Since ObjC
1440-
// headers find in the wild might rely only on #import and do not contain
1441-
// controlling macros, be conservative and only try to enter textual headers
1442-
// if such macro is present.
1443-
if (!FileInfo.isModuleHeader &&
1444-
FileInfo.getControllingMacro(ExternalLookup))
1445-
TryEnterHdr = true;
1446-
return TryEnterHdr;
1447-
};
1448-
14491411
// If this is a #import directive, check that we have not already imported
14501412
// this header.
14511413
if (isImport) {
14521414
// If this has already been imported, don't import it again.
14531415
FileInfo.isImport = true;
14541416

1417+
// FIXME: this is a workaround for the lack of proper modules-aware support
1418+
// for #import / #pragma once
1419+
auto TryEnterImported = [&]() -> bool {
1420+
if (!ModulesEnabled)
1421+
return false;
1422+
// Ensure FileInfo bits are up to date.
1423+
ModMap.resolveHeaderDirectives(File);
1424+
// Modules with builtins are special; multiple modules use builtins as
1425+
// modular headers, example:
1426+
//
1427+
// module stddef { header "stddef.h" export * }
1428+
//
1429+
// After module map parsing, this expands to:
1430+
//
1431+
// module stddef {
1432+
// header "/path_to_builtin_dirs/stddef.h"
1433+
// textual "stddef.h"
1434+
// }
1435+
//
1436+
// It's common that libc++ and system modules will both define such
1437+
// submodules. Make sure cached results for a builtin header won't
1438+
// prevent other builtin modules from potentially entering the builtin
1439+
// header. Note that builtins are header guarded and the decision to
1440+
// actually enter them is postponed to the controlling macros logic below.
1441+
bool TryEnterHdr = false;
1442+
if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
1443+
TryEnterHdr = ModMap.isBuiltinHeader(File);
1444+
1445+
// Textual headers can be #imported from different modules. Since ObjC
1446+
// headers find in the wild might rely only on #import and do not contain
1447+
// controlling macros, be conservative and only try to enter textual
1448+
// headers if such macro is present.
1449+
if (!FileInfo.isModuleHeader &&
1450+
FileInfo.getControllingMacro(ExternalLookup))
1451+
TryEnterHdr = true;
1452+
return TryEnterHdr;
1453+
};
1454+
14551455
// Has this already been #import'ed or #include'd?
14561456
if (PP.alreadyIncluded(File) && !TryEnterImported())
14571457
return false;
14581458
} else {
14591459
// Otherwise, if this is a #include of a file that was previously #import'd
14601460
// or if this is the second #include of a #pragma once file, ignore it.
1461-
if ((FileInfo.isPragmaOnce || FileInfo.isImport) && !TryEnterImported())
1461+
if (FileInfo.isPragmaOnce || FileInfo.isImport)
14621462
return false;
14631463
}
14641464

clang/test/Modules/pr73023.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: split-file %s %t
4+
//
5+
// RUN: %clang_cc1 -std=c++20 %t/test.cpp -fsyntax-only -verify
6+
7+
//--- i.h
8+
#ifndef I_H
9+
#pragma once
10+
struct S{};
11+
#endif
12+
13+
//--- test.cpp
14+
// expected-no-diagnostics
15+
#include "i.h"
16+
17+
int foo() {
18+
return sizeof(S);
19+
}

0 commit comments

Comments
 (0)