2018-12-23 Martin Sebor <msebor@redhat.com>
Jeff Law <law@redhat.com>
+ * builtins.h (c_strlen_data): Add new fields and comments.
+ * builtins.c (unterminated_array): Change field reference from
+ "len" to "minlen" in c_strlen_data instance.
+ * gimple-fold.c (get_range_strlen): Likewise.
+ * gimple-ssa-sprintf.c (get_string_length): Likewise.
+
* builtins.c (unterminated_array): Rename "data" to "lendata". Fix
a few comments.
(expand_builtin_strnlen, expand_builtin_stpcpy_1): Likewise.
structure if EXP references a unterminated array. */
c_strlen_data lendata = { };
tree len = c_strlen (exp, 1, &lendata);
- if (len == NULL_TREE && lendata.len && lendata.decl)
+ if (len == NULL_TREE && lendata.minlen && lendata.decl)
{
if (size)
{
- len = lendata.len;
+ len = lendata.minlen;
if (lendata.off)
{
/* Constant offsets are already accounted for in LENDATA.MINLEN,
{
data->decl = decl;
data->off = byteoff;
- data->len = ssize_int (len);
+ data->minlen = ssize_int (len);
return NULL_TREE;
}
{
data->decl = decl;
data->off = byteoff;
- data->len = ssize_int (len);
+ data->minlen = ssize_int (len);
return NULL_TREE;
}
unsigned HOST_WIDE_INT *);
extern unsigned int get_pointer_alignment (tree);
extern unsigned string_length (const void*, unsigned, unsigned);
+
struct c_strlen_data
{
+ /* [MINLEN, MAXBOUND, MAXLEN] is a range describing the length of
+ one or more strings of possibly unknown length. For a single
+ string of known length the range is a constant where
+ MINLEN == MAXBOUND == MAXLEN holds.
+ For other strings, MINLEN is the length of the shortest known
+ string. MAXBOUND is the length of a string that could be stored
+ in the largest array referenced by the expression. MAXLEN is
+ the length of the longest sequence of non-zero bytes
+ in an object referenced by the expression. For such strings,
+ MINLEN <= MAXBOUND <= MAXLEN holds. For example, given:
+ struct A { char a[7], b[]; };
+ extern struct A *p;
+ n = strlen (p->a);
+ the computed range will be [0, 6, ALL_ONES].
+ However, for a conditional expression involving a string
+ of known length and an array of unknown bound such as
+ n = strlen (i ? p->b : "123");
+ the range will be [3, 3, ALL_ONES].
+ MINLEN != 0 && MAXLEN == ALL_ONES indicates that MINLEN is
+ the length of the shortest known string and implies that
+ the shortest possible string referenced by the expression may
+ actually be the empty string. This distinction is useful for
+ diagnostics. get_range_strlen() return value distinguishes
+ between these two cases.
+ As the tighter (and more optimistic) bound, MAXBOUND is suitable
+ for diagnostics but not for optimization.
+ As the more conservative bound, MAXLEN is intended to be used
+ for optimization. */
+ tree minlen;
+ tree maxlen;
+ tree maxbound;
+ /* When non-null, NONSTR 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
+ strlen() that expect a nul-terminated string as an argument. */
tree decl;
- tree len;
+ /* Non-constant offset from the beginning of a string not accounted
+ for in the length range. Used to improve diagnostics. */
tree off;
};