Commit b5338fb3 by Martin Sebor Committed by Martin Sebor

PR middle-end/88226 - missing warning on fprintf, fputs, and puts with an unterminated array

gcc/ChangeLog:

	PR middle-end/88226
	* builtins.c (check_nul_terminated_array): New function.
	(fold_builtin_0): Remove declaration.
	(fold_builtin_1): Same.
	(fold_builtin_2): Same.
	(fold_builtin_3): Same.
	(fold_builtin_strpbrk): Add argument.
	(fold_builtin_strspn): Same.
	(fold_builtin_strcspn): Same.
	(expand_builtin_strcat): Call it.  Remove unused argument.
	(expand_builtin_stpncpy): Same.
	(expand_builtin_strncat): Same.
	(expand_builtin_strncpy): Same.  Adjust indentation.
	(expand_builtin_strcmp): Same.
	(expand_builtin_strncmp): Same.
	(expand_builtin_fork_or_exec): Same.
	(expand_builtin): Handle more built-ins.
	(fold_builtin_2): Add argument.
	(fold_builtin_n): Make static.  Add argument.
	(fold_call_expr): Pass new argument to fold_builtin_n and fold_builtin_2.
	(fold_builtin_call_array): Pass new argument to fold_builtin_n.
	(fold_builtin_strpbrk): Add argument.  Call check_nul_terminated_array.
	(fold_call_stmt): Pass new argument to fold_builtin_n.
	* builtins.h: Correct a comment.
	* gimple-fold.c (gimple_fold_builtin_strchr): Call
	check_nul_terminated_array.
	* tree-ssa-strlen.c (handle_builtin_strlen): Call
	check_nul_terminated_array.
	(handle_builtin_strchr): Same.
	(handle_builtin_string_cmp): Same.

gcc/testsuite/ChangeLog:

	PR middle-end/88226
	* gcc.dg/Wstringop-overflow-22.c: New test.
	* gcc.dg/tree-ssa/builtin-fprintf-warn-1.c: Remove xfails.

