mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-07 13:40:55 +08:00
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
…
…
…
…
…
…
…
…
…
…
…
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
Languages
C++
31.9%
C
31.3%
Ada
12%
D
6.5%
Go
6.4%
Other
11.5%