[PATCH] D70183: Detect source location overflow due includes
Diogo N. Sampaio via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 13 07:49:22 PST 2019
dnsampaio created this revision.
dnsampaio added reviewers: rsmith, thakis, miyuki.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
dnsampaio marked an inline comment as done.
dnsampaio added inline comments.
================
Comment at: clang/lib/Basic/SourceManager.cpp:587
+ Diag.Report(IncludePos, diag::err_include_too_large);
+ exit(1);
+ }
----------------
For debug builds, I could not find any other way to not reach an assert failure other than exiting here. Perhaps there is a more llvm specific way to die? llvm_unreachable() ?
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.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D70183
Files:
clang/include/clang/Basic/DiagnosticCommonKinds.td
clang/lib/Basic/SourceManager.cpp
Index: clang/lib/Basic/SourceManager.cpp
===================================================================
--- clang/lib/Basic/SourceManager.cpp
+++ clang/lib/Basic/SourceManager.cpp
@@ -577,13 +577,18 @@
SLocEntryLoaded[Index] = true;
return FileID::get(LoadedID);
}
+ unsigned FileSize = File->getSize();
+ if (!(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
+ NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset)) {
+ // From this point, there is no sensible way to point to the current
+ // source-location and say: This include at line ### generates a too
+ // big file, as the IncludePos received is
+ Diag.Report(IncludePos, diag::err_include_too_large);
+ exit(1);
+ }
LocalSLocEntryTable.push_back(
SLocEntry::get(NextLocalOffset,
FileInfo::get(IncludePos, File, FileCharacter, Filename)));
- unsigned FileSize = File->getSize();
- assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
- NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
// We do a +1 here because we want a SourceLocation that means "the end of the
// file", e.g. for the "no newline at the end of the file" diagnostic.
NextLocalOffset += FileSize + 1;
Index: clang/include/clang/Basic/DiagnosticCommonKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -282,6 +282,10 @@
"file '%0' modified since it was first processed">, DefaultFatal;
def err_file_too_large : Error<
"sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_include_too_large : Error<
+ "sorry, this include generates a translation unit too large for"
+ " Clang to process. This may by a result from multiple"
+ " inclusions of unguarded header files.">;
def err_unsupported_bom : Error<"%0 byte order mark detected in '%1', but "
"encoding is not supported">, DefaultFatal;
def err_unable_to_rename_temp : Error<
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70183.229098.patch
Type: text/x-patch
Size: 2087 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191113/abd2495c/attachment.bin>
More information about the cfe-commits
mailing list