aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2018-07-09 20:33:48 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2018-07-09 14:33:48 -0600
commit35b4d3a644222b7bd69b3a1e9c00e78f3dbf3eba (patch)
treea540d226c0eeee38bd5ea06483ae688c1e0c070e /gcc/builtins.c
parentaad2444d346d4ae504a938de8708341dd1889aed (diff)
downloadgcc-35b4d3a644222b7bd69b3a1e9c00e78f3dbf3eba.zip
gcc-35b4d3a644222b7bd69b3a1e9c00e78f3dbf3eba.tar.gz
gcc-35b4d3a644222b7bd69b3a1e9c00e78f3dbf3eba.tar.bz2
PR middle-end/77357 - strlen of constant strings not folded
gcc/ChangeLog: PR middle-end/77357 PR middle-end/86428 * builtins.c (c_strlen): Avoid out-of-bounds warnings when accessing implicitly initialized array elements. * expr.c (string_constant): Handle string initializers of character arrays within aggregates. * gimple-fold.c (fold_array_ctor_reference): Add argument. Store element offset. As a special case, handle zero size. (fold_nonarray_ctor_reference): Same. (fold_ctor_reference): Add argument. Store subobject offset. * gimple-fold.h (fold_ctor_reference): Add argument. gcc/testsuite/ChangeLog: PR middle-end/77357 * gcc.dg/strlenopt-49.c: New test. * gcc.dg/strlenopt-50.c: New test. * gcc.dg/strlenopt-51.c: New test. * gcc.dg/strlenopt-52.c: New test. From-SVN: r262522
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 91658e8..820d6c2 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -602,8 +602,15 @@ c_strlen (tree src, int only_value)
= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (src))));
/* Set MAXELTS to sizeof (SRC) / sizeof (*SRC) - 1, the maximum possible
- length of SRC. */
- unsigned maxelts = TREE_STRING_LENGTH (src) / eltsize - 1;
+ length of SRC. Prefer TYPE_SIZE() to TREE_STRING_LENGTH() if possible
+ in case the latter is less than the size of the array. */
+ HOST_WIDE_INT maxelts = TREE_STRING_LENGTH (src);
+ tree type = TREE_TYPE (src);
+ if (tree size = TYPE_SIZE_UNIT (type))
+ if (tree_fits_shwi_p (size))
+ maxelts = tree_to_uhwi (size);
+
+ maxelts = maxelts / eltsize - 1;
/* PTR can point to the byte representation of any string type, including
char* and wchar_t*. */
@@ -629,7 +636,6 @@ c_strlen (tree src, int only_value)
what he gets. Subtract the offset from the length of the string,
and return that. This would perhaps not be valid if we were dealing
with named arrays in addition to literal string constants. */
-
return size_diffop_loc (loc, size_int (maxelts * eltsize), byteoff);
}