Commit 79d2e614 by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/92691 (ICE in strlen_dom_walker::before_dom_children at…

re PR tree-optimization/92691 (ICE in strlen_dom_walker::before_dom_children at gcc/tree-ssa-strlen.c:5177 since r274933)

	PR tree-optimization/92691
	* tree-ssa-strlen.c (handle_store): Clarify return value meaning
	in function comment.
	(strlen_check_and_optimize_call): Likewise.  For handle_printf_call
	calls, return !handle_printf_call rather than always returning true.
	(check_and_optimize_stmt): Describe return value meaning in function
	comment.  Formatting fix.

	* gcc.dg/tree-ssa/builtin-snprintf-10.c: New test.

From-SVN: r278803
parent 99150b05
2019-11-28 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/92691
* tree-ssa-strlen.c (handle_store): Clarify return value meaning
in function comment.
(strlen_check_and_optimize_call): Likewise. For handle_printf_call
calls, return !handle_printf_call rather than always returning true.
(check_and_optimize_stmt): Describe return value meaning in function
comment. Formatting fix.
2019-11-28 Jan Hubicka <hubicka@ucw.cz> 2019-11-28 Jan Hubicka <hubicka@ucw.cz>
* profile-count.c (profile_count::to_sreal_scale): Handle correctly * profile-count.c (profile_count::to_sreal_scale): Handle correctly
2019-11-28 Jakub Jelinek <jakub@redhat.com> 2019-11-28 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/92691
* gcc.dg/tree-ssa/builtin-snprintf-10.c: New test.
PR c++/92695 PR c++/92695
* g++.dg/warn/inline3.C: New test. * g++.dg/warn/inline3.C: New test.
......
/* PR tree-optimization/92691 */
/* { dg-do compile } */
/* { dg-options "-O2" } */
void
foo (int x, char *y)
{
if (x != 0)
__builtin_snprintf (y, 0, "foo");
}
...@@ -4300,7 +4300,8 @@ count_nonzero_bytes (tree exp, unsigned lenrange[3], bool *nulterm, ...@@ -4300,7 +4300,8 @@ count_nonzero_bytes (tree exp, unsigned lenrange[3], bool *nulterm,
/* Handle a single or multibyte store other than by a built-in function, /* Handle a single or multibyte store other than by a built-in function,
either via a single character assignment or by multi-byte assignment either via a single character assignment or by multi-byte assignment
either via MEM_REF or via a type other than char (such as in either via MEM_REF or via a type other than char (such as in
'*(int*)a = 12345'). Return true when handled. */ '*(int*)a = 12345'). Return true to let the caller advance *GSI to
the next statement in the basic block and false otherwise. */
static bool static bool
handle_store (gimple_stmt_iterator *gsi, bool *zero_write, const vr_values *rvals) handle_store (gimple_stmt_iterator *gsi, bool *zero_write, const vr_values *rvals)
...@@ -4728,8 +4729,8 @@ is_char_type (tree type) ...@@ -4728,8 +4729,8 @@ is_char_type (tree type)
} }
/* Check the built-in call at GSI for validity and optimize it. /* Check the built-in call at GSI for validity and optimize it.
Return true to let the caller advance *GSI to the statement Return true to let the caller advance *GSI to the next statement
in the CFG and false otherwise. */ in the basic block and false otherwise. */
static bool static bool
strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, strlen_check_and_optimize_call (gimple_stmt_iterator *gsi,
...@@ -4738,16 +4739,13 @@ strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, ...@@ -4738,16 +4739,13 @@ strlen_check_and_optimize_call (gimple_stmt_iterator *gsi,
{ {
gimple *stmt = gsi_stmt (*gsi); gimple *stmt = gsi_stmt (*gsi);
/* When not optimizing we must be checking printf calls which
we do even for user-defined functions when they are declared
with attribute format. */
if (!flag_optimize_strlen if (!flag_optimize_strlen
|| !strlen_optimize || !strlen_optimize
|| !valid_builtin_call (stmt)) || !valid_builtin_call (stmt))
{ return !handle_printf_call (gsi, rvals);
/* When not optimizing we must be checking printf calls which
we do even for user-defined functions when they are declared
with attribute format. */
handle_printf_call (gsi, rvals);
return true;
}
tree callee = gimple_call_fndecl (stmt); tree callee = gimple_call_fndecl (stmt);
switch (DECL_FUNCTION_CODE (callee)) switch (DECL_FUNCTION_CODE (callee))
...@@ -4806,7 +4804,8 @@ strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, ...@@ -4806,7 +4804,8 @@ strlen_check_and_optimize_call (gimple_stmt_iterator *gsi,
return false; return false;
break; break;
default: default:
handle_printf_call (gsi, rvals); if (handle_printf_call (gsi, rvals))
return false;
break; break;
} }
...@@ -4932,7 +4931,8 @@ handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh) ...@@ -4932,7 +4931,8 @@ handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh)
/* Attempt to check for validity of the performed access a single statement /* Attempt to check for validity of the performed access a single statement
at *GSI using string length knowledge, and to optimize it. at *GSI using string length knowledge, and to optimize it.
If the given basic block needs clean-up of EH, CLEANUP_EH is set to If the given basic block needs clean-up of EH, CLEANUP_EH is set to
true. */ true. Return true to let the caller advance *GSI to the next statement
in the basic block and false otherwise. */
static bool static bool
check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh, check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh,
...@@ -4973,32 +4973,32 @@ check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh, ...@@ -4973,32 +4973,32 @@ check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh,
/* Handle assignment to a character. */ /* Handle assignment to a character. */
handle_integral_assign (gsi, cleanup_eh); handle_integral_assign (gsi, cleanup_eh);
else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs)) else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
{ {
tree type = TREE_TYPE (lhs); tree type = TREE_TYPE (lhs);
if (TREE_CODE (type) == ARRAY_TYPE) if (TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type); type = TREE_TYPE (type);
bool is_char_store = is_char_type (type); bool is_char_store = is_char_type (type);
if (!is_char_store && TREE_CODE (lhs) == MEM_REF) if (!is_char_store && TREE_CODE (lhs) == MEM_REF)
{ {
/* To consider stores into char objects via integer types /* To consider stores into char objects via integer types
other than char but not those to non-character objects, other than char but not those to non-character objects,
determine the type of the destination rather than just determine the type of the destination rather than just
the type of the access. */ the type of the access. */
tree ref = TREE_OPERAND (lhs, 0); tree ref = TREE_OPERAND (lhs, 0);
type = TREE_TYPE (ref); type = TREE_TYPE (ref);
if (TREE_CODE (type) == POINTER_TYPE) if (TREE_CODE (type) == POINTER_TYPE)
type = TREE_TYPE (type); type = TREE_TYPE (type);
if (TREE_CODE (type) == ARRAY_TYPE) if (TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type); type = TREE_TYPE (type);
if (is_char_type (type)) if (is_char_type (type))
is_char_store = true; is_char_store = true;
} }
/* Handle a single or multibyte assignment. */ /* Handle a single or multibyte assignment. */
if (is_char_store && !handle_store (gsi, &zero_write, rvals)) if (is_char_store && !handle_store (gsi, &zero_write, rvals))
return false; return false;
} }
} }
else if (gcond *cond = dyn_cast<gcond *> (stmt)) else if (gcond *cond = dyn_cast<gcond *> (stmt))
{ {
......
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