diff options
author | David Malcolm <dmalcolm@redhat.com> | 2016-08-08 22:50:47 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2016-08-08 22:50:47 +0000 |
commit | 895aa8e11319635104e6fa0dc1468fd6aec7b5b1 (patch) | |
tree | d1295b1b4e0a648f2f906e00b8e96ce05e031c74 /gcc/testsuite/gcc.dg | |
parent | b123572d819ffc4d3c250c7cbeb547fc351d4cf7 (diff) | |
download | gcc-895aa8e11319635104e6fa0dc1468fd6aec7b5b1.zip gcc-895aa8e11319635104e6fa0dc1468fd6aec7b5b1.tar.gz gcc-895aa8e11319635104e6fa0dc1468fd6aec7b5b1.tar.bz2 |
c-format.c: suggest the correct format string to use (PR c/64955)
This adds fix-it hints to c-format.c so that it can (sometimes) suggest
the format string the user should have used.
The patch adds selftests for the new code in c-format.c. These
selftests are thus lang-specific. This is the first time we've had
lang-specific selftests, and hence the patch also adds a langhook for
running them. (Note that currently the Makefile only invokes the
selftests for cc1).
gcc/c-family/ChangeLog:
PR c/64955
* c-common.h (selftest::c_format_c_tests): New declaration.
(selftest::run_c_tests): New declaration.
* c-format.c: Include "selftest.h.
(format_warning_va): Add param "corrected_substring" and use
it to add a replacement fix-it hint.
(format_warning_at_substring): Likewise.
(format_warning_at_char): Update for new param of
format_warning_va.
(argument_parser::check_argument_type): Pass "fki" to
check_format_types.
(check_format_types): Add param "fki" and pass it to
format_type_warning.
(deref_n_times): New function.
(get_modifier_for_format_len): New function.
(selftest::test_get_modifier_for_format_len): New function.
(get_format_for_type): New function.
(format_type_warning): Add param "fki" and use it to attempt
to provide hints for argument types when calling
format_warning_at_substring.
(selftest::get_info): New function.
(selftest::assert_format_for_type_streq): New function.
(ASSERT_FORMAT_FOR_TYPE_STREQ): New macro.
(selftest::test_get_format_for_type_printf): New function.
(selftest::test_get_format_for_type_scanf): New function.
(selftest::c_format_c_tests): New function.
gcc/c/ChangeLog:
PR c/64955
* c-lang.c (LANG_HOOKS_RUN_LANG_SELFTESTS): If CHECKING_P, wire
this up to selftest::run_c_tests.
(selftest::run_c_tests): New function.
gcc/ChangeLog:
PR c/64955
* langhooks-def.h (LANG_HOOKS_RUN_LANG_SELFTESTS): New default
do-nothing langhook.
(LANG_HOOKS_INITIALIZER): Add LANG_HOOKS_RUN_LANG_SELFTESTS.
* langhooks.h (struct lang_hooks): Add run_lang_selftests.
* selftest-run-tests.c: Include "tree.h" and "langhooks.h".
(selftest::run_tests): Call lang_hooks.run_lang_selftests.
gcc/testsuite/ChangeLog:
PR c/64955
* gcc.dg/format/diagnostic-ranges.c: Add fix-it hints to expected
output.
From-SVN: r239260
Diffstat (limited to 'gcc/testsuite/gcc.dg')
-rw-r--r-- | gcc/testsuite/gcc.dg/format/diagnostic-ranges.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/format/diagnostic-ranges.c b/gcc/testsuite/gcc.dg/format/diagnostic-ranges.c index 9e86b52..ff51833 100644 --- a/gcc/testsuite/gcc.dg/format/diagnostic-ranges.c +++ b/gcc/testsuite/gcc.dg/format/diagnostic-ranges.c @@ -12,6 +12,25 @@ void test_mismatching_types (const char *msg) /* { dg-begin-multiline-output "" } printf("hello %i", msg); ~^ + %s + { dg-end-multiline-output "" } */ + + + printf("hello %s", 42); /* { dg-warning "format '%s' expects argument of type 'char \\*', but argument 2 has type 'int'" } */ +/* TODO: ideally would also underline "42". */ +/* { dg-begin-multiline-output "" } + printf("hello %s", 42); + ~^ + %d + { dg-end-multiline-output "" } */ + + + printf("hello %i", (long)0); /* { dg-warning "format '%i' expects argument of type 'int', but argument 2 has type 'long int' " } */ +/* TODO: ideally would also underline the argument. */ +/* { dg-begin-multiline-output "" } + printf("hello %i", (long)0); + ~^ + %ld { dg-end-multiline-output "" } */ } @@ -23,6 +42,7 @@ void test_multiple_arguments (void) /* { dg-begin-multiline-output "" } printf ("arg0: %i arg1: %s arg 2: %i", ~^ + %d { dg-end-multiline-output "" } */ } @@ -33,6 +53,7 @@ void test_multiple_arguments_2 (int i, int j) /* { dg-begin-multiline-output "" } printf ("arg0: %i arg1: %s arg 2: %i", ~^ + %d 100, i + j, 102); ~~~~~ { dg-end-multiline-output "" } */ @@ -67,6 +88,7 @@ void test_hex (const char *msg) /* { dg-begin-multiline-output "" } printf("hello \x25\x69", msg); ~~~~~~~^ + %s { dg-end-multiline-output "" } */ } @@ -80,6 +102,7 @@ void test_oct (const char *msg) /* { dg-begin-multiline-output "" } printf("hello \045\151", msg); ~~~~~~~^ + %s { dg-end-multiline-output "" } */ } @@ -98,6 +121,7 @@ void test_multiple (const char *msg) /* { dg-begin-multiline-output "" } printf("prefix" "\x25" "\151" "suffix", ~~~~~~~~~~~^ + %s { dg-end-multiline-output "" } */ } @@ -108,6 +132,7 @@ void test_u8 (const char *msg) /* { dg-begin-multiline-output "" } printf(u8"hello %i", msg); ~^ + %s { dg-end-multiline-output "" } */ } @@ -117,6 +142,7 @@ void test_param (long long_i, long long_j) /* { dg-begin-multiline-output "" } printf ("foo %s bar", long_i + long_j); ~^ ~~~~~~~~~~~~~~~ + %ld { dg-end-multiline-output "" } */ } @@ -192,13 +218,14 @@ void test_macro (const char *msg) /* { dg-begin-multiline-output "" } #define INT_FMT "%i" ~^ + %s { dg-end-multiline-output "" } */ } void test_non_contiguous_strings (void) { __builtin_printf(" %" "d ", 0.5); /* { dg-warning "20: format .%d. expects argument of type .int., but argument 2 has type .double." } */ - /* { dg-message "26: format string is defined here" "" { target *-*-* } 200 } */ + /* { dg-message "26: format string is defined here" "" { target *-*-* } 227 } */ /* { dg-begin-multiline-output "" } __builtin_printf(" %" "d ", 0.5); ^~~~ @@ -206,6 +233,7 @@ void test_non_contiguous_strings (void) /* { dg-begin-multiline-output "" } __builtin_printf(" %" "d ", 0.5); ~~~~^ + %f { dg-end-multiline-output "" } */ } |