Skip to content

Commit bce360b

Browse files
author
Diogo Sampaio
committed
Detect source location overflow due includes
Summary: As discussed in http://lists.llvm.org/pipermail/cfe-dev/2019-October/063459.html the overflow of the souce locations (limited to 2^31 chars) can generate all sorts of weird things (bogus warnings, hangs, crashes, miscompilation and correct compilation). In debug mode this assert would fail. So it might be a good start, as in PR42301, to detect the failure and exit with a proper error message. Reviewers: rsmith, thakis, miyuki Reviewed By: miyuki Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D70183
1 parent ec62bf2 commit bce360b

File tree

8 files changed

+2528
-6
lines changed

8 files changed

+2528
-6
lines changed

clang/include/clang/Basic/DiagnosticCommonKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,9 @@ def err_file_modified : Error<
282282
"file '%0' modified since it was first processed">, DefaultFatal;
283283
def err_file_too_large : Error<
284284
"sorry, unsupported: file '%0' is too large for Clang to process">;
285+
def err_include_too_large : Error<
286+
"sorry, this include generates a translation unit too large for"
287+
" Clang to process.">, DefaultFatal;
285288
def err_unsupported_bom : Error<"%0 byte order mark detected in '%1', but "
286289
"encoding is not supported">, DefaultFatal;
287290
def err_unable_to_rename_temp : Error<

clang/include/clang/Lex/Preprocessor.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2203,12 +2203,14 @@ class Preprocessor {
22032203
ModuleBegin,
22042204
ModuleImport,
22052205
SkippedModuleImport,
2206+
Failure,
22062207
} Kind;
22072208
Module *ModuleForHeader = nullptr;
22082209

22092210
ImportAction(ActionKind AK, Module *Mod = nullptr)
22102211
: Kind(AK), ModuleForHeader(Mod) {
2211-
assert((AK == None || Mod) && "no module for module action");
2212+
assert((AK == None || Mod || AK == Failure) &&
2213+
"no module for module action");
22122214
}
22132215
};
22142216

clang/lib/Basic/SourceManager.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -577,13 +577,15 @@ FileID SourceManager::createFileID(const ContentCache *File, StringRef Filename,
577577
SLocEntryLoaded[Index] = true;
578578
return FileID::get(LoadedID);
579579
}
580+
unsigned FileSize = File->getSize();
581+
if (!(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
582+
NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset)) {
583+
Diag.Report(IncludePos, diag::err_include_too_large);
584+
return FileID();
585+
}
580586
LocalSLocEntryTable.push_back(
581587
SLocEntry::get(NextLocalOffset,
582588
FileInfo::get(IncludePos, File, FileCharacter, Filename)));
583-
unsigned FileSize = File->getSize();
584-
assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
585-
NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
586-
"Ran out of source locations!");
587589
// We do a +1 here because we want a SourceLocation that means "the end of the
588590
// file", e.g. for the "no newline at the end of the file" diagnostic.
589591
NextLocalOffset += FileSize + 1;

clang/lib/Lex/PPDirectives.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1708,6 +1708,13 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
17081708
EnterAnnotationToken(SourceRange(HashLoc, EndLoc),
17091709
tok::annot_module_include, Action.ModuleForHeader);
17101710
break;
1711+
case ImportAction::Failure:
1712+
assert(TheModuleLoader.HadFatalFailure &&
1713+
"This should be an early exit only to a fatal error");
1714+
TheModuleLoader.HadFatalFailure = true;
1715+
IncludeTok.setKind(tok::eof);
1716+
CurLexer->cutOffLexing();
1717+
return;
17111718
}
17121719
}
17131720

@@ -2165,7 +2172,10 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
21652172
if (IncludePos.isMacroID())
21662173
IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();
21672174
FileID FID = SourceMgr.createFileID(*File, IncludePos, FileCharacter);
2168-
assert(FID.isValid() && "Expected valid file ID");
2175+
if (!FID.isValid()) {
2176+
TheModuleLoader.HadFatalFailure = true;
2177+
return ImportAction::Failure;
2178+
}
21692179

21702180
// If all is good, enter the new file!
21712181
if (EnterSourceFile(FID, CurDir, FilenameTok.getLocation()))

clang/lib/Lex/Preprocessor.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,9 @@ void Preprocessor::Lex(Token &Result) {
906906
}
907907
} while (!ReturnedToken);
908908

909+
if (Result.is(tok::unknown) && TheModuleLoader.HadFatalFailure)
910+
return;
911+
909912
if (Result.is(tok::code_completion) && Result.getIdentifierInfo()) {
910913
// Remember the identifier before code completion token.
911914
setCodeCompletionIdentifierInfo(Result.getIdentifierInfo());
@@ -1200,6 +1203,13 @@ bool Preprocessor::LexAfterModuleImport(Token &Result) {
12001203
Suffix[0].setAnnotationValue(Action.ModuleForHeader);
12011204
// FIXME: Call the moduleImport callback?
12021205
break;
1206+
case ImportAction::Failure:
1207+
assert(TheModuleLoader.HadFatalFailure &&
1208+
"This should be an early exit only to a fatal error");
1209+
Result.setKind(tok::eof);
1210+
CurLexer->cutOffLexing();
1211+
EnterTokens(Suffix);
1212+
return true;
12031213
}
12041214

12051215
EnterTokens(Suffix);

0 commit comments

Comments
 (0)