diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 13580de7525..75ff1342713 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-02-20 David Malcolm + + 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. + 2019-02-20 Andre Vieira PR target/86487 diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c index ddc9421ce63..205ee56f409 100644 --- a/gcc/diagnostic-show-locus.c +++ b/gcc/diagnostic-show-locus.c @@ -1211,7 +1211,8 @@ layout::calculate_line_spans () const line_span *next = &tmp_spans[i]; gcc_assert (next->m_first_line >= current->m_first_line); const int merger_distance = m_show_line_numbers_p ? 1 : 0; - if (next->m_first_line <= current->m_last_line + 1 + merger_distance) + if ((linenum_arith_t)next->m_first_line + <= (linenum_arith_t)current->m_last_line + 1 + merger_distance) { /* We can merge them. */ if (next->m_last_line > current->m_last_line) @@ -2301,8 +2302,10 @@ diagnostic_show_locus (diagnostic_context * context, context->start_span (context, exploc); } } - linenum_type last_line = line_span->get_last_line (); - for (linenum_type row = line_span->get_first_line (); + /* Iterate over the lines within this span (using linenum_arith_t to + avoid overflow with 0xffffffff causing an infinite loop). */ + linenum_arith_t last_line = line_span->get_last_line (); + for (linenum_arith_t row = line_span->get_first_line (); row <= last_line; row++) layout.print_line (row); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7a407cdba20..9d344ba7c2d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-02-20 David Malcolm + + PR c/89410 + * gcc.dg/pr89410-1.c: New test. + * gcc.dg/pr89410-2.c: New test. + 2019-02-20 Pat Haugen * lib/target-supports.exp (check_effective_target_vect_usad_char): diff --git a/gcc/testsuite/gcc.dg/pr89410-1.c b/gcc/testsuite/gcc.dg/pr89410-1.c new file mode 100644 index 00000000000..73dc6d4de3f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr89410-1.c @@ -0,0 +1,9 @@ +/* { dg-options "" } */ + +int main(void) +{ + /* This is 0xffffffff. */ +#line 4294967295 +#warning msg + /* { dg-warning "msg" "" { target *-*-* } -1 } */ +} diff --git a/gcc/testsuite/gcc.dg/pr89410-2.c b/gcc/testsuite/gcc.dg/pr89410-2.c new file mode 100644 index 00000000000..76e781b09df --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr89410-2.c @@ -0,0 +1,13 @@ +/* { dg-options "-fdiagnostics-show-caret" } */ + +int main(void) +{ + /* This is 0x7fffffffffffffff, which truncates to 0xffffffff. */ +#line 9223372036854775807 /* { dg-warning "line number out of range" } */ +#warning msg + /* { dg-begin-multiline-output "" } + #line 9223372036854775807 + ^~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + /* { dg-warning "msg" "" { target *-*-* } -1 } */ +} diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index fa2fa7d97e8..355b4cb0f73 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,9 @@ +2019-02-20 David Malcolm + + PR c/89410 + * include/line-map.h (linenum_arith_t): New typedef. + (compare): Use it. + 2019-02-18 Martin Liska PR c++/89383 diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index a6eb87c2ec0..6c77c288855 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -49,13 +49,16 @@ along with this program; see the file COPYING3. If not see /* The type of line numbers. */ typedef unsigned int linenum_type; +/* A type for doing arithmetic on line numbers. */ +typedef long long linenum_arith_t; + /* A function for for use by qsort for comparing line numbers. */ inline int compare (linenum_type lhs, linenum_type rhs) { - /* Avoid truncation issues by using long long for the comparison, + /* Avoid truncation issues by using linenum_arith_t for the comparison, and only consider the sign of the result. */ - long long diff = (long long)lhs - (long long)rhs; + linenum_arith_t diff = (linenum_arith_t)lhs - (linenum_arith_t)rhs; if (diff) return diff > 0 ? 1 : -1; return 0;