summaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authordmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-12 17:37:48 +0000
committerdmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-12 17:37:48 +0000
commit48abd10111bf5bd0bc23dca6b29186ed7ff752c8 (patch)
treea32a794c4f95428a405af91cfcb1f30cff277778 /libcpp
parentb35d5d073f2be47650eabe8b0972f17d8f0daeb6 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--libcpp/lex.c7
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)