This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Adjust string_constant to new STRING_CST semantics
- From: Bernd Edlinger <bernd dot edlinger at hotmail dot de>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, Richard Biener <rguenther at suse dot de>, Jeff Law <law at redhat dot com>, Martin Sebor <msebor at gmail dot com>
- Date: Fri, 24 Aug 2018 21:24:45 +0000
- Subject: [PATCH] Adjust string_constant to new STRING_CST semantics
Hi,
I noticed that the latest patches to make STRING_CST
semantics for literals and for initializers consistent
also fixes PR 86711 and PR 86714 (but not PR 87053).
The code change in the string_constant does not change
any test case, the new test cases are already fixed
once we have the unified STRING_CST semantics.
Thus https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01569.html
would be the pre-condition for this patch.
If the pre-condition patch is applied then my earlier patch
to fix PR 86711/86714 is no longer necessary.
Likely neither Martin's patch (at least that part about
PR 86711/86714).
Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
Is it OK for trunk?
Thanks
Bernd.
gcc:
2018-08-24 Bernd Edlinger <bernd.edlinger@hotmail.de>
* expr.c (string_constant): Adjust function comment.
Remove bogus check for zero termination.
testsuite:
2018-08-24 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR middle-end/86711
PR middle-end/86714
* gcc.c-torture/execute/pr86711.c: New test.
* gcc.c-torture/execute/pr86714.c: New test.
diff -Npur gcc/expr.c gcc/expr.c
--- gcc/expr.c 2018-08-22 22:34:01.000000000 +0200
+++ gcc/expr.c 2018-08-24 20:24:21.592913041 +0200
@@ -11304,8 +11304,9 @@ is_aligning_offset (const_tree offset, c
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.
The type of the offset is sizetype. If MEM_SIZE is non-zero the storage
- size of the memory is returned. If MEM_SIZE is zero, the string is
- only returned when it is properly zero terminated. */
+ 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. */
tree
string_constant (tree arg, tree *ptr_offset, tree *mem_size)
@@ -11404,6 +11405,8 @@ string_constant (tree arg, tree *ptr_off
*ptr_offset = fold_convert (sizetype, offset);
if (mem_size)
*mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
+ gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (array)))
+ >= TREE_STRING_LENGTH (array));
return array;
}
@@ -11446,27 +11449,10 @@ string_constant (tree arg, tree *ptr_off
if (!init || TREE_CODE (init) != STRING_CST)
return NULL_TREE;
- tree array_size = DECL_SIZE_UNIT (array);
- if (!array_size || TREE_CODE (array_size) != INTEGER_CST)
- return NULL_TREE;
-
- /* Avoid returning a string that doesn't fit in the array
- it is stored in, like
- const char a[4] = "abcde";
- but do handle those that fit even if they have excess
- initializers, such as in
- const char a[4] = "abc\000\000";
- The excess elements contribute to TREE_STRING_LENGTH()
- but not to strlen(). */
- unsigned HOST_WIDE_INT charsize
- = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (init))));
- unsigned HOST_WIDE_INT length = TREE_STRING_LENGTH (init);
- length = string_length (TREE_STRING_POINTER (init), charsize,
- length / charsize);
if (mem_size)
*mem_size = TYPE_SIZE_UNIT (TREE_TYPE (init));
- else if (compare_tree_int (array_size, length + 1) < 0)
- return NULL_TREE;
+ gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (init)))
+ >= TREE_STRING_LENGTH (init));
*ptr_offset = offset;
return init;
diff -Npur gcc/testsuite/gcc.c-torture/execute/pr86711.c gcc/testsuite/gcc.c-torture/execute/pr86711.c
--- gcc/testsuite/gcc.c-torture/execute/pr86711.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr86711.c 2018-08-24 20:29:15.960882045 +0200
@@ -0,0 +1,11 @@
+/* PR middle-end/86711 */
+
+static const char a[2][4] = { "1234", "5678" };
+
+int main ()
+{
+ void *p = __builtin_memchr (a, 0, 5);
+
+ if (p)
+ __builtin_abort ();
+}
diff -Npur gcc/testsuite/gcc.c-torture/execute/pr86714.c gcc/testsuite/gcc.c-torture/execute/pr86714.c
--- gcc/testsuite/gcc.c-torture/execute/pr86714.c 1970-01-01 01:00:00.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr86714.c 2018-08-24 20:29:15.960882045 +0200
@@ -0,0 +1,12 @@
+/* PR middle-end/86714 */
+
+const char a[2][3] = { "1234", "xyz" };
+char b[6];
+
+int main ()
+{
+ __builtin_memcpy (b, a, 4);
+ __builtin_memset (b + 4, 'a', 2);
+ if (__builtin_memcmp (b, "123xaa", 6))
+ __builtin_abort ();
+}