David Malcolm 082284da9d Fix ICE for missing header fix-it hints with overlarge #line directives (PR c/84852)
PR c/84852 reports an ICE inside diagnostic_show_locus when printing
a diagnostic for a source file with a #line >= 2^31:

  #line 7777777777
  int foo (void) { return strlen(""); }

where we're attempting to print a fix-it hint at the top of the file
and underline the "strlen" (two "line spans").

The
  #line 7777777777
won't fix within the 32-bit linenum_type, and is truncated from
  0x1cf977871
to
   0xcf977871
i.e. 3482810481 in decimal.

Such a #line is reported by -pedantic and -pedantic-errors, but we
shouldn't ICE.

The ICE is an assertion failure within layout::calculate_line_spans,
where the line spans have not been properly sorted.

The layout_ranges are stored as int, rather than linenum_type,
giving line -812156815 for the error, and line 1 for the fix-it hint.

However, line_span uses linenum_type rather than int.

line_span::comparator compares these values as int, and hence
decides that (linenum_type)3482810481 aka (int)-812156815 is less
than line 1.

This leads to this assertion failing in layout::calculate_line_spans:

1105	      gcc_assert (next->m_first_line >= current->m_first_line);

since it isn't the case that 1 >= 3482810481.

The underlying problem is the mix of types for storing line numbers:
in parts of libcpp and diagnostic-show-locus.c we use linenum_type;
in other places (including libcpp's expanded_location) we use int.

I looked at using linenum_type throughout, but doing so turned into
a large patch, so this patch fixes the ICE in a less invasive way
by merely using linenum_type more consistently just within
diagnostic-show-locus.c, and fixing line_span::comparator to properly
handle line numbers (and line number differences) >= 2^31, by using
a new helper function for linenum_type differences, computing the
difference using long long, and using the sign of the difference
(as the difference might not fit in the "int" return type imposed
by qsort).

gcc/ChangeLog:
	PR c/84852
	* diagnostic-show-locus.c (class layout_point): Convert m_line
	from int to linenum_type.
	(line_span::comparator): Use linenum "compare" function when
	comparing line numbers.
	(test_line_span): New function.
	(layout_range::contains_point): Convert param "row" from int to
	linenum_type.
	(layout_range::intersects_line_p): Likewise.
	(layout::will_show_line_p): Likewise.
	(layout::print_source_line): Likewise.
	(layout::should_print_annotation_line_p): Likewise.
	(layout::print_annotation_line): Likewise.
	(layout::print_leading_fixits): Likewise.
	(layout::annotation_line_showed_range_p): Likewise.
	(struct line_corrections): Likewise for field m_row.
	(line_corrections::line_corrections): Likewise for param "row".
	(layout::print_trailing_fixits): Likewise.
	(layout::get_state_at_point): Likewise.
	(layout::get_x_bound_for_row): Likewise.
	(layout::print_line): Likewise.
	(diagnostic_show_locus): Likewise for locals "last_line" and
	"row".
	(selftest::diagnostic_show_locus_c_tests): Call test_line_span.
	* input.c (selftest::test_linenum_comparisons): New function.
	(selftest::input_c_tests): Call it.
	* selftest.c (selftest::test_assertions): Test ASSERT_GT,
	ASSERT_GT_AT, ASSERT_LT, and ASSERT_LT_AT.
	* selftest.h (ASSERT_GT): New macro.
	(ASSERT_GT_AT): New macro.
	(ASSERT_LT): New macro.
	(ASSERT_LT_AT): New macro.

gcc/testsuite/ChangeLog:
	PR c/84852
	* gcc.dg/fixits-pr84852-1.c: New test.
	* gcc.dg/fixits-pr84852-2.c: New test.

libcpp/ChangeLog:
	* include/line-map.h (compare): New function on linenum_type.

From-SVN: r258526
2018-03-14 13:58:13 +00:00
2018-03-02 17:35:26 +01:00
2018-01-03 11:03:58 +01:00
2018-01-03 11:03:58 +01:00
2018-01-03 11:03:58 +01:00
2018-01-03 11:03:58 +01:00
2018-01-03 11:03:58 +01:00
2018-01-03 11:03:58 +01:00
2017-11-28 11:35:37 +01:00
2017-11-28 11:35:37 +01:00
2017-10-27 13:13:05 +00:00

This directory contains the GNU Compiler Collection (GCC).

The GNU Compiler Collection is free software.  See the files whose
names start with COPYING for copying permission.  The manuals, and
some of the runtime libraries, are under different terms; see the
individual source files for details.

The directory INSTALL contains copies of the installation information
as HTML and plain text.  The source of this information is
gcc/doc/install.texi.  The installation information includes details
of what is included in the GCC sources and what files GCC installs.

See the file gcc/doc/gcc.texi (together with other files that it
includes) for usage and porting information.  An online readable
version of the manual is in the files gcc/doc/gcc.info*.

See http://gcc.gnu.org/bugs/ for how to report bugs usefully.

Copyright years on GCC source files may be listed using range
notation, e.g., 1987-2012, indicating that every year in the range,
inclusive, is a copyrightable year that could otherwise be listed
individually.
Description
No description provided
Readme 2.1 GiB
Languages
C++ 31.9%
C 31.3%
Ada 12%
D 6.5%
Go 6.4%
Other 11.5%