Bug 91977 - missing -Wstringop-overflow on memcpy into a pointer plus offset
Summary: missing -Wstringop-overflow on memcpy into a pointer plus offset
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: 10.0
Assignee: Martin Sebor
URL:
Keywords: diagnostic, patch
Depends on:
Blocks: Wstringop-overflow
  Show dependency treegraph
 
Reported: 2019-10-02 21:29 UTC by Martin Sebor
Modified: 2019-10-04 21:30 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-10-02 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2019-10-02 21:29:19 UTC
In GCC 8 and above, -Wstringop-overflow detects the first buffer overflow but not the second in the test program below.

$ cat b.c && gcc -O2 -S -Wall -fdump-tree-strlen=/dev/stdout b.c
char a[7];

void f (const void *s)
{
  __builtin_memcpy (a + 4, s, 4);   // -Wstringop-overflow
}

void g (const void *s)
{
  char *d = a + 4;
  __builtin_memcpy (d, s, 4);   // no warning
}


;; Function f (f, funcdef_no=0, decl_uid=1925, cgraph_uid=1, symbol_order=1)

;; 1 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2
;; 2 succs { 1 }
f (const void * s)
{
  <bb 2> [local count: 1073741824]:
  __builtin_memcpy (&MEM <char[7]> [(void *)&a + 4B], s_2(D), 4);
  return;

}


b.c: In function ‘f’:
b.c:5:3: warning: ‘__builtin_memcpy’ forming offset 7 is out of the bounds [0, 7] of object ‘a’ with type ‘char[7]’ [-Warray-bounds]
    5 |   __builtin_memcpy (a + 4, s, 4);   // -Wstringop-overflow
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
b.c:1:6: note: ‘a’ declared here
    1 | char a[7];
      |      ^

;; Function g (g, funcdef_no=1, decl_uid=1928, cgraph_uid=2, symbol_order=2)

;; 1 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2
;; 2 succs { 1 }
g (const void * s)
{
  unsigned int _3;

  <bb 2> [local count: 1073741824]:
  _3 = MEM <unsigned int> [(char * {ref-all})s_2(D)];
  MEM <unsigned int> [(char * {ref-all})&a + 4B] = _3;
  return;

}
Comment 1 Martin Sebor 2019-10-03 23:29:11 UTC
Patch: https://gcc.gnu.org/ml/gcc-patches/2019-10/msg00258.html
Comment 2 Martin Sebor 2019-10-04 21:30:15 UTC
Author: msebor
Date: Fri Oct  4 21:29:41 2019
New Revision: 276603

URL: https://gcc.gnu.org/viewcvs?rev=276603&root=gcc&view=rev
Log:
PR middle-end/91977 - missing -Wstringop-overflow on memcpy into a pointer plus offset

gcc/ChangeLog:

	PR middle-end/91977
	* tree-ssa-strlen.c (count_nonzero_bytes): Handle assignments with
	MEM_REF right operand.  Avoid failing for MEM_REF assignments from
	uninitialized objects.

gcc/testsuite/ChangeLog:

	PR middle-end/91977
	* gcc.dg/Wstringop-overflow-18.c: New test.


Added:
    trunk/gcc/testsuite/gcc.dg/Wstringop-overflow-18.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/Warray-bounds-18.c
    trunk/gcc/tree-ssa-strlen.c
Comment 3 Martin Sebor 2019-10-04 21:30:36 UTC
Patch committed in r276603.