aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/c-format.c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2016-08-16 18:19:34 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2016-08-16 18:19:34 +0000
commit65e736c0efc463270764ea3012b9804c495c71bc (patch)
treef13ad9e3631ebbae2255d5fef36928ccaf345409 /gcc/c-family/c-format.c
parenteb3a5bcc74b063c05ceb78f8e0bfee3e03b021a6 (diff)
downloadgcc-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.c36
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;