aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2018-09-14 03:34:19 +0000
committerJeff Law <law@gcc.gnu.org>2018-09-13 21:34:19 -0600
commit6ab24ea809555eeb869fe49595f22ed9c8737cc4 (patch)
treea6a98bb3c25e71934a2ae133c6e5116dcb9349b9 /gcc/expr.c
parentd01b568a78351beb6b693b613e6b48bcb2475eae (diff)
downloadgcc-6ab24ea809555eeb869fe49595f22ed9c8737cc4.zip
gcc-6ab24ea809555eeb869fe49595f22ed9c8737cc4.tar.gz
gcc-6ab24ea809555eeb869fe49595f22ed9c8737cc4.tar.bz2
builtins.h (c_srlen): Add argument.
* builtins.h (c_srlen): Add argument. * builtins.c (warn_string_no_nul): New function. (c_strlen): Add argument and use it. Update recursive calls. Pass DECL argument to string_constant to get info on non terminated strings. Update *NONSTR as needed. (fold_builtin_strlen): Add argument to calls to c_strlen. Warn for unterminated arrays. (warn_string_no_null): Add prototype. * expr.c (string_constant): Update arguments. Update recursive calls appropriately. Detect missing NUL terminator and outermost declaration its missing in. Improve checks for arrays with nonzero lower bound or elements that are not a single byte. Simplify offset computation. Simplify checks for non-NUL terminated strings. * gimple-fold.c (get_range_strlen): Add argument to c_strlen call. * gimple-ssa-sprintf.c (get_string_length): Remove unnecessary code. * gcc.dg/warn-strlen-no-nul.c: New test. Co-Authored-By: Bernd Edlinger <bernd.edlinger@hotmail.de> Co-Authored-By: Jeff Law <law@redhat.com> From-SVN: r264302
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c47
1 files changed, 15 insertions, 32 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 2d9a9eb..67aa052 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11303,16 +11303,11 @@ is_aligning_offset (const_tree offset, const_tree exp)
/* Return the tree node if an ARG corresponds to a string constant or zero
if it doesn't. If we return nonzero, set *PTR_OFFSET to the (possibly
non-constant) offset in bytes within the string that ARG is accessing.
- If NONSTR is non-null, consider valid even sequences of characters that
- aren't nul-terminated strings. In that case, if ARG refers to such
- a sequence set *NONSTR to its declaration and clear it otherwise.
- The type of the offset is sizetype. If MEM_SIZE is non-zero the storage
- size of the memory is returned. The returned STRING_CST object is
- valid up to TREE_STRING_LENGTH. Bytes between TREE_STRING_LENGTH
- and MEM_SIZE are zero. MEM_SIZE is at least TREE_STRING_LENGTH. */
+ If MEM_SIZE is non-zero the storage size of the memory is returned.
+ If DECL is non-zero the constant declaration is returned if available. */
tree
-string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *nonstr)
+string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
{
tree array;
STRIP_NOPS (arg);
@@ -11341,6 +11336,12 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *nonstr)
if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
return NULL_TREE;
+
+ if (!integer_zerop (array_ref_low_bound (arg)))
+ return NULL_TREE;
+
+ if (!integer_onep (array_ref_element_size (arg)))
+ return NULL_TREE;
}
}
array = get_addr_base_and_unit_offset (ref, &base_off);
@@ -11366,7 +11367,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *nonstr)
return NULL_TREE;
tree offset;
- if (tree str = string_constant (arg0, &offset, mem_size, nonstr))
+ if (tree str = string_constant (arg0, &offset, mem_size, decl))
{
/* Avoid pointers to arrays (see bug 86622). */
if (POINTER_TYPE_P (TREE_TYPE (arg))
@@ -11396,11 +11397,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *nonstr)
if (TREE_CODE (chartype) != INTEGER_TYPE)
return NULL;
- tree charsize = array_ref_element_size (arg);
- /* Set the non-constant offset to the non-constant index scaled
- by the size of the character type. */
- offset = fold_build2 (MULT_EXPR, TREE_TYPE (offset),
- fold_convert (sizetype, varidx), charsize);
+ offset = fold_convert (sizetype, varidx);
}
if (TREE_CODE (array) == STRING_CST)
@@ -11408,9 +11405,8 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *nonstr)
*ptr_offset = fold_convert (sizetype, offset);
if (mem_size)
*mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
- /* This is not strictly correct. FIXME in follow-up patch. */
- if (nonstr)
- *nonstr = NULL_TREE;
+ if (decl)
+ *decl = NULL_TREE;
gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (array)))
>= TREE_STRING_LENGTH (array));
return array;
@@ -11455,23 +11451,10 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *nonstr)
if (!init || TREE_CODE (init) != STRING_CST)
return NULL_TREE;
- /* Compute the lower bound number of elements (not bytes) in the array
- that the string is used to initialize. The actual size of the array
- may be greater if the string is shorter, but the the important
- data point is whether the literal, inlcuding the terminating nul,
- fits the array. */
- unsigned HOST_WIDE_INT charsize
- = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (init))));
- unsigned HOST_WIDE_INT array_elts
- = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (init))) / charsize;
-
- /* Compute the string length in (wide) characters. */
- unsigned HOST_WIDE_INT length = TREE_STRING_LENGTH (init);
-
if (mem_size)
*mem_size = TYPE_SIZE_UNIT (TREE_TYPE (init));
- if (nonstr)
- *nonstr = array_elts > length ? NULL_TREE : array;
+ if (decl)
+ *decl = array;
gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (init)))
>= TREE_STRING_LENGTH (init));