aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-03-19 17:45:34 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-03-19 11:45:34 -0600
commite3ba46bd52f9bd6db8788384dd186c9ba5963129 (patch)
tree5f4bc3c12380a6768864bf49672216e0763845a4
parent2214085affb80feb19e79882ee769e28c2a85a5a (diff)
downloadgcc-e3ba46bd52f9bd6db8788384dd186c9ba5963129.zip
gcc-e3ba46bd52f9bd6db8788384dd186c9ba5963129.tar.gz
gcc-e3ba46bd52f9bd6db8788384dd186c9ba5963129.tar.bz2
PR tree-optimization/89644 - False-positive -Warray-bounds diagnostic on strncpy
gcc/ChangeLog: PR tree-optimization/89644 * tree-ssa-strlen.c (handle_builtin_stxncpy): Consider unterminated arrays in determining sequence sizes in strncpy and stpncpy. gcc/testsuite/ChangeLog: PR tree-optimization/89644 * gcc.dg/Wstringop-truncation-8.c: New test. From-SVN: r269807
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-truncation-8.c94
-rw-r--r--gcc/tree-ssa-strlen.c30
4 files changed, 127 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 750d5e6..fe1f064 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2019-03-19 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/89644
+ * tree-ssa-strlen.c (handle_builtin_stxncpy): Consider unterminated
+ arrays in determining sequence sizes in strncpy and stpncpy.
+
2019-03-19 Martin Liska <mliska@suse.cz>
PR middle-end/89737
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 86cc80b..cf01b2f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-03-19 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/89644
+ * gcc.dg/Wstringop-truncation-8.c: New test.
+
2019-03-19 Martin Liska <mliska@suse.cz>
PR middle-end/89737
diff --git a/gcc/testsuite/gcc.dg/Wstringop-truncation-8.c b/gcc/testsuite/gcc.dg/Wstringop-truncation-8.c
new file mode 100644
index 0000000..1745da5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-truncation-8.c
@@ -0,0 +1,94 @@
+/* PR tree-optimization/89644 - False-positive -Warray-bounds diagnostic
+ on strncpy
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+#define NONSTR __attribute__ ((nonstring))
+
+typedef __SIZE_TYPE__ size_t;
+
+size_t strlen (const char*);
+extern char* stpncpy (char*, const char*, size_t);
+extern char* strncpy (char*, const char*, size_t);
+
+void sink (char*, ...);
+
+char f0 (char *s)
+{
+ char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+ if (*s)
+ strncpy (a, s, sizeof a); /* { dg-bogus "\\\[-Warray-bounds" } */
+ return a[0];
+}
+
+void f1 (char *s)
+{
+ char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+ if (*s)
+ strncpy (a, s, sizeof a); /* { dg-bogus "\\\[-Warray-bounds" } */
+ sink (a);
+}
+
+char f2 (void)
+{
+ char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+ char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+ strncpy (a, b + 1, 5); /* { dg-bogus "\\\[-Warray-bounds" } */
+ return a[0];
+}
+
+void f3 (void)
+{
+ char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+ char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+ strncpy (a, b + 2, 4); /* { dg-bogus "\\\[-Warray-bounds" } */
+ sink (a);
+}
+
+void f4 (NONSTR char *d)
+{
+ char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+ strncpy (d, b + 3, 3); /* { dg-bogus "\\\[-Warray-bounds" } */
+ sink (d);
+}
+
+
+char g0 (char *s)
+{
+ char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+ if (*s)
+ stpncpy (a, s, sizeof a); /* { dg-bogus "\\\[-Warray-bounds" } */
+ return a[0];
+}
+
+void g1 (char *s)
+{
+ char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+ char *p = 0;
+ if (*s)
+ p = stpncpy (a, s, sizeof a); /* { dg-bogus "\\\[-Warray-bounds" } */
+ sink (a, p);
+}
+
+char g2 (void)
+{
+ char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+ char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+ stpncpy (a, b + 1, 5); /* { dg-bogus "\\\[-Warray-bounds" } */
+ return a[0];
+}
+
+void g3 (void)
+{
+ char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+ char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+ char *p = stpncpy (a, b + 2, 4); /* { dg-bogus "\\\[-Warray-bounds" } */
+ sink (a, p);
+}
+
+void g4 (NONSTR char *d)
+{
+ char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+ char *p = stpncpy (d, b + 3, 3); /* { dg-bogus "\\\[-Warray-bounds" } */
+ sink (d, p);
+}
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 1eaed66..cf0f70d 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -2206,13 +2206,21 @@ handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *gsi)
int didx = get_stridx (dst);
if (strinfo *sidst = didx > 0 ? get_strinfo (didx) : NULL)
{
- /* Compute the size of the destination string including the NUL. */
+ /* Compute the size of the destination string including the nul
+ if it is known to be nul-terminated. */
if (sidst->nonzero_chars)
{
- tree type = TREE_TYPE (sidst->nonzero_chars);
- dstsize = fold_build2 (PLUS_EXPR, type, sidst->nonzero_chars,
- build_int_cst (type, 1));
+ if (sidst->endptr)
+ {
+ /* String is known to be nul-terminated. */
+ tree type = TREE_TYPE (sidst->nonzero_chars);
+ dstsize = fold_build2 (PLUS_EXPR, type, sidst->nonzero_chars,
+ build_int_cst (type, 1));
+ }
+ else
+ dstsize = sidst->nonzero_chars;
}
+
dst = sidst->ptr;
}
@@ -2224,12 +2232,18 @@ handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *gsi)
over the terminating nul so SISRC->DONT_INVALIDATE must be left
clear. */
- /* Compute the size of the source string including the NUL. */
+ /* Compute the size of the source string including the terminating
+ nul if its known to be nul-terminated. */
if (sisrc->nonzero_chars)
{
- tree type = TREE_TYPE (sisrc->nonzero_chars);
- srcsize = fold_build2 (PLUS_EXPR, type, sisrc->nonzero_chars,
- build_int_cst (type, 1));
+ if (sisrc->endptr)
+ {
+ tree type = TREE_TYPE (sisrc->nonzero_chars);
+ srcsize = fold_build2 (PLUS_EXPR, type, sisrc->nonzero_chars,
+ build_int_cst (type, 1));
+ }
+ else
+ srcsize = sisrc->nonzero_chars;
}
src = sisrc->ptr;