diff options
author | Martin Sebor <msebor@redhat.com> | 2017-12-06 17:59:01 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2017-12-06 10:59:01 -0700 |
commit | 9c1caf50e16b50903364709d774244928c719b35 (patch) | |
tree | 37e9610f886770d0980145594fd7487eac2c1c1a /gcc/testsuite | |
parent | 8a797929f09274ccbf95ee7d8e415d35c1f5b0d1 (diff) | |
download | gcc-9c1caf50e16b50903364709d774244928c719b35.zip gcc-9c1caf50e16b50903364709d774244928c719b35.tar.gz gcc-9c1caf50e16b50903364709d774244928c719b35.tar.bz2 |
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
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/strncpy-chk1.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-stringop-chk-9.c | 150 |
4 files changed, 164 insertions, 4 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c39f3d2..a42348f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,12 @@ 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. diff --git a/gcc/testsuite/g++.dg/ext/strncpy-chk1.C b/gcc/testsuite/g++.dg/ext/strncpy-chk1.C index b94c3bd..8f8822b 100644 --- a/gcc/testsuite/g++.dg/ext/strncpy-chk1.C +++ b/gcc/testsuite/g++.dg/ext/strncpy-chk1.C @@ -1,4 +1,4 @@ -// 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=]" } diff --git a/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c b/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c index 35cc6dc..10048f3 100644 --- a/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c +++ b/gcc/testsuite/gcc.dg/builtin-stringop-chk-1.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.dg/builtin-stringop-chk-9.c b/gcc/testsuite/gcc.dg/builtin-stringop-chk-9.c new file mode 100644 index 0000000..b5464c2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-stringop-chk-9.c @@ -0,0 +1,150 @@ +/* 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=]" } */ +} |