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&regrtested 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

Reply via email to