In the test case below, the -Wstringop-overflow detects the buffer overflow in the call to memmove() in function f() but fails to detect the same overflow in the call to __builtin_memove(). This is another case I missed when implementing the warning, in addition to bug 79222. $ cat t.c && gcc -D_FORTIFY_SOURCE=2 -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-vrp=/dev/stdout t.c #include <string.h> char d[3]; void f (void) { memmove (d, d + 1, 17); } void g (void) { __builtin_memmove (d, d + 1, 17); } ;; Function f (f, funcdef_no=24, decl_uid=2254, cgraph_uid=24, symbol_order=25) ;; 1 loops found ;; ;; Loop 0 ;; header 0, latch 1 ;; depth 0, outer -1 ;; nodes: 0 1 2 ;; 2 succs { 1 } Value ranges after VRP: f () { <bb 2> [100.00%]: __builtin___memmove_chk (&d, &MEM[(void *)&d + 1B], 17, 3); return; } ;; Function f (f, funcdef_no=24, decl_uid=2254, cgraph_uid=24, symbol_order=25) ;; 1 loops found ;; ;; Loop 0 ;; header 0, latch 1 ;; depth 0, outer -1 ;; nodes: 0 1 2 ;; 2 succs { 1 } Value ranges after VRP: f () { <bb 2> [100.00%]: __builtin___memmove_chk (&d, &MEM[(void *)&d + 1B], 17, 3); return; } In file included from /usr/include/string.h:639:0, from t.c:1: In function ‘memmove’, inlined from ‘f’ at t.c:7:3: /usr/include/bits/string3.h:57:10: warning: ‘__builtin___memmove_chk’ writing 17 bytes into a region of size 3 overflows the destination [-Wstringop-overflow=] return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;; Function g (g, funcdef_no=25, decl_uid=2257, cgraph_uid=25, symbol_order=26) ;; 1 loops found ;; ;; Loop 0 ;; header 0, latch 1 ;; depth 0, outer -1 ;; nodes: 0 1 2 ;; 2 succs { 1 } Value ranges after VRP: g () { <bb 2> [100.00%]: __builtin_memmove (&d, &MEM[(void *)&d + 1B], 17); return; } ;; Function g (g, funcdef_no=25, decl_uid=2257, cgraph_uid=25, symbol_order=26) ;; 1 loops found ;; ;; Loop 0 ;; header 0, latch 1 ;; depth 0, outer -1 ;; nodes: 0 1 2 ;; 2 succs { 1 } Value ranges after VRP: g () { <bb 2> [100.00%]: __builtin_memmove (&d, &MEM[(void *)&d + 1B], 17); return; }
Patch posted for review: https://gcc.gnu.org/ml/gcc-patches/2017-01/msg01994.html
Author: msebor Date: Thu May 4 20:54:43 2017 New Revision: 247618 URL: https://gcc.gnu.org/viewcvs?rev=247618&root=gcc&view=rev Log: PR preprocessor/79214 - -Wno-system-header defeats strncat buffer overflow warnings PR middle-end/79222 - missing -Wstringop-overflow= on a stpcpy overflow PR middle-end/79223 - missing -Wstringop-overflow on a memmove overflow gcc/ChangeLog: PR preprocessor/79214 PR middle-end/79222 PR middle-end/79223 * builtins.c (check_sizes): Add inlinining context and issue warnings even when -Wno-system-headers is set. (check_strncat_sizes): Same. (expand_builtin_strncat): Same. (expand_builtin_memmove): New function. (expand_builtin_stpncpy): Same. (expand_builtin): Handle memmove and stpncpy. gcc/testsuite/ChangeLog: PR preprocessor/79214 PR middle-end/79222 PR middle-end/79223 * gcc.dg/pr79214.c: New test. * gcc.dg/pr79214.h: New test header. * gcc.dg/pr79222.c: New test. * gcc.dg/pr79223.c: New test. * gcc.dg/pr78138.c: Adjust. * gfortran.dg/unconstrained_commons.f: Same. Added: trunk/gcc/testsuite/gcc.dg/pr79214.c trunk/gcc/testsuite/gcc.dg/pr79214.h trunk/gcc/testsuite/gcc.dg/pr79222.c trunk/gcc/testsuite/gcc.dg/pr79223.c Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/pr78138.c trunk/gcc/testsuite/gfortran.dg/unconstrained_commons.f
Fix committed in r247618.