diff options
author | David Malcolm <dmalcolm@redhat.com> | 2016-08-16 18:19:34 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2016-08-16 18:19:34 +0000 |
commit | 65e736c0efc463270764ea3012b9804c495c71bc (patch) | |
tree | f13ad9e3631ebbae2255d5fef36928ccaf345409 /gcc/c-family/c-format.c | |
parent | eb3a5bcc74b063c05ceb78f8e0bfee3e03b021a6 (diff) | |
download | gcc-65e736c0efc463270764ea3012b9804c495c71bc.zip gcc-65e736c0efc463270764ea3012b9804c495c71bc.tar.gz gcc-65e736c0efc463270764ea3012b9804c495c71bc.tar.bz2 |
Fix caret locations in format_type_warning (PR c/72857)
gcc/c-family/ChangeLog:
PR c/72857
* c-common.c (substring_loc::get_range): Rename to...
(substring_loc::get_location): ...this, converting param from a
source_range * to a location_t *. Call
get_source_location_for_substring rather than
get_source_range_for_substring, and pass in m_caret_idx.
* c-common.h (substring_loc::substring_loc): Add param "caret_idx".
(substring_loc::get_range): Replace with...
(substring_loc::get_location): ...this.
(substring_loc::set_caret_index): New method.
(substring_loc): Add field m_caret_idx.
* c-format.c (format_warning_va): Update for above changes.
Rename local "substring_loc" to "fmt_substring_loc" to avoid
clashing with type name.
(format_warning_at_char): Add caret_idx param to substring_loc ctor.
(check_argument_type): Likewise.
(format_type_warning): Rename param "fmt_loc" to "whole_fmt_loc"
Use a copy when emitting warnings, setting the caret index from TYPE.
gcc/ChangeLog:
PR c/72857
* input.c (get_source_range_for_substring): Rename to...
(get_source_location_for_substring): ...this, adding param
"caret_idx", and converting output param from source_range * to
location_t *.
(get_source_range_for_char): New function.
(get_num_source_ranges_for_substring): Update comment to reflect
above renaming.
(assert_char_at_range): Update to use get_source_range_for_char
rather than get_source_range_for_substring.
(test_lexer_string_locations_concatenation_2): Likewise.
* substring-locations.h (get_source_range_for_substring): Rename
to...
(get_source_location_for_substring): ...this, and adding param
"caret_idx", and converting output param from source_range * to
location_t *.
gcc/testsuite/ChangeLog:
PR c/72857
* gcc.dg/format/asm_fprintf-1.c: Restore column numbers
for embedded NUL.
* gcc.dg/format/c90-printf-1.c: Restore column numbers.
* gcc.dg/format/diagnostic-ranges.c (test_hex): Update expected
caret placement.
(test_oct): Likewise.
(test_multiple): Likewise.
(test_field_width_specifier): Likewise.
(test_field_width_specifier_2): New function.
(test_field_precision_specifier): New function.
(test_embedded_nul): Update expected caret placement.
(test_non_contiguous_strings): Update line number.
* gcc.dg/plugin/diagnostic-test-string-literals-1.c
(__emit_string_literal_range): Add "caret_idx" param.
(test_simple_string_literal): Add value for new param, updating
expected output..
(test_concatenated_string_literal): Likewise.
(test_multiline_string_literal): Likewise.
(test_hex): Likewise.
(test_oct): Likewise.
(test_multiple): Likewise.
(test_ucn4): Likewise.
(test_ucn8): Likewise.
(test_u8): Likewise.
(test_u): Likewise; update expected message, from "range" to
"location".
(test_U): Likewise.
(test_L): Likewise.
(test_macro): Add value for new param.
* gcc.dg/plugin/diagnostic-test-string-literals-2.c
(__emit_string_literal_range): Add "caret_idx" param.
(test_stringified_token_1): Add value for new param. Update
expected message, from "range" to "location".
(test_stringized_token_2): Likewise, adding param to macro.
(test_stringified_token_3): Likewise.
* gcc.dg/plugin/diagnostic_plugin_test_string_literals.c
(emit_warning): Convert param from source_range to location_t.
(test_string_literals): Add caret_idx param, and use it when
constructing a substring_loc. Update error message, from
"range" to "location".
From-SVN: r239510
Diffstat (limited to 'gcc/c-family/c-format.c')
-rw-r--r-- | gcc/c-family/c-format.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index 951ffd0..ad434f8 100644 --- a/gcc/c-family/c-format.c +++ b/gcc/c-family/c-format.c @@ -146,26 +146,23 @@ format_warning_va (const substring_loc &fmt_loc, source_range *param_range, { bool substring_within_range = false; location_t primary_loc; - location_t substring_loc = UNKNOWN_LOCATION; + location_t fmt_substring_loc = UNKNOWN_LOCATION; source_range fmt_loc_range = get_range_from_loc (line_table, fmt_loc.get_fmt_string_loc ()); - source_range fmt_substring_range; - const char *err = fmt_loc.get_range (&fmt_substring_range); + const char *err = fmt_loc.get_location (&fmt_substring_loc); + source_range fmt_substring_range + = get_range_from_loc (line_table, fmt_substring_loc); if (err) /* Case 3: unable to get substring location. */ primary_loc = fmt_loc.get_fmt_string_loc (); else { - substring_loc = make_location (fmt_substring_range.m_finish, - fmt_substring_range.m_start, - fmt_substring_range.m_finish); - if (fmt_substring_range.m_start >= fmt_loc_range.m_start && fmt_substring_range.m_finish <= fmt_loc_range.m_finish) /* Case 1. */ { substring_within_range = true; - primary_loc = substring_loc; + primary_loc = fmt_substring_loc; } else /* Case 2. */ @@ -193,11 +190,11 @@ format_warning_va (const substring_loc &fmt_loc, source_range *param_range, diagnostic.option_index = opt; bool warned = report_diagnostic (&diagnostic); - if (!err && substring_loc && !substring_within_range) + if (!err && fmt_substring_loc && !substring_within_range) /* Case 2. */ if (warned) { - rich_location substring_richloc (line_table, substring_loc); + rich_location substring_richloc (line_table, fmt_substring_loc); if (corrected_substring) substring_richloc.add_fixit_replace (fmt_substring_range, corrected_substring); @@ -247,7 +244,8 @@ format_warning_at_char (location_t fmt_string_loc, tree format_string_cst, be emitted. Fix it. */ char_idx -= 1; - substring_loc fmt_loc (fmt_string_loc, string_type, char_idx, char_idx); + substring_loc fmt_loc (fmt_string_loc, string_type, char_idx, char_idx, + char_idx); bool warned = format_warning_va (fmt_loc, NULL, NULL, opt, gmsgid, &ap); va_end (ap); @@ -2809,7 +2807,9 @@ check_argument_type (const format_char_info *fci, { ptrdiff_t offset_to_format_start = (start_of_this_format - 1) - orig_format_chars; ptrdiff_t offset_to_format_end = (format_chars - 1) - orig_format_chars; + /* By default, use the end of the range for the caret location. */ substring_loc fmt_loc (fmt_param_loc, TREE_TYPE (format_string_cst), + offset_to_format_end, offset_to_format_start, offset_to_format_end); check_format_types (fmt_loc, first_wanted_type, fki); } @@ -3262,8 +3262,10 @@ get_format_for_type (const format_kind_info *fki, tree arg_type) return NULL; } -/* Give a warning at FMT_LOC about a format argument of different type - from that expected. If non-NULL, PARAM_RANGE is the source range of the +/* Give a warning about a format argument of different type from that expected. + The range of the diagnostic is taken from WHOLE_FMT_LOC; the caret location + is based on the location of the char at TYPE->offset_loc. + If non-NULL, PARAM_RANGE is the source range of the relevant argument. WANTED_TYPE is the type the argument should have, possibly stripped of pointer dereferences. The description (such as "field precision"), the placement in the format string, a possibly more @@ -3271,7 +3273,7 @@ get_format_for_type (const format_kind_info *fki, tree arg_type) are taken from TYPE. ARG_TYPE is the type of the actual argument, or NULL if it is missing. */ static void -format_type_warning (const substring_loc &fmt_loc, +format_type_warning (const substring_loc &whole_fmt_loc, source_range *param_range, format_wanted_type *type, tree wanted_type, tree arg_type, @@ -3316,6 +3318,12 @@ format_type_warning (const substring_loc &fmt_loc, p[pointer_count + 1] = 0; } + /* WHOLE_FMT_LOC has the caret at the end of the range. + Set the caret to be at the offset from TYPE. Subtract one + from the offset for the same reason as in format_warning_at_char. */ + substring_loc fmt_loc (whole_fmt_loc); + fmt_loc.set_caret_index (type->offset_loc - 1); + /* Attempt to provide hints for argument types, but not for field widths and precisions. */ char *format_for_type = NULL; |