PR c++/72803 describes an issue where a fix-it hint is to be emitted at column 512 of a 511-column source line, leading to an ICE. The root cause is a bug in linemap_line_start, when transitioning from lines >= 512 in width to narrow lines. The wide line in the reproducer has a line map with: m_column_and_range_bits = 15, m_range_bits = 5 giving 10 effective bits for representing columns, so that columns <= 1023 can be represented. When parsing the following line, linemap_line_start (..., ..., max_column_hint=0); is called. This leads to the "add_map" logic, due to this condition: || (max_column_hint <= 80 && effective_column_bits >= 10) i.e. the new line is sufficiently narrower than the old one to potentially use a new linemap (so as to conserve values within the location_t space). It then attempts to avoid allocating a new line map. Part of the logic to determine if we really need a new line map is this condition: SOURCE_COLUMN (map, highest) >= (1U << column_bits) The above condition is incorrect: we need to determine if the highest column we've handed out will fit within the proposed *effective* column bits, but "column_bits" here is the column plus the range bits, rather than just the column bits. Hence in this case linemap_line_start erroneously decides that we don't need a new line map, and updates the column bits within the existing line map, so any location_t values we've already handed out within it that are offset from the start by >= (1<<new_column_and_range_bits) effectively change meaning, leading to incorrect line&column information when decoding them, and various "interesting" ways for the linemap code to fail. The fix is to use the effective column bits in the above conditional. gcc/ChangeLog: PR c++/72803 * input.c (selftest::test_accessing_ordinary_linemaps): Verify that the transition from a max line width >= 1<<10 to narrower lines works correctly. gcc/testsuite/ChangeLog: PR c++/72803 * g++.dg/diagnostic/pr72803.C: New test case. libcpp/ChangeLog: PR c++/72803 * line-map.c (linemap_line_start): When determining if the highest column given out so far will fit into a proposed change to the current map, use the effective number of column bits, rather than the total number of column + range bits. From-SVN: r244199
Name |
Last commit
|
Last update |
---|---|---|
.. | ||
include | Loading commit data... | |
po | Loading commit data... | |
ChangeLog | Loading commit data... | |
ChangeLog.jit | Loading commit data... | |
Makefile.in | Loading commit data... | |
aclocal.m4 | Loading commit data... | |
charset.c | Loading commit data... | |
config.in | Loading commit data... | |
configure | Loading commit data... | |
configure.ac | Loading commit data... | |
directives-only.c | Loading commit data... | |
directives.c | Loading commit data... | |
errors.c | Loading commit data... | |
expr.c | Loading commit data... | |
files.c | Loading commit data... | |
identifiers.c | Loading commit data... | |
init.c | Loading commit data... | |
internal.h | Loading commit data... | |
lex.c | Loading commit data... | |
line-map.c | Loading commit data... | |
location-example.txt | Loading commit data... | |
macro.c | Loading commit data... | |
makeucnid.c | Loading commit data... | |
mkdeps.c | Loading commit data... | |
pch.c | Loading commit data... | |
symtab.c | Loading commit data... | |
system.h | Loading commit data... | |
traditional.c | Loading commit data... | |
ucnid.h | Loading commit data... | |
ucnid.tab | Loading commit data... |