diff options
author | dodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-06 11:33:52 +0000 |
---|---|---|
committer | dodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-06 11:33:52 +0000 |
commit | fc3eff8854861fcd70d33d26095b17fe456fae31 (patch) | |
tree | 9df93357bf3f4d53fa06f73941b2e247cae258ed /gcc/input.h | |
parent | 9c2292aa8ae664ec4302d3ecdb80099dc60d90a7 (diff) | |
download | gcc-fc3eff8854861fcd70d33d26095b17fe456fae31.tar.gz |
preprocessor/58580 - preprocessor goes OOM with warning for zero literals
In this problem report, the compiler is fed a (bogus) translation unit
in which some literals contain bytes whose value is zero. The
preprocessor detects that and proceeds to emit diagnostics for that
king of bogus literals. But then when the diagnostics machinery
re-reads the input file again to display the bogus literals with a
caret, it attempts to calculate the length of each of the lines it got
using fgets. The line length calculation is done using strlen. But
that doesn't work well when the content of the line can have several
zero bytes. The result is that the read_line never sees the end of
the line because strlen repeatedly reports that the line ends before
the end-of-line character; so read_line thinks its buffer for reading
the line is too small; it thus increases the buffer, leading to a huge
memory consumption, pain and disaster.
The patch below introduces a new get_line function that returns the
next line of a file and return the length of that line even if the
line contains zero bytes. That get_line function has been adapted
from the getline function from the GNU C Library because getline being
a GNU extension it is not necessarily supported on all platforms.
read_line is then modified to return the length of the line along with
the line itself, as the line can now contain zero bytes. Callers of
read_line are adjusted consequently.
diagnostic_show_locus() is modified to consider that a line can have
characters of value zero, and so just shows a white space when
instructed to display one of these characters.
gcc/ChangeLog:
* input.h (location_get_source_line): Take an additional line_size
parameter.
* input.c (get_line): New static function definition.
(read_line): Take an additional line_length output parameter to be
set to the size of the line. Use the new get_line function do the
actual line reading.
(location_get_source_line): Take an additional output line_len
parameter. Update the use of read_line to pass it the line_len
parameter.
* diagnostic.c (adjust_line): Take an additional input parameter
for the length of the line, rather than calculating it with
strlen.
(diagnostic_show_locus): Adjust the use of
location_get_source_line and adjust_line with respect to their new
signature. While displaying a line now, do not stop at the first
null byte. Rather, display the zero byte as a space and keep
going until we reach the size of the line.
gcc/testsuite/ChangeLog:
* c-c++-common/cpp/warning-zero-in-literals-1.c: New test file.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204453 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/input.h')
-rw-r--r-- | gcc/input.h | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/gcc/input.h b/gcc/input.h index 8fdc7b28d92..128e28cd942 100644 --- a/gcc/input.h +++ b/gcc/input.h @@ -37,7 +37,8 @@ extern char builtins_location_check[(BUILTINS_LOCATION < RESERVED_LOCATION_COUNT) ? 1 : -1]; extern expanded_location expand_location (source_location); -extern const char *location_get_source_line (expanded_location xloc); +extern const char *location_get_source_line (expanded_location xloc, + int *line_size); extern expanded_location expand_location_to_spelling_point (source_location); extern source_location expansion_point_location_if_in_system_header (source_location); |