aboutsummaryrefslogtreecommitdiff
path: root/gcc/input.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/input.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/input.c')
-rw-r--r--gcc/input.c86
1 files changed, 66 insertions, 20 deletions
diff --git a/gcc/input.c b/gcc/input.c
index 0c5f817..10cab77 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -1402,10 +1402,17 @@ get_substring_ranges_for_loc (cpp_reader *pfile,
return NULL;
}
-/* Attempt to populate *OUT_RANGE with source location information on the
- range of given characters within the string literal found at STRLOC.
- START_IDX and END_IDX refer to offsets within the execution character
- set.
+/* Attempt to populate *OUT_LOC with source location information on the
+ given characters within the string literal found at STRLOC.
+ CARET_IDX, START_IDX, and END_IDX refer to offsets within the execution
+ character set.
+
+ For example, given CARET_IDX = 4, START_IDX = 3, END_IDX = 7
+ and string literal "012345\n789"
+ *OUT_LOC is written to with:
+ "012345\n789"
+ ~^~~~~
+
If CONCATS is non-NULL, then any string literals that the token at
STRLOC was concatenated with are also considered.
@@ -1416,16 +1423,17 @@ get_substring_ranges_for_loc (cpp_reader *pfile,
than for end-users. */
const char *
-get_source_range_for_substring (cpp_reader *pfile,
- string_concat_db *concats,
- location_t strloc,
- enum cpp_ttype type,
- int start_idx, int end_idx,
- source_range *out_range)
-{
+get_source_location_for_substring (cpp_reader *pfile,
+ string_concat_db *concats,
+ location_t strloc,
+ enum cpp_ttype type,
+ int caret_idx, int start_idx, int end_idx,
+ source_location *out_loc)
+{
+ gcc_checking_assert (caret_idx >= 0);
gcc_checking_assert (start_idx >= 0);
gcc_checking_assert (end_idx >= 0);
- gcc_assert (out_range);
+ gcc_assert (out_loc);
cpp_substring_ranges ranges;
const char *err
@@ -1433,17 +1441,56 @@ get_source_range_for_substring (cpp_reader *pfile,
if (err)
return err;
+ if (caret_idx >= ranges.get_num_ranges ())
+ return "caret_idx out of range";
if (start_idx >= ranges.get_num_ranges ())
return "start_idx out of range";
if (end_idx >= ranges.get_num_ranges ())
return "end_idx out of range";
- out_range->m_start = ranges.get_range (start_idx).m_start;
- out_range->m_finish = ranges.get_range (end_idx).m_finish;
+ *out_loc = make_location (ranges.get_range (caret_idx).m_start,
+ ranges.get_range (start_idx).m_start,
+ ranges.get_range (end_idx).m_finish);
+ return NULL;
+}
+
+/* Attempt to populate *OUT_RANGE with source location information on the
+ given character within the string literal found at STRLOC.
+ CHAR_IDX refers to an offset within the execution character set.
+ If CONCATS is non-NULL, then any string literals that the token at
+ STRLOC was concatenated with are also considered.
+
+ This is implemented by re-parsing the relevant source line(s).
+
+ Return NULL if successful, or an error message if any errors occurred.
+ Error messages are intended for GCC developers (to help debugging) rather
+ than for end-users. */
+
+static const char *
+get_source_range_for_char (cpp_reader *pfile,
+ string_concat_db *concats,
+ location_t strloc,
+ enum cpp_ttype type,
+ int char_idx,
+ source_range *out_range)
+{
+ gcc_checking_assert (char_idx >= 0);
+ gcc_assert (out_range);
+
+ cpp_substring_ranges ranges;
+ const char *err
+ = get_substring_ranges_for_loc (pfile, concats, strloc, type, ranges);
+ if (err)
+ return err;
+
+ if (char_idx >= ranges.get_num_ranges ())
+ return "char_idx out of range";
+
+ *out_range = ranges.get_range (char_idx);
return NULL;
}
-/* As get_source_range_for_substring, but write to *OUT the number
+/* As get_source_range_for_char, but write to *OUT the number
of ranges that are available. */
const char *
@@ -1939,8 +1986,8 @@ assert_char_at_range (const location &loc,
source_range actual_range;
const char *err
- = get_source_range_for_substring (pfile, concats, strloc, type,
- idx, idx, &actual_range);
+ = get_source_range_for_char (pfile, concats, strloc, type, idx,
+ &actual_range);
if (should_have_column_data_p (strloc))
ASSERT_EQ_AT (loc, NULL, err);
else
@@ -2789,9 +2836,8 @@ test_lexer_string_locations_concatenation_2 (const line_table_case &case_)
this case. */
source_range actual_range;
const char *err
- = get_source_range_for_substring (test.m_parser, &test.m_concats,
- initial_loc, type, 0, 0,
- &actual_range);
+ = get_source_range_for_char (test.m_parser, &test.m_concats,
+ initial_loc, type, 0, &actual_range);
ASSERT_STREQ ("range starts after LINE_MAP_MAX_LOCATION_WITH_COLS", err);
return;
}