diff options
author | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-12-12 17:37:48 +0000 |
---|---|---|
committer | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-12-12 17:37:48 +0000 |
commit | 48abd10111bf5bd0bc23dca6b29186ed7ff752c8 (patch) | |
tree | a32a794c4f95428a405af91cfcb1f30cff277778 /libcpp | |
parent | b35d5d073f2be47650eabe8b0972f17d8f0daeb6 (diff) | |
download | gcc-48abd10111bf5bd0bc23dca6b29186ed7ff752c8.tar.gz |
Fix for PR preprocessor/78680
PR preprocessor/78680 identifies a crash when attempting to issue
a -Wformat warning, where the format string includes a string token
split across multiple physical source lines via backslash-continued
lines.
The issue is that libcpp is generating bogus range information for
such tokens.
For example, in:
void fn1() {
__builtin_printf("\
%ld.\n\
2\n"); };
the range of the string token is printed as:
__builtin_printf("\
^~
whereas the range ought to be:
__builtin_printf("\
^~
%ld.\n\
~~~~~~~
2\n"); };
~~~~
The root cause is that the line notes expressing the update
of the buffer in lex.c aren't yet updated when the end-point of
the token is computed
3095 tok_range.m_finish
3096 = linemap_position_for_column (pfile->line_table,
3097 CPP_BUF_COLUMN (buffer, buffer->cur));
so that the physical line is still regarded as that of the start
of the token, and, where CPP_BUF_COLUMN uses (BUF)->line_base,
line_base is still the location of the first physical line in the
and hence the column information is too large (as if it were the
offset in the *logical* line).
(the printed range is somewhat misleading; the actual buggy range
extends beyond the "\ in the line, but within diagnostic-show-locus.c
layout::print_annotation_line only prints up to the xbound set by
layout::print_source_line and so truncates most of the buggy range).
The fix is to ensure that line notes are handled before calculating
the end-point of the token range.
This leads to the range for the string token being correctly
computed, as:
__builtin_printf("\
^~
%ld.\n\
~~~~~~~
2\n"); };
~~~~
and this leads to get_substring_ranges_for_loc failing gracefully,
rather than crashing.
gcc/testsuite/ChangeLog:
PR preprocessor/78680
* gcc.dg/format/pr78680.c: New test case.
* gcc.dg/plugin/diagnostic-test-expressions-1.c
(test_multiline_token): New function.
* gcc.dg/plugin/diagnostic-test-string-literals-1.c
(test_backslash_continued_logical_lines): New function.
libcpp/ChangeLog:
PR preprocessor/78680
* lex.c (_cpp_lex_direct): Ensure line notes are processed before
computing the end-point of the token.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@243567 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp')
-rw-r--r-- | libcpp/ChangeLog | 6 | ||||
-rw-r--r-- | libcpp/lex.c | 7 |
2 files changed, 13 insertions, 0 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 1a7e737cd95..63681220187 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,9 @@ +2016-12-12 David Malcolm <dmalcolm@redhat.com> + + PR preprocessor/78680 + * lex.c (_cpp_lex_direct): Ensure line notes are processed before + computing the end-point of the token. + 2016-11-23 Paolo Bonzini <bonzini@gnu.org> * include/cpplib.h (struct cpp_options): Add new member diff --git a/libcpp/lex.c b/libcpp/lex.c index cea88488f36..ae458926b75 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -3089,6 +3089,13 @@ _cpp_lex_direct (cpp_reader *pfile) break; } + /* Ensure that any line notes are processed, so that we have the + correct physical line/column for the end-point of the token even + when a logical line is split via one or more backslashes. */ + if (buffer->cur >= buffer->notes[buffer->cur_note].pos + && !pfile->overlaid_buffer) + _cpp_process_line_notes (pfile, false); + source_range tok_range; tok_range.m_start = result->src_loc; if (result->src_loc >= RESERVED_LOCATION_COUNT) |