mirror of https://github.com/microsoft/clang.git
Modules: set SystemHeader to true if we are building a system module.
If we are processing a #include from a module build, we should treat it as a system header if we're building a system module. Passing an optional flag to HeaderSearch::LookupFile. Before this, the testing case will crash when accessing a freed FileEntry. rdar://26214027 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@269730 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
24f1d22d44
commit
c760a821c1
|
@ -381,7 +381,7 @@ public:
|
|||
ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
|
||||
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
|
||||
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
|
||||
bool SkipCache = false);
|
||||
bool SkipCache = false, bool BuildSystemModule = false);
|
||||
|
||||
/// \brief Look up a subframework for the specified \#include file.
|
||||
///
|
||||
|
|
|
@ -565,7 +565,7 @@ const FileEntry *HeaderSearch::LookupFile(
|
|||
ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
|
||||
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
|
||||
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
|
||||
bool SkipCache) {
|
||||
bool SkipCache, bool BuildSystemModule) {
|
||||
if (SuggestedModule)
|
||||
*SuggestedModule = ModuleMap::KnownHeader();
|
||||
|
||||
|
@ -613,11 +613,12 @@ const FileEntry *HeaderSearch::LookupFile(
|
|||
// getFileAndSuggestModule, because it's a reference to an element of
|
||||
// a container that could be reallocated across this call.
|
||||
//
|
||||
// FIXME: If we have no includer, that means we're processing a #include
|
||||
// If we have no includer, that means we're processing a #include
|
||||
// from a module build. We should treat this as a system header if we're
|
||||
// building a [system] module.
|
||||
bool IncluderIsSystemHeader =
|
||||
Includer && getFileInfo(Includer).DirInfo != SrcMgr::C_User;
|
||||
(Includer && getFileInfo(Includer).DirInfo != SrcMgr::C_User) ||
|
||||
(!Includer && BuildSystemModule);
|
||||
if (const FileEntry *FE = getFileAndSuggestModule(
|
||||
TmpDir, IncluderAndDir.second, IncluderIsSystemHeader,
|
||||
RequestingModule, SuggestedModule)) {
|
||||
|
|
|
@ -671,6 +671,7 @@ const FileEntry *Preprocessor::LookupFile(
|
|||
// stack, record the parent #includes.
|
||||
SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 16>
|
||||
Includers;
|
||||
bool BuildSystemModule = false;
|
||||
if (!FromDir && !FromFile) {
|
||||
FileID FID = getCurrentFileLexer()->getFileID();
|
||||
const FileEntry *FileEnt = SourceMgr.getFileEntryForID(FID);
|
||||
|
@ -688,9 +689,10 @@ const FileEntry *Preprocessor::LookupFile(
|
|||
// come from header declarations in the module map) relative to the module
|
||||
// map file.
|
||||
if (!FileEnt) {
|
||||
if (FID == SourceMgr.getMainFileID() && MainFileDir)
|
||||
if (FID == SourceMgr.getMainFileID() && MainFileDir) {
|
||||
Includers.push_back(std::make_pair(nullptr, MainFileDir));
|
||||
else if ((FileEnt =
|
||||
BuildSystemModule = getCurrentModule()->IsSystem;
|
||||
} else if ((FileEnt =
|
||||
SourceMgr.getFileEntryForID(SourceMgr.getMainFileID())))
|
||||
Includers.push_back(std::make_pair(FileEnt, FileMgr.getDirectory(".")));
|
||||
} else {
|
||||
|
@ -736,7 +738,8 @@ const FileEntry *Preprocessor::LookupFile(
|
|||
// Do a standard file entry lookup.
|
||||
const FileEntry *FE = HeaderInfo.LookupFile(
|
||||
Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath,
|
||||
RelativePath, RequestingModule, SuggestedModule, SkipCache);
|
||||
RelativePath, RequestingModule, SuggestedModule, SkipCache,
|
||||
BuildSystemModule);
|
||||
if (FE) {
|
||||
if (SuggestedModule && !LangOpts.AsmPreprocessor)
|
||||
HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
@import UseAfterFreePublic;
|
|
@ -0,0 +1,2 @@
|
|||
@interface S1
|
||||
@end
|
|
@ -0,0 +1,3 @@
|
|||
module UseAfterFreePublic {
|
||||
header "UseAfterFreePublic.h"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
module UseAfterFreePrivate {
|
||||
header "UseAfterFreePrivate.h"
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// RUN: rm -rf %t
|
||||
|
||||
// Here, we build the module without "non-modular-include-in-framework-module".
|
||||
// RUN: echo '@import UseAfterFreePublic;' | \
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \
|
||||
// RUN: -fmodules-cache-path=%t -isystem %S/Inputs/UseAfterFree/ -fsyntax-only \
|
||||
// RUN: -x objective-c -
|
||||
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \
|
||||
// RUN: -fmodules-cache-path=%t -isystem %S/Inputs/UseAfterFree/ -fsyntax-only \
|
||||
// RUN: -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module \
|
||||
// RUN: -x objective-c %s -verify
|
||||
// expected-no-diagnostics
|
||||
|
||||
// Here, we load the module UseAfterFreePublic, it is treated as a system module,
|
||||
// we ignore the inconsistency for "non-modular-include-in-framework-module".
|
||||
@import UseAfterFreePublic;
|
||||
|
||||
// We start a thread to build the module for UseAfterFreePrivate.h. In the thread,
|
||||
// we load UseAfterFreePublic and should treat it as a system module as well.
|
||||
// If not, we will invalidate UseAfterFreePublic because of the inconsistency
|
||||
// for "non-modular-include-in-framework-module", and have a use-after-free error
|
||||
// of the FileEntry.
|
||||
#import <UseAfterFreePrivate.h>
|
Loading…
Reference in New Issue