Bug 77949 - [7 Regression] ICE on invalid code in internal compiler error: in linemap_position_for_loc_and_offset, at libcpp/line-map.c:907
Summary: [7 Regression] ICE on invalid code in internal compiler error: in linemap_pos...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: 7.0
Assignee: David Malcolm
URL:
Keywords: error-recovery, ice-on-invalid-code
Depends on:
Blocks:
 
Reported: 2016-10-12 09:23 UTC by Martin Liška
Modified: 2017-01-10 21:59 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2016-11-04 00:00:00


Attachments
Test-case (901 bytes, text/plain)
2016-10-12 09:24 UTC, Martin Liška
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Liška 2016-10-12 09:23:34 UTC
Following test-case was accidentally created as a secondary product of a test-case reduction. The code is very crappy, but causes an ICE:

$ g++ linemap-ice2.ii
...
linemap-ice2.ii:1:4063: error: expected ‘;’ at end of member declaration
linemap-ice2.ii:1:4095: internal compiler error: in linemap_position_for_loc_and_offset, at libcpp/line-map.c:907
 :const_iterator, bool>         result = cobject_info_set.insert(co);     return *(result.first); } inline void basic_oarchive_impl::save_object(     basic_oarchive & ar     const void *t     const basic_oserializer & bos ) inline void basic_oarchive_implsave_pointer }
                                                                                                                                                                                                                                                                            ^
0x1591bd3 linemap_position_for_loc_and_offset(line_maps*, unsigned int, unsigned int)
	../../libcpp/line-map.c:907
0x7922d9 cp_parser_class_specifier_1
	../../gcc/cp/parser.c:21810
0x794221 cp_parser_class_specifier
	../../gcc/cp/parser.c:21961
0x794221 cp_parser_type_specifier
	../../gcc/cp/parser.c:16102
0x7a82e9 cp_parser_decl_specifier_seq
	../../gcc/cp/parser.c:13019
0x7bc7b5 cp_parser_member_declaration
	../../gcc/cp/parser.c:22696
0x791c88 cp_parser_member_specification_opt
	../../gcc/cp/parser.c:22548
0x791c88 cp_parser_class_specifier_1
	../../gcc/cp/parser.c:21712
0x794221 cp_parser_class_specifier
	../../gcc/cp/parser.c:21961
0x794221 cp_parser_type_specifier
	../../gcc/cp/parser.c:16102
0x7a82e9 cp_parser_decl_specifier_seq
	../../gcc/cp/parser.c:13019
0x7b2691 cp_parser_simple_declaration
	../../gcc/cp/parser.c:12546
0x7b2ada cp_parser_block_declaration
	../../gcc/cp/parser.c:12493
0x7bacfe cp_parser_declaration
	../../gcc/cp/parser.c:12390
0x7bb156 cp_parser_declaration_seq_opt
	../../gcc/cp/parser.c:12266
0x7bb8d8 cp_parser_namespace_body
	../../gcc/cp/parser.c:17940
0x7bb8d8 cp_parser_namespace_definition
	../../gcc/cp/parser.c:17916
0x7bae17 cp_parser_declaration
	../../gcc/cp/parser.c:12374
0x7bb156 cp_parser_declaration_seq_opt
	../../gcc/cp/parser.c:12266
0x7bb488 cp_parser_translation_unit
	../../gcc/cp/parser.c:4360

Started to ICE with r238008.
Comment 1 Martin Liška 2016-10-12 09:24:09 UTC
Created attachment 39792 [details]
Test-case
Comment 2 Aldy Hernandez 2016-11-04 16:39:18 UTC
Confirmed.  I'll take a peek.
Comment 3 Aldy Hernandez 2016-11-04 19:22:21 UTC
Caused by:

commit b65b8df248d4eb4801cbe16287cf32eda9325dec
Author: dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Tue Jul 5 15:50:54 2016 +0000

    PR c++/62314: add fixit hint for "expected ';' after class definition"
    
    gcc/cp/ChangeLog:
        PR c++/62314
        * parser.c (cp_parser_class_specifier_1): When reporting
        missing semicolons, use a fixit-hint to suggest insertion
        of a semicolon immediately after the closing brace,
        offsetting the reported column accordingly.
    
    gcc/testsuite/ChangeLog:
        PR c++/62314
        * gcc/testsuite/g++.dg/parse/error5.C: Update column
        number of missing semicolon error.
        * g++.dg/pr62314-2.C: New test case.
    
    
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@238008 138bc75d-0d04-0410-96
1f-82ee72b054a4
Comment 4 David Malcolm 2017-01-10 21:54:41 UTC
Author: dmalcolm
Date: Tue Jan 10 21:54:09 2017
New Revision: 244292

URL: https://gcc.gnu.org/viewcvs?rev=244292&root=gcc&view=rev
Log:
Fix issues with unrepresentable column numbers (PR c++/77949)

PR c++/77949 identifies an ICE when the C++ frontend attempts to emit a
fix-it hint inserting a missing semicolon at column 4097 of a source file.

This column value exceeds LINE_MAP_MAX_COLUMN_NUMBER and hence isn't
representable using a location_t.

Attempting to do so leads to these problems, which this patch fixes:

(a) when encountering a column number > LINE_MAP_MAX_COLUMN_NUMBER we
create a new linemap with m_column_and_range_bits == 0, but
linemap_position_for_column doesn't check for this, and hence can emit
a bogus location_t value that's calculated relative to the previous
linemap start, but which will be decoded relative to the new linemap,
leading to very large incorrect line values.

(b) when encountering a column number that can't be represented, and
for which the linemap was pre-existing, the code would hit this assertion:
  if (linemap_assert_fails (column < (1u << map->m_column_and_range_bits)))
around a bail-out condition.  The patch replaces this assertion with a
simple conditional, to stop the ICE when this occurs, and fixes the
bit count (effective column bits, vs column+range bits)

(c) the C++ frontend wasn't checking for failure of
linemap_position_for_loc_and_offset when considering emitting the fix-it
hint.  The patch adds a conditional, so that no fix-it hint is emitted
if the location is bogus.

gcc/cp/ChangeLog:
	PR c++/77949
	* parser.c (cp_parser_class_specifier_1): Only suggest inserting
	a missing semicolon if we have a valid insertion location for
	the fix-it hint.

gcc/ChangeLog:
	PR c++/77949
	* input.c (selftest::test_accessing_ordinary_linemaps): Verify
	that we correctly handle column numbers greater than
	LINE_MAP_MAX_COLUMN_NUMBER.

gcc/testsuite/ChangeLog:
	PR c++/77949
	* g++.dg/diagnostic/pr77949.C: New test case.

libcpp/ChangeLog:
	PR c++/77949
	* line-map.c (linemap_position_for_column): When calling
	linemap_start_line, detect if a new linemap was created with
	0 column bits, and bail out early if this is the case.
	(linemap_position_for_loc_and_offset): Replace overzealous
	linemap_assert_fails with a simple conditional; use correct
	bit count.


Added:
    trunk/gcc/testsuite/g++.dg/diagnostic/pr77949.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
    trunk/gcc/input.c
    trunk/gcc/testsuite/ChangeLog
    trunk/libcpp/ChangeLog
    trunk/libcpp/line-map.c
Comment 5 David Malcolm 2017-01-10 21:59:31 UTC
Should be fixed by r244292; closing.