On 08/12/2016 01:27 PM, David Malcolm wrote:
In r239260 I attempted to add fix-it hints for -Wformat type
warnings.
Unfortunately, my implementation was too simplistic, and only
worked correctly for the most simple format strings: the fix-it
hint would suggest replacement of an entire conversion specification,
but the replacement would only include the length modifier (if
any) and the conversion character, thus effectively discarding
any user-supplied flags, width, or precision.
Additionally, the replacement failed to take into account the
user-specified conversion character, so that e.g. an "x" could
be replaced by a "d".
The following patch fixes these issues by:
(a) making the suggestion retain any user-supplied part of the
conversion specification before the length modifier, and
(b) attempt to preserve the user-specified conversion character, by
first considering replacements that only change the length
modifier.
It also expands the function comments in c-format.c, showing how
the functions work through a non-trivial example.
This patch is a followup to:
"[PATCH] Fix caret locations in format_type_warning (PR c/72857)"
https://gcc.gnu.org/ml/gcc-patches/2016-08/msg00867.html
Successfully bootstrapped®rtested on x86_64-pc-linux-gnu (on top
of the other patch).
OK for trunk?
gcc/c-family/ChangeLog:
PR c/72858
* c-format.c (argument_parser::check_argument_type): Add params
"type_start" and "conversion_char". Use the former to generate
offset_to_type_start and pass it and conversion_char to
check_format_types.
(check_format_info_main): Capture the start of the type
information as "type_start", and pass it an format_char
to arg_parser.check_argument_type.
(check_format_types): Provide an example in the leading comment.
Add params "offset_to_type_start" and "conversion_char"; pass
them to format_type_warning calls.
(test_get_modifier_for_format_len): Likewise.
(matching_type_p): New function.
(get_format_for_type): Add param "conversion_char" and move
implementation into...
(get_format_for_type_1): ...new function, called twice.
Use new function matching_type_p rather than checking for
TYPE_CANONICAL equality.
(get_corrected_substring): New function.
(format_type_warning): Provide an example in the leading comment.
Add params "offset_to_type_start" and "conversion_char". Replace
call to get_format_for_type with call to get_corrected_substring
and move rejection of hints for widths/precisions there.
(assert_format_for_type_streq): Add param "conversion_char".
(ASSERT_FORMAT_FOR_TYPE_STREQ): Add param CONVERSION_CHAR.
(test_get_format_for_type_printf): Add conversion chars to the
tests, adding coverage for various combinations of integer
vs double conversions, and for preserving octal and hexadecimal
conversions.
(test_get_format_for_type_scanf): Add conversion chars to the
tests.
gcc/testsuite/ChangeLog:
PR c/72858
* gcc.dg/format/diagnostic-ranges.c: Update expected suggestions
to preserve conversion chars, and to preserve prefix information.
* gcc.dg/format/pr72858.c: New test case.
OK.
jeff