Commit 895aa8e1 by David Malcolm Committed by David Malcolm

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
parent b123572d
2016-08-08 David Malcolm <dmalcolm@redhat.com>
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.
2016-08-08 David Malcolm <dmalcolm@redhat.com>
PR bootstrap/72844
* input.c: Ensure that HAVE_ICONV is defined.
......
2016-08-08 David Malcolm <dmalcolm@redhat.com>
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.
2016-08-08 David Malcolm <dmalcolm@redhat.com>
PR c/52952
* c-format.c: Include "diagnostic.h".
(location_column_from_byte_offset): Delete.
......
......@@ -1533,4 +1533,11 @@ extern bool valid_array_size_p (location_t, tree, tree);
extern bool cilk_ignorable_spawn_rhs_op (tree);
extern bool cilk_recognize_spawn (tree, tree *);
#if CHECKING_P
namespace selftest {
extern void c_format_c_tests (void);
extern void run_c_tests (void);
} // namespace selftest
#endif /* #if CHECKING_P */
#endif /* ! GCC_C_COMMON_H */
2016-08-08 David Malcolm <dmalcolm@redhat.com>
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.
2016-08-04 Thomas Schwinge <thomas@codesourcery.com>
* c-parser.c (struct oacc_routine_data): Add error_seen and
......
......@@ -38,7 +38,29 @@ enum c_language_kind c_language = clk_c;
#undef LANG_HOOKS_INIT_TS
#define LANG_HOOKS_INIT_TS c_common_init_ts
#if CHECKING_P
#undef LANG_HOOKS_RUN_LANG_SELFTESTS
#define LANG_HOOKS_RUN_LANG_SELFTESTS selftest::run_c_tests
#endif /* #if CHECKING_P */
/* Each front end provides its own lang hook initializer. */
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
#if CHECKING_P
namespace selftest {
/* Implementation of LANG_HOOKS_RUN_LANG_SELFTESTS for the C frontend. */
void
run_c_tests (void)
{
c_format_c_tests ();
}
} // namespace selftest
#endif /* #if CHECKING_P */
#include "gtype-c.h"
......@@ -120,6 +120,7 @@ extern bool lhd_omp_mappable_type (tree);
#define LANG_HOOKS_BLOCK_MAY_FALLTHRU hook_bool_const_tree_true
#define LANG_HOOKS_EH_USE_CXA_END_CLEANUP false
#define LANG_HOOKS_DEEP_UNSHARING false
#define LANG_HOOKS_RUN_LANG_SELFTESTS lhd_do_nothing
/* Attribute hooks. */
#define LANG_HOOKS_ATTRIBUTE_TABLE NULL
......@@ -319,7 +320,8 @@ extern void lhd_end_section (void);
LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS, \
LANG_HOOKS_BLOCK_MAY_FALLTHRU, \
LANG_HOOKS_EH_USE_CXA_END_CLEANUP, \
LANG_HOOKS_DEEP_UNSHARING \
LANG_HOOKS_DEEP_UNSHARING, \
LANG_HOOKS_RUN_LANG_SELFTESTS \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
......@@ -505,6 +505,9 @@ struct lang_hooks
gimplification. */
bool deep_unsharing;
/* Run all lang-specific selftests. */
void (*run_lang_selftests) (void);
/* Whenever you add entries here, make sure you adjust langhooks-def.h
and langhooks.c accordingly. */
};
......
......@@ -21,6 +21,8 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "selftest.h"
#include "tree.h"
#include "langhooks.h"
/* This function needed to be split out from selftest.c as it references
tests from the whole source tree, and so is within
......@@ -70,6 +72,9 @@ selftest::run_tests ()
/* This one relies on most of the above. */
function_tests_c_tests ();
/* Run any lang-specific selftests. */
lang_hooks.run_lang_selftests ();
/* Finished running tests. */
long finish_time = get_run_time ();
long elapsed_time = finish_time - start_time;
......
2016-08-08 David Malcolm <dmalcolm@redhat.com>
PR c/64955
* gcc.dg/format/diagnostic-ranges.c: Add fix-it hints to expected
output.
2016-08-08 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
* gcc.dg/tree-ssa/pr71078-1.c: Add require-effective-target
......
......@@ -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 "" } */
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment