[Bug c++/72803] [7 Regression] ICE on invalid code in linemap_position_for_loc_and_offset, at libcpp/line-map.c:891
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72803 Martin Liška changed: What|Removed |Added Keywords||ice-on-invalid-code CC||dmalcolm at gcc dot gnu.org Target Milestone|--- |7.0
[Bug c++/72803] [7 Regression] ICE on invalid code in linemap_position_for_loc_and_offset, at libcpp/line-map.c:891
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72803 David Malcolm changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |dmalcolm at gcc dot gnu.org --- Comment #7 from David Malcolm --- (In reply to Aldy Hernandez from comment #6) [...] > That should still be line 1 and column 511. Why is it line 4 and column > 127? Something smells fishy. Something is going wrong with the linemaps. I'm investigating.
[Bug c++/72803] [7 Regression] ICE on invalid code in linemap_position_for_loc_and_offset, at libcpp/line-map.c:891
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72803 --- Comment #8 from David Malcolm --- Author: dmalcolm Date: Sat Jan 7 21:33:59 2017 New Revision: 244199 URL: https://gcc.gnu.org/viewcvs?rev=244199&root=gcc&view=rev Log: Fix linemap corruption after very wide source lines (PR c++/72803) 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<= 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. Added: trunk/gcc/testsuite/g++.dg/diagnostic/pr72803.C Modified: trunk/gcc/ChangeLog trunk/gcc/input.c trunk/gcc/testsuite/ChangeLog trunk/libcpp/ChangeLog trunk/libcpp/line-map.c
[Bug c++/72803] [7 Regression] ICE on invalid code in linemap_position_for_loc_and_offset, at libcpp/line-map.c:891
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72803 David Malcolm changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --- Comment #9 from David Malcolm --- Should be fixed on trunk; marking as resolved.
[Bug c++/72803] [7 Regression] ICE on invalid code in linemap_position_for_loc_and_offset, at libcpp/line-map.c:891
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72803 Aldy Hernandez changed: What|Removed |Added Status|UNCONFIRMED |WAITING Last reconfirmed||2016-11-04 CC||aldyh at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Aldy Hernandez --- I cannot reproduce on mainline. I just get a compile error, not an ICE: reynosa:/build/t$ cat /tmp/a.cc template class basic_string { typedef typename __gnu_cxx__alloc_traitstemplate rebindother _Char_alloc_typepublic static const int npos = static_cast private template class num_get public localefacettemplate localeid num_putid;;;;;; ;;;;;;; } # 1 "" 1 reynosa:/build/t$ ./install/bin/g++ -c /tmp/a.cc /tmp/a.cc:1:63: error: expected nested-name-specifier before ‘__gnu_cxx__alloc_traitstemplate’ template class basic_string { typedef typename __gnu_cxx__alloc_traitstemplate rebindother _Char_alloc_typepublic static const int npos = static_cast private template class num_get public localefacettemplate localeid num_putid;;;;;; ;;;;;;; } etc etc etc Is this still reproducible on mainline, or can we close it?
[Bug c++/72803] [7 Regression] ICE on invalid code in linemap_position_for_loc_and_offset, at libcpp/line-map.c:891
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72803 --- Comment #2 from Aldy Hernandez --- This looks like a duplicate of pr77949, but I cannot confirm since I can't reproduce it. Since this looks like it could be white space or column sensitive, could the reporter please include the testcase as an attachment, as opposed to cut and pasted onto the bug report? Thanks.
[Bug c++/72803] [7 Regression] ICE on invalid code in linemap_position_for_loc_and_offset, at libcpp/line-map.c:891
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72803 --- Comment #3 from Martin Liška --- Created attachment 39977 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39977&action=edit Test-case
[Bug c++/72803] [7 Regression] ICE on invalid code in linemap_position_for_loc_and_offset, at libcpp/line-map.c:891
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72803 Martin Liška changed: What|Removed |Added Status|WAITING |NEW --- Comment #4 from Martin Liška --- (In reply to Aldy Hernandez from comment #2) > This looks like a duplicate of pr77949, but I cannot confirm since I can't > reproduce it. Since this looks like it could be white space or column > sensitive, could the reporter please include the testcase as an attachment, > as opposed to cut and pasted onto the bug report? Thanks. I've attached the test-case. I guess it would be duplicate as it begins with the same revision.
[Bug c++/72803] [7 Regression] ICE on invalid code in linemap_position_for_loc_and_offset, at libcpp/line-map.c:891
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72803 --- Comment #5 from Aldy Hernandez --- Confirmed with the attachment. Thanks. Let's leave this open for now, as the ICE occurs in a different place than PR77949. It could be another unrelated bug caused by the same patch. Though it seems like this is a better place to start, since the testcase is considerable shorter.
[Bug c++/72803] [7 Regression] ICE on invalid code in linemap_position_for_loc_and_offset, at libcpp/line-map.c:891
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72803 --- Comment #6 from Aldy Hernandez --- In cp_lexer_new_main() we read all the tokens from the preprocessor: /* Get the remaining tokens from the preprocessor. */ while (token.type != CPP_EOF) { cp_lexer_get_preprocessor_token (lexer, &token); vec_safe_push (lexer->buffer, token); } The next to last token we push onto lexer->buffer is the closing brace in the testcase: (gdb) p token $252 = {type = CPP_CLOSE_BRACE, keyword = RID_MAX, flags = 1 '\001', implicit_extern_c = 0, error_reported = 0, purged_p = 0, location = 258432, u = { tree_check_value = 0x0, value = }} (gdb) p token.location $253 = 258432 (gdb) call expand_location($253) $254 = {file = 0x7fffe774 "b.ii", line = 1, column = 511, data = 0x0, sysp = false} However, the next token is the CPP_EOF, and calling expand_location() again on the CPP_CLOSE_BRACE token has the line and column offset completely incorrect: // Read the next token, which is CPP_EOF (gdb) next (gdb) p token $255 = {type = CPP_EOF, keyword = RID_MAX, flags = 64 '@', implicit_extern_c = 0, error_reported = 0, purged_p = 0, location = 258496, u = {tree_check_value = 0x0, value = }} // Look at the closing brace token again: (gdb) call expand_location($253) $256 = {file = 0x7fffe774 "b.ii", line = 4, column = 127, data = 0x0, sysp = false} (gdb) That should still be line 1 and column 511. Why is it line 4 and column 127? Something smells fishy.