Commit 03c4a945 by Martin Sebor Committed by Jeff Law

re PR middle-end/88663 (internal compiler error: in check, at tree-vrp.c:188)

	PR middle-end/88663
	* gimple-fold.c (get_range_strlen): Update prototype to no longer
	need the flexp argument.
	(get_range_strlen_tree): Drop flexp argument.  Drop flexp argument
	from calls to get_range_strlen.  Update comments.  Just update
	VAL for an unterminated const char array and let the reset of the
	code handle it normally.  No longer try to set *flexp.  Adjust
	return value.
	(get_range_strlen): Update for the new get_range_strlen API.
	(get_maxval_strlen): Similarly.
	(gimple_fold_builtin_strlen): Handle update meaning of return value
	from get_range_strlen.
	* gimple-ssa-sprintf.c (get_string_length): Update for the new
	get_range_strlen API.

Co-Authored-By: Jeff Law <law@redhat.com>

From-SVN: r267520
parent 905969f9
2019-01-02 Martin Sebor <msebor@redhat.com>
Jeff Law <law@redhat.com>
PR middle-end/88663
* gimple-fold.c (get_range_strlen): Update prototype to no longer
need the flexp argument.
(get_range_strlen_tree): Drop flexp argument. Drop flexp argument
from calls to get_range_strlen. Update comments. Just update
VAL for an unterminated const char array and let the reset of the
code handle it normally. No longer try to set *flexp. Adjust
return value.
(get_range_strlen): Update for the new get_range_strlen API.
(get_maxval_strlen): Similarly.
(gimple_fold_builtin_strlen): Handle update meaning of return value
from get_range_strlen.
* gimple-ssa-sprintf.c (get_string_length): Update for the new
get_range_strlen API.
2019-01-02 Jan Hubicka <hubicka@ucw.cz> 2019-01-02 Jan Hubicka <hubicka@ucw.cz>
PR lto/88130 PR lto/88130
......
...@@ -83,8 +83,8 @@ enum strlen_range_kind { ...@@ -83,8 +83,8 @@ enum strlen_range_kind {
SRK_INT_VALUE SRK_INT_VALUE
}; };
static bool get_range_strlen (tree, bitmap *, strlen_range_kind, static bool
c_strlen_data *, bool *, unsigned); get_range_strlen (tree, bitmap *, strlen_range_kind, c_strlen_data *, unsigned);
/* Return true when DECL can be referenced from current unit. /* Return true when DECL can be referenced from current unit.
FROM_DECL (if non-null) specify constructor of variable DECL was taken from. FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
...@@ -1281,10 +1281,8 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len) ...@@ -1281,10 +1281,8 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
/* Helper of get_range_strlen for ARG that is not an SSA_NAME. */ /* Helper of get_range_strlen for ARG that is not an SSA_NAME. */
static bool static bool
get_range_strlen_tree (tree arg, bitmap *visited, get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind,
strlen_range_kind rkind, c_strlen_data *pdata, unsigned eltsize)
c_strlen_data *pdata,
bool *flexp, unsigned eltsize)
{ {
gcc_assert (TREE_CODE (arg) != SSA_NAME); gcc_assert (TREE_CODE (arg) != SSA_NAME);
...@@ -1307,8 +1305,8 @@ get_range_strlen_tree (tree arg, bitmap *visited, ...@@ -1307,8 +1305,8 @@ get_range_strlen_tree (tree arg, bitmap *visited,
tree aop0 = TREE_OPERAND (op, 0); tree aop0 = TREE_OPERAND (op, 0);
if (TREE_CODE (aop0) == INDIRECT_REF if (TREE_CODE (aop0) == INDIRECT_REF
&& TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME) && TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME)
return get_range_strlen (TREE_OPERAND (aop0, 0), visited, return get_range_strlen (TREE_OPERAND (aop0, 0), visited, rkind,
rkind, pdata, flexp, eltsize); pdata, eltsize);
} }
else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF
&& (rkind == SRK_LENRANGE || rkind == SRK_LENRANGE_2)) && (rkind == SRK_LENRANGE || rkind == SRK_LENRANGE_2))
...@@ -1342,14 +1340,12 @@ get_range_strlen_tree (tree arg, bitmap *visited, ...@@ -1342,14 +1340,12 @@ get_range_strlen_tree (tree arg, bitmap *visited,
c_strlen_data lendata = { }; c_strlen_data lendata = { };
val = c_strlen (arg, 1, &lendata, eltsize); val = c_strlen (arg, 1, &lendata, eltsize);
/* If we potentially had a non-terminated string, then
bubble that information up to the caller. */
if (!val && lendata.decl) if (!val && lendata.decl)
{ {
/* ARG refers to an unterminated const character array.
DATA.DECL with size DATA.LEN. */
val = lendata.minlen;
pdata->decl = lendata.decl; pdata->decl = lendata.decl;
pdata->minlen = lendata.minlen;
pdata->maxlen = lendata.minlen;
return rkind == SRK_STRLEN ? false : true;
} }
} }
...@@ -1357,7 +1353,7 @@ get_range_strlen_tree (tree arg, bitmap *visited, ...@@ -1357,7 +1353,7 @@ get_range_strlen_tree (tree arg, bitmap *visited,
{ {
if (TREE_CODE (arg) == ADDR_EXPR) if (TREE_CODE (arg) == ADDR_EXPR)
return get_range_strlen (TREE_OPERAND (arg, 0), visited, rkind, return get_range_strlen (TREE_OPERAND (arg, 0), visited, rkind,
pdata, flexp, eltsize); pdata, eltsize);
if (TREE_CODE (arg) == ARRAY_REF) if (TREE_CODE (arg) == ARRAY_REF)
{ {
...@@ -1386,10 +1382,6 @@ get_range_strlen_tree (tree arg, bitmap *visited, ...@@ -1386,10 +1382,6 @@ get_range_strlen_tree (tree arg, bitmap *visited,
the array could have zero length. */ the array could have zero length. */
pdata->minlen = ssize_int (0); pdata->minlen = ssize_int (0);
if (TREE_CODE (TREE_OPERAND (arg, 0)) == COMPONENT_REF
&& optype == TREE_TYPE (TREE_OPERAND (arg, 0))
&& array_at_struct_end_p (TREE_OPERAND (arg, 0)))
*flexp = true;
tight_bound = true; tight_bound = true;
} }
else if (TREE_CODE (arg) == COMPONENT_REF else if (TREE_CODE (arg) == COMPONENT_REF
...@@ -1401,11 +1393,7 @@ get_range_strlen_tree (tree arg, bitmap *visited, ...@@ -1401,11 +1393,7 @@ get_range_strlen_tree (tree arg, bitmap *visited,
optimistic if the array itself isn't NUL-terminated and optimistic if the array itself isn't NUL-terminated and
the caller relies on the subsequent member to contain the caller relies on the subsequent member to contain
the NUL but that would only be considered valid if the NUL but that would only be considered valid if
the array were the last member of a struct. the array were the last member of a struct. */
Set *FLEXP to true if the array whose bound is being
used is at the end of a struct. */
if (array_at_struct_end_p (arg))
*flexp = true;
tree fld = TREE_OPERAND (arg, 1); tree fld = TREE_OPERAND (arg, 1);
...@@ -1550,7 +1538,7 @@ get_range_strlen_tree (tree arg, bitmap *visited, ...@@ -1550,7 +1538,7 @@ get_range_strlen_tree (tree arg, bitmap *visited,
} }
pdata->maxlen = val; pdata->maxlen = val;
return true; return rkind == SRK_LENRANGE || rkind == SRK_LENRANGE_2 || !integer_all_onesp (val);
} }
/* For an ARG referencing one or more strings, try to obtain the range /* For an ARG referencing one or more strings, try to obtain the range
...@@ -1570,12 +1558,13 @@ get_range_strlen_tree (tree arg, bitmap *visited, ...@@ -1570,12 +1558,13 @@ get_range_strlen_tree (tree arg, bitmap *visited,
Return true if *PDATA was successfully populated and false otherwise. */ Return true if *PDATA was successfully populated and false otherwise. */
static bool static bool
get_range_strlen (tree arg, bitmap *visited, strlen_range_kind rkind, get_range_strlen (tree arg, bitmap *visited,
c_strlen_data *pdata, bool *flexp, unsigned eltsize) strlen_range_kind rkind,
c_strlen_data *pdata, unsigned eltsize)
{ {
if (TREE_CODE (arg) != SSA_NAME) if (TREE_CODE (arg) != SSA_NAME)
return get_range_strlen_tree (arg, visited, rkind, pdata, flexp, eltsize); return get_range_strlen_tree (arg, visited, rkind, pdata, eltsize);
/* If ARG is registered for SSA update we cannot look at its defining /* If ARG is registered for SSA update we cannot look at its defining
statement. */ statement. */
...@@ -1601,7 +1590,7 @@ get_range_strlen (tree arg, bitmap *visited, strlen_range_kind rkind, ...@@ -1601,7 +1590,7 @@ get_range_strlen (tree arg, bitmap *visited, strlen_range_kind rkind,
|| gimple_assign_unary_nop_p (def_stmt)) || gimple_assign_unary_nop_p (def_stmt))
{ {
tree rhs = gimple_assign_rhs1 (def_stmt); tree rhs = gimple_assign_rhs1 (def_stmt);
return get_range_strlen (rhs, visited, rkind, pdata, flexp, eltsize); return get_range_strlen (rhs, visited, rkind, pdata, eltsize);
} }
else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR) else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR)
{ {
...@@ -1609,8 +1598,7 @@ get_range_strlen (tree arg, bitmap *visited, strlen_range_kind rkind, ...@@ -1609,8 +1598,7 @@ get_range_strlen (tree arg, bitmap *visited, strlen_range_kind rkind,
gimple_assign_rhs3 (def_stmt) }; gimple_assign_rhs3 (def_stmt) };
for (unsigned int i = 0; i < 2; i++) for (unsigned int i = 0; i < 2; i++)
if (!get_range_strlen (ops[i], visited, rkind, pdata, if (!get_range_strlen (ops[i], visited, rkind, pdata, eltsize))
flexp, eltsize))
{ {
if (rkind != SRK_LENRANGE_2) if (rkind != SRK_LENRANGE_2)
return false; return false;
...@@ -1644,7 +1632,7 @@ get_range_strlen (tree arg, bitmap *visited, strlen_range_kind rkind, ...@@ -1644,7 +1632,7 @@ get_range_strlen (tree arg, bitmap *visited, strlen_range_kind rkind,
if (arg == gimple_phi_result (def_stmt)) if (arg == gimple_phi_result (def_stmt))
continue; continue;
if (!get_range_strlen (arg, visited, rkind, pdata, flexp, eltsize)) if (!get_range_strlen (arg, visited, rkind, pdata, eltsize))
{ {
if (rkind != SRK_LENRANGE_2) if (rkind != SRK_LENRANGE_2)
return false; return false;
...@@ -1696,8 +1684,8 @@ get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize, bool strict) ...@@ -1696,8 +1684,8 @@ get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize, bool strict)
{ {
bitmap visited = NULL; bitmap visited = NULL;
bool flexarray = false; if (!get_range_strlen (arg, &visited, strict ? SRK_LENRANGE : SRK_LENRANGE_2,
if (!get_range_strlen (arg, &visited, strict ? SRK_LENRANGE : SRK_LENRANGE_2, pdata, &flexarray, eltsize)) pdata, eltsize))
{ {
/* On failure extend the length range to an impossible maximum /* On failure extend the length range to an impossible maximum
(a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other (a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other
...@@ -1715,7 +1703,7 @@ get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize, bool strict) ...@@ -1715,7 +1703,7 @@ get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize, bool strict)
if (visited) if (visited)
BITMAP_FREE (visited); BITMAP_FREE (visited);
return flexarray; return !integer_all_onesp (pdata->maxlen);
} }
/* Return the maximum value for ARG given RKIND (see strlen_range_kind). /* Return the maximum value for ARG given RKIND (see strlen_range_kind).
...@@ -1741,8 +1729,7 @@ get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL) ...@@ -1741,8 +1729,7 @@ get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL)
/* Reset DATA.MAXLEN if the call fails or when DATA.MAXLEN /* Reset DATA.MAXLEN if the call fails or when DATA.MAXLEN
is unbounded. */ is unbounded. */
c_strlen_data lendata = { }; c_strlen_data lendata = { };
bool dummy; if (!get_range_strlen (arg, &visited, rkind, &lendata, /* eltsize = */1))
if (!get_range_strlen (arg, &visited, rkind, &lendata, &dummy, 1))
lendata.maxlen = NULL_TREE; lendata.maxlen = NULL_TREE;
else if (lendata.maxlen && integer_all_onesp (lendata.maxlen)) else if (lendata.maxlen && integer_all_onesp (lendata.maxlen))
lendata.maxlen = NULL_TREE; lendata.maxlen = NULL_TREE;
...@@ -3720,7 +3707,7 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi) ...@@ -3720,7 +3707,7 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
wide_int maxlen; wide_int maxlen;
c_strlen_data lendata = { }; c_strlen_data lendata = { };
if (!get_range_strlen (arg, &lendata, /* eltsize = */ 1) if (get_range_strlen (arg, &lendata, /* eltsize = */ 1)
&& !lendata.decl && !lendata.decl
&& lendata.minlen && TREE_CODE (lendata.minlen) == INTEGER_CST && lendata.minlen && TREE_CODE (lendata.minlen) == INTEGER_CST
&& lendata.maxlen && TREE_CODE (lendata.maxlen) == INTEGER_CST) && lendata.maxlen && TREE_CODE (lendata.maxlen) == INTEGER_CST)
......
...@@ -2009,7 +2009,7 @@ get_string_length (tree str, unsigned eltsize) ...@@ -2009,7 +2009,7 @@ get_string_length (tree str, unsigned eltsize)
aren't known to point any such arrays result in LENDATA.MAXLEN aren't known to point any such arrays result in LENDATA.MAXLEN
set to SIZE_MAX. */ set to SIZE_MAX. */
c_strlen_data lendata = { }; c_strlen_data lendata = { };
bool flexarray = get_range_strlen (str, &lendata, eltsize); get_range_strlen (str, &lendata, eltsize);
/* Return the default result when nothing is known about the string. */ /* Return the default result when nothing is known about the string. */
if (integer_all_onesp (lendata.maxbound) if (integer_all_onesp (lendata.maxbound)
...@@ -2026,7 +2026,7 @@ get_string_length (tree str, unsigned eltsize) ...@@ -2026,7 +2026,7 @@ get_string_length (tree str, unsigned eltsize)
? tree_to_uhwi (lendata.maxbound) ? tree_to_uhwi (lendata.maxbound)
: HOST_WIDE_INT_M1U); : HOST_WIDE_INT_M1U);
const bool unbounded = flexarray || integer_all_onesp (lendata.maxlen); const bool unbounded = integer_all_onesp (lendata.maxlen);
/* Set the max/likely counters to unbounded when a minimum is known /* Set the max/likely counters to unbounded when a minimum is known
but the maximum length isn't bounded. This implies that STR is but the maximum length isn't bounded. This implies that STR is
......
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