Commit 9c1caf50 by Martin Sebor Committed by Martin Sebor

PR tree-optimization/82646 - bogus -Wstringop-overflow with -D_FORTIFY_SOURCE=2…

PR tree-optimization/82646 - bogus -Wstringop-overflow with -D_FORTIFY_SOURCE=2 on strncpy with range to a member array

gcc/ChangeLog:

	PR tree-optimization/82646
	* builtins.c (maybe_emit_chk_warning): Use size as the bound for
	strncpy, not maxlen.

gcc/testsuite/ChangeLog:

	PR tree-optimization/82646
	* gcc.dg/builtin-stringop-chk-1.c: Adjust.
	* gcc.dg/builtin-stringop-chk-9.c: New test.
	* g++.dg/ext/strncpy-chk1.C: Adjust.

From-SVN: r255448
parent 8a797929
2017-12-06 Martin Sebor <msebor@redhat.com>
PR tree-optimization/82646
* builtins.c (maybe_emit_chk_warning): Use size as the bound for
strncpy, not maxlen.
2017-12-06 Martin Sebor <msebor@redhat.com>
* doc/invoke.texi (-Wstringop-truncation): Mention attribute
nonstring.
......@@ -9861,6 +9861,8 @@ maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
(such as __strncat_chk) or null if the operation isn't bounded
(such as __strcat_chk). */
tree maxlen = NULL_TREE;
/* The exact size of the access (such as in __strncpy_chk). */
tree size = NULL_TREE;
switch (fcode)
{
......@@ -9888,7 +9890,7 @@ maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
case BUILT_IN_STRNCPY_CHK:
case BUILT_IN_STPNCPY_CHK:
srcstr = CALL_EXPR_ARG (exp, 1);
maxlen = CALL_EXPR_ARG (exp, 2);
size = CALL_EXPR_ARG (exp, 2);
objsize = CALL_EXPR_ARG (exp, 3);
break;
......@@ -9911,7 +9913,7 @@ maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
}
check_sizes (OPT_Wstringop_overflow_, exp,
/*size=*/NULL_TREE, maxlen, srcstr, objsize);
size, maxlen, srcstr, objsize);
}
/* Emit warning if a buffer overflow is detected at compile time
......
2017-12-06 Martin Sebor <msebor@redhat.com>
PR tree-optimization/82646
* gcc.dg/builtin-stringop-chk-1.c: Adjust.
* gcc.dg/builtin-stringop-chk-9.c: New test.
* g++.dg/ext/strncpy-chk1.C: Adjust.
2017-12-06 Martin Sebor <msebor@redhat.com>
PR tree-optimization/83075
* gcc.dg/tree-ssa/strncat.c: New test.
* gcc.dg/tree-ssa/strncpy-2.c: Same.
......
// PR c++/40502
// PR c++/40502 - [4.5 Regression] crash in cp_diagnostic_starter
// { dg-do compile }
// { dg-options "-O2" }
// { dg-skip-if "packed attribute missing for struct A" { "epiphany-*-*" } }
......@@ -9,7 +9,8 @@ struct B { char z[50]; };
inline void
foo (char *dest, const char *__restrict src, __SIZE_TYPE__ n)
{
__builtin___strncpy_chk (dest, src, n, __builtin_object_size (dest, 0)); // { dg-warning "specified bound 36 exceeds destination size 35" }
// This triggers a -Wstringop-overflow warning (pruned below).
__builtin___strncpy_chk (dest, src, n, __builtin_object_size (dest, 0));
}
void bar (const char *, int);
......@@ -30,3 +31,5 @@ test ()
{
baz (0);
}
// { dg-prune-output "\\\[-Wstringop-overflow=]" }
......@@ -36,7 +36,7 @@ test (int arg, ...)
vx = stpcpy (&buf2[18], "a");
vx = stpcpy (&buf2[18], "ab"); /* { dg-warning "writing 3" "stpcpy" } */
strncpy (&buf2[18], "a", 2);
strncpy (&buf2[18], "a", 3); /* { dg-warning "specified bound 3 exceeds destination size 2" "strncpy" } */
strncpy (&buf2[18], "a", 3); /* { dg-warning "writing 3 bytes into a region of size 2" "strncpy" } */
strncpy (&buf2[18], "abc", 2);
strncpy (&buf2[18], "abc", 3); /* { dg-warning "writing 3 " "strncpy" } */
memset (buf2, '\0', sizeof (buf2));
......@@ -93,7 +93,7 @@ void
test2 (const H h)
{
char c;
strncpy (&c, str, 3); /* { dg-warning "specified bound 3 exceeds destination size 1" "strncpy" } */
strncpy (&c, str, 3); /* { dg-warning "writing 3 bytes into a region of size 1" "strncpy" } */
struct { char b[4]; } x;
sprintf (x.b, "%s", "ABCD"); /* { dg-warning "writing 5" "sprintf" } */
......
/* PR middle-end/82646 - bogus -Wstringop-overflow with -D_FORTIFY_SOURCE=2
on strncpy with range to a member array
{ dg-do compile }
{ dg-options "-O2 -Wstringop-overflow -ftrack-macro-expansion=0" } */
#define bos(p) __builtin_object_size (p, 1)
struct S {
char a[5];
void (*pf)(void);
};
/* Verify that none of the string function calls below triggers a warning. */
char* test_stpncpy_const_nowarn (struct S *p)
{
int n = sizeof p->a;
return __builtin_stpncpy (p->a, "123456", n);
}
char* test_strncpy_const_nowarn (struct S *p)
{
int n = sizeof p->a;
return __builtin_strncpy (p->a, "1234567", n);
}
char* test_stpncpy_chk_const_nowarn (struct S *p)
{
int n = sizeof p->a;
return __builtin___stpncpy_chk (p->a, "12345678", n, bos (p->a));
}
char* test_strncpy_chk_const_nowarn (struct S *p)
{
int n = sizeof p->a;
return __builtin___strncpy_chk (p->a, "123456789", n, bos (p->a));
}
char* test_stpncpy_range_nowarn (struct S *p, int n)
{
if (n < sizeof p->a)
n = sizeof p->a;
return __builtin_stpncpy (p->a, "123456", n);
}
char* test_strncpy_range_nowarn (struct S *p, int n)
{
if (n < sizeof p->a)
n = sizeof p->a;
return __builtin_strncpy (p->a, "1234567", n);
}
char* test_stpncpy_chk_range_nowarn (struct S *p, int n)
{
if (n < sizeof p->a)
n = sizeof p->a;
return __builtin___stpncpy_chk (p->a, "12345678", n, bos (p->a)); /* { dg-bogus "\\\[-Wstringop-overflow=]" } */
}
char* test_strncpy_chk_range_nowarn (struct S *p, int n)
{
if (n < sizeof p->a)
n = sizeof p->a;
return __builtin___strncpy_chk (p->a, "123456789", n, bos (p->a)); /* { dg-bogus "\\\[-Wstringop-overflow=]" } */
}
/* Verify that all of the string function calls below trigger a warning. */
char* test_stpncpy_const_warn (struct S *p)
{
int n = sizeof p->a;
++n;
return __builtin_stpncpy (p->a, "123456", n); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
char* test_strncpy_const_warn (struct S *p)
{
int n = sizeof p->a;
/* A call to strncpy() with a known string and small bound is folded
into memcpy() which defeats the warning in this case since memcpy
uses Object Size Type 0, i.e., the largest object that p->a may
be a part of. Use a larger bound to get around this here. */
n += 11;
return __builtin_strncpy (p->a, "1234567", n); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
char* test_stpncpy_chk_const_warn (struct S *p)
{
int n = sizeof p->a;
++n;
return __builtin___stpncpy_chk (p->a, "12345678", n, bos (p->a)); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
char* test_strncpy_chk_const_warn (struct S *p)
{
int n = sizeof p->a;
++n;
return __builtin___strncpy_chk (p->a, "123456789", n, bos (p->a)); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
char* test_stpncpy_range_warn (struct S *p, int n)
{
if (n < sizeof p->a + 1)
n = sizeof p->a + 1;
return __builtin_stpncpy (p->a, "123456", n); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
char* test_strncpy_range_warn (struct S *p, int n)
{
if (n < sizeof p->a + 1)
n = sizeof p->a + 1;
return __builtin_strncpy (p->a, "1234567", n); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
char* test_stpncpy_chk_range_warn (struct S *p, int n)
{
if (n < sizeof p->a + 1)
n = sizeof p->a + 1;
return __builtin___stpncpy_chk (p->a, "12345678", n, bos (p->a)); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
char* test_strncpy_chk_range_warn (struct S *p, int n)
{
if (n < sizeof p->a + 1)
n = sizeof p->a + 1;
return __builtin___strncpy_chk (p->a, "123456789", n, bos (p->a)); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment