summaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-08-22 23:09:26 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-08-22 17:09:26 -0600
commit14b7950f126f84fa585e3a057940ff10d4c5b3f8 (patch)
tree12d343894aea62b7964a5f595ddfd3cac40750e6 /gcc/builtins.c
parent1b1e13dbde7f3eef0f8356af05c5de1fb46cb31b (diff)
PR middle-end/91490 - bogus argument missing terminating nul warning on strlen of a flexible array member
gcc/c-family/ChangeLog: PR middle-end/91490 * c-common.c (braced_list_to_string): Add argument and overload. Handle flexible length arrays and unions. gcc/testsuite/ChangeLog: PR middle-end/91490 * c-c++-common/Warray-bounds-7.c: New test. * gcc.dg/Warray-bounds-39.c: Expect either -Warray-bounds or -Wstringop-overflow. * gcc.dg/strlenopt-78.c: New test. gcc/ChangeLog: PR middle-end/91490 * builtins.c (c_strlen): Rename argument and introduce new local. Set no-warning bit on original argument. * expr.c (string_constant): Pass argument type to fold_ctor_reference. Fold empty and zero constructors into empty strings. * gimple-fold.c (fold_nonarray_ctor_reference): Return a STRING_CST for missing initializers. * tree.c (build_string_literal): Handle optional argument. * tree.h (build_string_literal): Add defaulted argument. * gimple-ssa-warn-restrict.c (maybe_diag_access_bounds): Check no-warning bit on original expression. From-SVN: r274837
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 9a766e4ad63..073b92a1dc9 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -620,7 +620,7 @@ unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */)
into the instruction stream and zero if it is going to be expanded.
E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
is returned, otherwise NULL, since
- len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
+ len = c_strlen (ARG, 1); if (len) expand_expr (len, ...); would not
evaluate the side-effects.
If ONLY_VALUE is two then we do not emit warnings about out-of-bound
@@ -628,7 +628,7 @@ unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */)
into the instruction stream.
Additional information about the string accessed may be recorded
- in DATA. For example, if SRC references an unterminated string,
+ in DATA. For example, if ARG references an unterminated string,
then the declaration will be stored in the DECL field. If the
length of the unterminated string can be determined, it'll be
stored in the LEN field. Note this length could well be different
@@ -640,7 +640,7 @@ unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */)
The value returned is of type `ssizetype'. */
tree
-c_strlen (tree src, int only_value, c_strlen_data *data, unsigned eltsize)
+c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize)
{
/* If we were not passed a DATA pointer, then get one to a local
structure. That avoids having to check DATA for NULL before
@@ -650,7 +650,8 @@ c_strlen (tree src, int only_value, c_strlen_data *data, unsigned eltsize)
data = &local_strlen_data;
gcc_checking_assert (eltsize == 1 || eltsize == 2 || eltsize == 4);
- STRIP_NOPS (src);
+
+ tree src = STRIP_NOPS (arg);
if (TREE_CODE (src) == COND_EXPR
&& (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
{
@@ -762,11 +763,15 @@ c_strlen (tree src, int only_value, c_strlen_data *data, unsigned eltsize)
{
/* Suppress multiple warnings for propagated constant strings. */
if (only_value != 2
- && !TREE_NO_WARNING (src)
+ && !TREE_NO_WARNING (arg)
&& warning_at (loc, OPT_Warray_bounds,
"offset %qwi outside bounds of constant string",
eltoff))
- TREE_NO_WARNING (src) = 1;
+ {
+ if (decl)
+ inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl);
+ TREE_NO_WARNING (arg) = 1;
+ }
return NULL_TREE;
}