Fix ICE with #line directive (PR c/89410)
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 20 Feb 2019 20:07:20 +0000 (20:07 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Wed, 20 Feb 2019 20:07:20 +0000 (20:07 +0000)
commit200a8e1a38d11c112a460e026663e8301b201d85
tree95cf9e2472514f059dbf50ec176a47c6b017d7ca
parentb054705ae6b841b297e621ac20e9023a671d33bd
Fix ICE with #line directive (PR c/89410)

PR c/89410 reports various issues with #line directives with very
large numbers; one of them is an ICE inside diagnostic-show-locus.c
when emitting a diagnostic at line 0xffffffff.

The issue is that the arithmetic in layout::calculate_line_spans to
determine if two line spans are sufficiently close to consolidate
was using the unsigned 32-bit linenum_type, which was overflowing
when comparing the line for the expanded location with those of
the location range (all on line 0xffffffff), leading to it
erroneously adding two spans for the same line, leading to an
assertion failure.

This patch fixes the ICE by generalizing the use of long long in
line-map.h's comparison function for linenum_type into a new
linenum_arith_t typedef, and using it here.

Doing so uncovered a second problem: the loop to print the lines
within the line_span for this case is infinite: looping from
0xfffffff upwards, overflowing to 0, and then never becoming
greater than 0xfffffff.  The patch fixes this by using linenum_arith_t
there also.

gcc/ChangeLog:
PR c/89410
* diagnostic-show-locus.c (layout::calculate_line_spans): Use
linenum_arith_t when determining if two adjacent line spans are
close enough to merge.
(diagnostic_show_locus): Use linenum_arith_t when iterating over
lines within each line_span.

gcc/testsuite/ChangeLog:
PR c/89410
* gcc.dg/pr89410-1.c: New test.
* gcc.dg/pr89410-2.c: New test.

libcpp/ChangeLog:
PR c/89410
* include/line-map.h (linenum_arith_t): New typedef.
(compare): Use it.

From-SVN: r269050
gcc/ChangeLog
gcc/diagnostic-show-locus.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr89410-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr89410-2.c [new file with mode: 0644]
libcpp/ChangeLog
libcpp/include/line-map.h