c-ppoutput: Fix preprocessing ICE on very large line number [PR99325]
authorJakub Jelinek <jakub@redhat.com>
Thu, 4 Mar 2021 15:02:07 +0000 (16:02 +0100)
committerJakub Jelinek <jakub@redhat.com>
Thu, 4 Mar 2021 15:02:07 +0000 (16:02 +0100)
commita1b56c3ef70036af6d171d61ea48ad4c368fcb5b
tree0f00abfaabbe4e976247537c1413b7c1a6a65ea1
parenta6bc1680a493de356d6a381718021c6a44401201
c-ppoutput: Fix preprocessing ICE on very large line number [PR99325]

In libcpp, lines are represented as linenum_type, which is unsigned int.
The following testcases ICE because maybe_print_line_1 is sometimes called
with UNKNOWN_LOCATION (e.g. at pragma eof) and while most of the time
the
        && src_line >= print.src_line
        && src_line < print.src_line + 8
check doesn't succeed for the src_line of 0 from UNKNOWN_LOCATION, when
print.src_line is from very large line numbers (UINT_MAX - 7 and above)
it succeeds (with UB on the compiler side) but src_file is NULL for
UNKNOWN_LOCATION and so the strcmp call ICEs.
As print.src_line can easily wrap around, this patch changes its type
to unsigned int to match libcpp, so that we don't invoke UB in the compiler.
For print.src_line of UINT_MAX - 7 and above, src_line from UNKNOWN_LOCATION
will not pass that test anymore, but when it wraps around to 0, it can,
so I've also added a check for src_loc != UNKNOWN_LOCATION (or, if
preferred, could be src_file != NULL).
Besides fixing the ICE and UB in the compiler, I believe worst case the
patch will cause printing a few more line directives in the preprocessed
source around the wrapping from lines UINT_MAX - 7 to 0 (but less
around the wrapping from INT_MAX to INT_MAX + 1U), but I think those
are exceptional cases (sources with > 2billion lines are rare and
we warn or error on #line > INT_MAX).

2021-03-04  Jakub Jelinek  <jakub@redhat.com>

PR c/99325
* c-ppoutput.c (print): Change src_line type from int to unsigned.
(token_streamer::stream) Likewise.
(maybe_print_line_1): Likewise.  Don't strcmp src_file if src_loc is
UNKNOWN_LOCATION.

* gcc.dg/cpp/line11.c: New test.
* gcc.dg/cpp/line12.c: New test.
gcc/c-family/c-ppoutput.c
gcc/testsuite/gcc.dg/cpp/line11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/line12.c [new file with mode: 0644]