aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun Ma <JunMa@linux.alibaba.com>2019-06-27 09:50:35 +0000
committerJun Ma <junma@gcc.gnu.org>2019-06-27 09:50:35 +0000
commit5fd336bbd7b273408018dfbb7a170e1d54facb8e (patch)
tree22f6406d9cbec125a110e719d1d92089c273176e
parente11c48711128a8aff3938cf28954acf1b1cc0b62 (diff)
downloadgcc-5fd336bbd7b273408018dfbb7a170e1d54facb8e.zip
gcc-5fd336bbd7b273408018dfbb7a170e1d54facb8e.tar.gz
gcc-5fd336bbd7b273408018dfbb7a170e1d54facb8e.tar.bz2
re PR tree-optimization/89772 (memchr for a character not in constant nul-padded string not folded)
PR tree-optimization/89772 * gimple-fold.c (gimple_fold_builtin_memchr): consider trailing nuls in out-of-bound accesses checking. gcc/testsuite * gcc.dg/builtin-memchr-4.c: New test. From-SVN: r272740
-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" } } */