aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-07-20 12:06:18 -0600
committerMartin Sebor <msebor@redhat.com>2020-07-20 12:08:58 -0600
commitd5803b9876b3d11c93d1a10fabb3fbb1c4a14bd6 (patch)
tree21c9c55bfd9003436d22c960d3578579af9dd744 /gcc/tree.c
parent3e99ed65cbedf7a6c0abb9cd63c191326995fd34 (diff)
downloadgcc-d5803b9876b3d11c93d1a10fabb3fbb1c4a14bd6.zip
gcc-d5803b9876b3d11c93d1a10fabb3fbb1c4a14bd6.tar.gz
gcc-d5803b9876b3d11c93d1a10fabb3fbb1c4a14bd6.tar.bz2
Correct handling of constant representations containing embedded nuls.
Resolves: PR middle-end/95189 - memcmp being wrongly stripped like strcm PR middle-end/95886 - suboptimal memcpy with embedded zero bytes gcc/ChangeLog: PR middle-end/95189 PR middle-end/95886 * builtins.c (inline_expand_builtin_string_cmp): Rename... (inline_expand_builtin_bytecmp): ...to this. (builtin_memcpy_read_str): Don't expect data to be nul-terminated. (expand_builtin_memory_copy_args): Handle object representations with embedded nul bytes. (expand_builtin_memcmp): Same. (expand_builtin_strcmp): Adjust call to naming change. (expand_builtin_strncmp): Same. * expr.c (string_constant): Create empty strings with nonzero size. * fold-const.c (c_getstr): Rename locals and update comments. * tree.c (build_string): Accept null pointer argument. (build_string_literal): Same. * tree.h (build_string): Provide a default. (build_string_literal): Same. gcc/testsuite/ChangeLog: PR middle-end/95189 PR middle-end/95886 * gcc.dg/memcmp-pr95189.c: New test. * gcc.dg/strncmp-3.c: New test. * gcc.target/i386/memcpy-pr95886.c: New test.
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 9102f8d..6522a08 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -2206,29 +2206,29 @@ build_real_from_int_cst (tree type, const_tree i)
return v;
}
-/* Return a newly constructed STRING_CST node whose value is
- the LEN characters at STR.
+/* Return a newly constructed STRING_CST node whose value is the LEN
+ characters at STR when STR is nonnull, or all zeros otherwise.
Note that for a C string literal, LEN should include the trailing NUL.
The TREE_TYPE is not initialized. */
tree
-build_string (int len, const char *str)
+build_string (unsigned len, const char *str /*= NULL */)
{
- tree s;
- size_t length;
-
/* Do not waste bytes provided by padding of struct tree_string. */
- length = len + offsetof (struct tree_string, str) + 1;
+ unsigned size = len + offsetof (struct tree_string, str) + 1;
- record_node_allocation_statistics (STRING_CST, length);
+ record_node_allocation_statistics (STRING_CST, size);
- s = (tree) ggc_internal_alloc (length);
+ tree s = (tree) ggc_internal_alloc (size);
memset (s, 0, sizeof (struct tree_typed));
TREE_SET_CODE (s, STRING_CST);
TREE_CONSTANT (s) = 1;
TREE_STRING_LENGTH (s) = len;
- memcpy (s->string.str, str, len);
+ if (str)
+ memcpy (s->string.str, str, len);
+ else
+ memset (s->string.str, 0, len);
s->string.str[len] = '\0';
return s;
@@ -11572,12 +11572,12 @@ build_alloca_call_expr (tree size, unsigned int align, HOST_WIDE_INT max_size)
/* Create a new constant string literal of type ELTYPE[SIZE] (or LEN
if SIZE == -1) and return a tree node representing char* pointer to
- it as an ADDR_EXPR (ARRAY_REF (ELTYPE, ...)). The STRING_CST value
- is the LEN bytes at STR (the representation of the string, which may
- be wide). */
+ it as an ADDR_EXPR (ARRAY_REF (ELTYPE, ...)). When STR is nonnull
+ the STRING_CST value is the LEN bytes at STR (the representation
+ of the string, which may be wide). Otherwise it's all zeros. */
tree
-build_string_literal (int len, const char *str,
+build_string_literal (unsigned len, const char *str /* = NULL */,
tree eltype /* = char_type_node */,
unsigned HOST_WIDE_INT size /* = -1 */)
{