mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
905969f941
commit
03c4a945ba
|
|
@ -1,3 +1,21 @@
|
||||||
|
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 {
|
||||||
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)
|
||||||
/* 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,
|
||||||
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,
|
||||||
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,
|
||||||
{
|
{
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
|| 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,
|
||||||
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,
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
/* 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)
|
||||||
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)
|
||||||
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)
|
||||||
? 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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue