aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimple-fold.c10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/builtin-memchr-4.c40
4 files changed, 60 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a1bd798..44f9850 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2019-06-27 Jun Ma <JunMa@linux.alibaba.com>
+
+ PR tree-optimization/89772
+ * gimple-fold.c (gimple_fold_builtin_memchr): consider trailing nuls in
+ out-of-bound accesses checking.
+
2019-06-27 Martin Liska <mliska@suse.cz>
PR tree-optimization/91014
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index dfb31a0..118718a 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -2543,7 +2543,15 @@ gimple_fold_builtin_memchr (gimple_stmt_iterator *gsi)
const char *r = (const char *)memchr (p1, c, MIN (length, string_length));
if (r == NULL)
{
- if (length <= string_length)
+ tree mem_size, offset_node;
+ string_constant (arg1, &offset_node, &mem_size, NULL);
+ unsigned HOST_WIDE_INT offset = (offset_node == NULL_TREE)
+ ? 0 : tree_to_uhwi (offset_node);
+ /* MEM_SIZE is the size of the array the string literal
+ is stored in. */
+ unsigned HOST_WIDE_INT string_size = tree_to_uhwi (mem_size) - offset;
+ gcc_checking_assert (string_length <= string_size);
+ if (length <= string_size)
{
replace_call_with_value (gsi, build_int_cst (ptr_type_node, 0));
return true;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c48ceef..3c459a4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-06-27 Jun Ma <JunMa@linux.alibaba.com>
+
+ PR tree-optimization/89772
+ * gcc.dg/builtin-memchr-4.c: New test.
+
2019-06-27 Martin Liska <mliska@suse.cz>
PR tree-optimization/91014
diff --git a/gcc/testsuite/gcc.dg/builtin-memchr-4.c b/gcc/testsuite/gcc.dg/builtin-memchr-4.c
new file mode 100644
index 0000000..58a3b44
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-memchr-4.c
@@ -0,0 +1,40 @@
+/* PR tree-optimization/89772
+ Verify that memchr calls with a pointer to a constant character
+ are folded as expected.
+ { dg-do compile }
+ { dg-options "-O1 -Wall -fdump-tree-release_ssa" } */
+
+typedef __SIZE_TYPE__ size_t;
+typedef __WCHAR_TYPE__ wchar_t;
+
+extern void* memchr (const void*, int, size_t);
+extern int printf (const char*, ...);
+extern void abort (void);
+
+#define A(expr) \
+ ((expr) \
+ ? (void)0 \
+ : (printf ("assertion failed on line %i: %s\n", \
+ __LINE__, #expr), \
+ abort ()))
+
+const char a[8] = {'a',0,'b'};
+const char b[3] = {'a','b'};
+const char c[8] = {'a','b','c'};
+
+void test_memchr_cst_char (void)
+{
+ A (!memchr (a, 'c', 2));
+ A (!memchr (a, 'c', 5));
+ A (!memchr (a, 'c', sizeof a));
+ A (&a[1] == memchr (a, 0, sizeof a));
+
+ A (!memchr (b, 0, 2));
+ A (&b[2] == memchr (b, 0, sizeof b));
+
+ A (!memchr (c, 0, 2));
+ A (&c[3] == memchr (c, 0, 4));
+ A (&c[3] == memchr (c, 0, sizeof a));
+}
+
+/* { dg-final { scan-tree-dump-not "abort" "release_ssa" } } */