diff options
author | Martin Sebor <msebor@redhat.com> | 2020-07-20 12:06:18 -0600 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2020-07-20 12:08:58 -0600 |
commit | d5803b9876b3d11c93d1a10fabb3fbb1c4a14bd6 (patch) | |
tree | 21c9c55bfd9003436d22c960d3578579af9dd744 /gcc/tree.c | |
parent | 3e99ed65cbedf7a6c0abb9cd63c191326995fd34 (diff) | |
download | gcc-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.c | 28 |
1 files changed, 14 insertions, 14 deletions
@@ -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 */) { |