aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2018-11-23 18:45:45 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2018-11-23 11:45:45 -0700
commit70c70369ce868fd8b049f710c01a899e502f6f68 (patch)
treee911138371a57dd5587cf3a3cc4e7882f5327607 /gcc/expr.c
parentdb1d09b049a9388c481ff76aa00fe74734cce1c8 (diff)
downloadgcc-70c70369ce868fd8b049f710c01a899e502f6f68.zip
gcc-70c70369ce868fd8b049f710c01a899e502f6f68.tar.gz
gcc-70c70369ce868fd8b049f710c01a899e502f6f68.tar.bz2
PR tree-optimization/87756 - missing unterminated argument warning using address of a constant character
gcc/ChangeLog: PR tree-optimization/87756 * expr.c (string_constant): Synthesize a string literal from the address of a constant character. * tree.c (build_string_literal): Add an argument. * tree.h (build_string_literal): Same. gcc/testsuite/ChangeLog: PR tree-optimization/87756 * gcc.dg/builtin-memchr-2.c: New test. * gcc.dg/builtin-memchr-3.c: Same. * gcc.dg/warn-sprintf-no-nul-2.c: Same. From-SVN: r266418
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 7ae3e37..021a04c 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11484,18 +11484,40 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
offset = off;
}
- if (!init || TREE_CODE (init) != STRING_CST)
+ if (!init)
return NULL_TREE;
+ *ptr_offset = offset;
+
+ tree eltype = TREE_TYPE (init);
+ tree initsize = TYPE_SIZE_UNIT (eltype);
if (mem_size)
- *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (init));
+ *mem_size = initsize;
+
if (decl)
*decl = array;
- gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (init)))
- >= TREE_STRING_LENGTH (init));
+ if (TREE_CODE (init) == INTEGER_CST)
+ {
+ /* For a reference to (address of) a single constant character,
+ store the native representation of the character in CHARBUF. */
+ unsigned char charbuf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
+ int len = native_encode_expr (init, charbuf, sizeof charbuf, 0);
+ if (len > 0)
+ {
+ /* Construct a string literal with elements of ELTYPE and
+ the representation above. Then strip
+ the ADDR_EXPR (ARRAY_REF (...)) around the STRING_CST. */
+ init = build_string_literal (len, (char *)charbuf, eltype);
+ init = TREE_OPERAND (TREE_OPERAND (init, 0), 0);
+ }
+ }
+
+ if (TREE_CODE (init) != STRING_CST)
+ return NULL_TREE;
+
+ gcc_checking_assert (tree_to_shwi (initsize) >= TREE_STRING_LENGTH (init));
- *ptr_offset = offset;
return init;
}