From-SVN: r278623
parent 86b0eb81
......@@ -8,6 +8,39 @@
2019-11-22 Martin Sebor <msebor@redhat.com>
PR middle-end/88226
* builtins.c (check_nul_terminated_array): New function.
(fold_builtin_0): Remove declaration.
(fold_builtin_1): Same.
(fold_builtin_2): Same.
(fold_builtin_3): Same.
(fold_builtin_strpbrk): Add argument.
(fold_builtin_strspn): Same.
(fold_builtin_strcspn): Same.
(expand_builtin_strcat): Call it. Remove unused argument.
(expand_builtin_stpncpy): Same.
(expand_builtin_strncat): Same.
(expand_builtin_strncpy): Same. Adjust indentation.
(expand_builtin_strcmp): Same.
(expand_builtin_strncmp): Same.
(expand_builtin_fork_or_exec): Same.
(expand_builtin): Handle more built-ins.
(fold_builtin_2): Add argument.
(fold_builtin_n): Make static. Add argument.
(fold_call_expr): Pass new argument to fold_builtin_n and fold_builtin_2.
(fold_builtin_call_array): Pass new argument to fold_builtin_n.
(fold_builtin_strpbrk): Add argument. Call check_nul_terminated_array.
(fold_call_stmt): Pass new argument to fold_builtin_n.
* builtins.h: Correct a comment.
* gimple-fold.c (gimple_fold_builtin_strchr): Call
check_nul_terminated_array.
* tree-ssa-strlen.c (handle_builtin_strlen): Call
check_nul_terminated_array.
(handle_builtin_strchr): Same.
(handle_builtin_string_cmp): Same.
2019-11-22 Martin Sebor <msebor@redhat.com>
PR tree-optimization/92501
* gimple-fold.c ((gimple_fold_builtin_string_compare): Let strncmp
handle unterminated arrays. Rename local variables for clarity.
......@@ -91,7 +91,7 @@ struct c_strlen_data
tree minlen;
tree maxlen;
tree maxbound;
/* When non-null, NONSTR refers to the declaration known to store
/* When non-null, DECL refers to the declaration known to store
an unterminated constant character array, as in:
const char s[] = { 'a', 'b', 'c' };
It is used to diagnose uses of such arrays in functions such as
......@@ -125,7 +125,6 @@ extern tree fold_builtin_expect (location_t, tree, tree, tree, tree);
extern bool avoid_folding_inline_builtin (tree);
extern tree fold_call_expr (location_t, tree, bool);
extern tree fold_builtin_call_array (location_t, tree, tree, int, tree *);
extern tree fold_builtin_n (location_t, tree, tree *, int, bool);
extern bool validate_gimple_arglist (const gcall *, ...);
extern rtx default_expand_builtin (tree, rtx, rtx, machine_mode, int);
extern bool fold_builtin_next_arg (tree, bool);
......@@ -148,6 +147,7 @@ extern bool target_char_cst_p (tree t, char *p);
extern internal_fn associated_internal_fn (tree);
extern internal_fn replacement_internal_fn (gcall *);
bool check_nul_terminated_array (tree, tree, tree = NULL_TREE);
extern void warn_string_no_nul (location_t, const char *, tree, tree);
extern tree unterminated_array (tree, tree * = NULL, bool * = NULL);
extern bool builtin_with_linkage_p (tree);
......
......@@ -1899,6 +1899,11 @@ gimple_fold_builtin_strchr (gimple_stmt_iterator *gsi, bool is_strrchr)
if (!gimple_call_lhs (stmt))
return false;
/* Avoid folding if the first argument is not a nul-terminated array.
Defer warning until later. */
if (!check_nul_terminated_array (NULL_TREE, str))
return false;
if ((p = c_getstr (str)) && target_char_cst_p (c, &ch))
{
const char *p1 = is_strrchr ? strrchr (p, ch) : strchr (p, ch);
......@@ -1973,18 +1978,23 @@ static bool
gimple_fold_builtin_strstr (gimple_stmt_iterator *gsi)
{
gimple *stmt = gsi_stmt (*gsi);
if (!gimple_call_lhs (stmt))
return false;
tree haystack = gimple_call_arg (stmt, 0);
tree needle = gimple_call_arg (stmt, 1);
const char *p, *q;
if (!gimple_call_lhs (stmt))
/* Avoid folding if either argument is not a nul-terminated array.
Defer warning until later. */
if (!check_nul_terminated_array (NULL_TREE, haystack)
|| !check_nul_terminated_array (NULL_TREE, needle))
return false;
q = c_getstr (needle);
const char *q = c_getstr (needle);
if (q == NULL)
return false;
if ((p = c_getstr (haystack)))
if (const char *p = c_getstr (haystack))
{
const char *r = strstr (p, q);
......
2019-11-22 Martin Sebor <msebor@redhat.com>
PR middle-end/88226
* gcc.dg/Wstringop-overflow-22.c: New test.
* gcc.dg/tree-ssa/builtin-fprintf-warn-1.c: Remove xfails.
2019-11-22 Martin Sebor <msebor@redhat.com>
PR tree-optimization/92501
* gcc.dg/strcmpopt_7.c: New test.
......
......@@ -84,8 +84,8 @@ void test_fprintf_s_const (int width)
if (nulptr)
T ("%s", nulptr);
T ("%s", &chr_no_nul); /* { dg-warning ".%s. directive argument is not a nul-terminated string" "pr88226" { xfail *-*-* } } */
T ("%s", arr_no_nul); /* { dg-warning ".%s. directive argument is not a nul-terminated string" "pr88226" { xfail *-*-* } } */
T ("%s", &chr_no_nul); /* { dg-warning ".%s. directive argument is not a nul-terminated string|argument missing terminating nul" } */
T ("%s", arr_no_nul); /* { dg-warning ".%s. directive argument is not a nul-terminated string|argument missing terminating nul" } */
/* Verify that output in excess of INT_MAX bytes is diagnosed even
when the size of the destination object is unknown. */
......@@ -117,7 +117,7 @@ void test_fprintf_ls_const (int width)
T ("%ls", nulptr);
T ("%ls", &wchr_no_nul); /* { dg-warning ".%ls. directive argument is not a nul-terminated string" } */
T ("%ls", warr_no_nul); /* { dg-warning ".%ls. directive argument is not a nul-terminated string" "pr88211" { xfail *-*-* } } */
T ("%ls", warr_no_nul); /* { dg-warning ".%ls. directive argument is not a nul-terminated string" "pr88226" { xfail *-*-* } } */
/* Verify that output in excess of INT_MAX bytes is diagnosed even
when the size of the destination object is unknown. */
......
......@@ -1946,8 +1946,6 @@ handle_builtin_strlen (gimple_stmt_iterator *gsi)
static void
handle_builtin_strchr (gimple_stmt_iterator *gsi)
{
int idx;
tree src;
gimple *stmt = gsi_stmt (*gsi);
tree lhs = gimple_call_lhs (stmt);
......@@ -1957,8 +1955,14 @@ handle_builtin_strchr (gimple_stmt_iterator *gsi)
if (!integer_zerop (gimple_call_arg (stmt, 1)))
return;
src = gimple_call_arg (stmt, 0);
idx = get_stridx (src);
tree src = gimple_call_arg (stmt, 0);
/* Avoid folding if the first argument is not a nul-terminated array.
Defer warning until later. */
if (!check_nul_terminated_array (NULL_TREE, src))
return;
int idx = get_stridx (src);
if (idx)
{
strinfo *si = NULL;
......@@ -3794,11 +3798,11 @@ handle_builtin_string_cmp (gimple_stmt_iterator *gsi)
/* For strncmp set to the the value of the third argument if known. */
HOST_WIDE_INT bound = -1;
tree len = NULL_TREE;
/* Extract the strncmp bound. */
if (gimple_call_num_args (stmt) == 3)
{
tree len = gimple_call_arg (stmt, 2);
len = gimple_call_arg (stmt, 2);
if (tree_fits_shwi_p (len))
bound = tree_to_shwi (len);
......@@ -3807,6 +3811,12 @@ handle_builtin_string_cmp (gimple_stmt_iterator *gsi)
return false;
}
/* Avoid folding if either argument is not a nul-terminated array.
Defer warning until later. */
if (!check_nul_terminated_array (NULL_TREE, arg1, len)
|| !check_nul_terminated_array (NULL_TREE, arg2, len))
return false;
{
/* Set to the length of one argument (or its complement if it's
the lower bound of a range) and the size of the array storing
......
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