https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70693

--- Comment #10 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
Author: dmalcolm
Date: Thu Aug 16 17:07:15 2018
New Revision: 263595

URL: https://gcc.gnu.org/viewcvs?rev=263595&root=gcc&view=rev
Log:
-Wmisleading-indentation: fix ICE in get_visual_column (PR c++/70693)

PR c++/70693 reports a crash within -Wmisleading-indentation in
get_visual_column, reading past the end of a source line.

The issue occurs due to a stray carriage return aka '\r' aka ^M, occurring
towards the end of line 35 of attachment 38289 - but not at the end itself.

This carriage return confuses our line numbering: from that point in the
file, the lexer (and thus location_t values) use line numbers that are
one larger than those seen by input.c, "cat -n" and emacs.

This discrepancy between the lexer's line numbering and input.c's line
numbering leads to an out-of-range read in get_visual_column (trying to
read column 8, to locate the first non-whitespace on the line containing
"break;", but finding the next line, which is only 4 characters long).

This patch fixes the ICE by adding a range check to get_visual_column
before accessing the input.c line buffer.  This is arguably papering
over the root cause, but there are presumably other ways of triggering
such an out-of-range read by writing to the source file after the lexer
but before -Wmisleading-indentation, and we ought to be not ICE in the
face of that.

gcc/c-family/ChangeLog:
        PR c++/70693
        * c-common.c (selftest::c_family_tests): Call
        selftest::c_indentation_c_tests.
        * c-common.h (selftest::c_indentation_c_tests): New decl.
        * c-indentation.c: Include "selftest.h".
        (next_tab_stop): Add "tab_width" param, rather than accessing
        cpp_opts.
        (get_visual_column): Likewise.  Clarify comment.  Bulletproof
        against reading past the end of the line.
        (get_first_nws_vis_column): Add "tab_width" param.
        (detect_intervening_unindent): Likewise.
        (should_warn_for_misleading_indentation): Read tab width from
        cpp_opts and pass around.
        (selftest::test_next_tab_stop): New test.
        (selftest::assert_get_visual_column_succeeds): New function.
        (ASSERT_GET_VISUAL_COLUMN_SUCCEEDS): New macro.
        (selftest::assert_get_visual_column_fails): New function.
        (ASSERT_GET_VISUAL_COLUMN_FAILS): New macro.
        (selftest::test_get_visual_column): New test.
        (selftest::c_indentation_c_tests): New function.

gcc/testsuite/ChangeLog:
        PR c++/70693
        * c-c++-common/Wmisleading-indentation-pr70693.c: New test.


Added:
    trunk/gcc/testsuite/c-c++-common/Wmisleading-indentation-pr70693.c
Modified:
    trunk/gcc/c-family/ChangeLog
    trunk/gcc/c-family/c-common.c
    trunk/gcc/c-family/c-common.h
    trunk/gcc/c-family/c-indentation.c
    trunk/gcc/testsuite/ChangeLog

Reply via email to