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
This commit is contained in:
Martin Sebor 2019-03-19 17:45:34 +00:00 committed by Martin Sebor
parent 2214085aff
commit e3ba46bd52
4 changed files with 127 additions and 8 deletions

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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;