Bug 83519 - missing -Wrestrict on an overlapping strcpy to a non-member array
Summary: missing -Wrestrict on an overlapping strcpy to a non-member array
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2017-12-21 00:55 UTC by Martin Sebor
Modified: 2018-03-08 00:57 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2017-12-21 00:55:55 UTC
Most likely due to bug 83501, while the newly enhanced -Wrestrict warning detects the overlapping copy in function f() below, it fails to detect the same problem in g() and h().  The strlen pass isn't prepared to handle the MEM_REF.

$ cat a.c && gcc -O2 -S -Wall -fdump-tree-strlen=/dev/stdout a.c
extern char* stpcpy (char*, const char*);   // work around bug 82429

struct S { char a[17]; };

void f (struct S *p, const char *s)
{
  __builtin_strcpy (p->a, "0123456789abcdef");

  __builtin_strcpy (p->a, p->a + 4);   // warning (good)
}

char a[17];

void g (const char *s)
{
  __builtin_strcpy (a, "0123456789abcdef");

  __builtin_strcpy (a, a + 4);   // missing warning (bug)
}

void h (const char *s)
{
   char a[17];

  __builtin_strcpy (a, "0123456789abcdef");

  __builtin_strcpy (a, a + 4);   // missing warning (bug)

  extern void sink (void*);
  sink (a);
}


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

a.c: In function ‘f’:
a.c:9:3: warning: ‘__builtin_strcpy’ accessing 13 bytes at offsets 0 and 4 overlaps 9 bytes at offset 4 [-Wrestrict]
   __builtin_strcpy (p->a, p->a + 4);   // warning (good)
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
f (struct S * p, const char * s)
{
  char[17] * _1;
  const char * _2;

  <bb 2> [local count: 1073741825]:
  _1 = &p_3(D)->a;
  __builtin_memcpy (_1, "0123456789abcdef", 17);
  _2 = &MEM[(void *)p_3(D) + 4B];
  __builtin_strcpy (_1, _2);
  return;

}



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

g (const char * s)
{
  <bb 2> [local count: 1073741825]:
  MEM[(char * {ref-all})&a] = MEM[(char * {ref-all})"0123456789abcdef"];
  __builtin_strcpy (&a, &MEM[(void *)&a + 4B]);
  return;

}



;; Function h (h, funcdef_no=2, decl_uid=1905, cgraph_uid=2, symbol_order=3)

h (const char * s)
{
  char a[17];

  <bb 2> [local count: 1073741825]:
  MEM[(char * {ref-all})&a] = MEM[(char * {ref-all})"0123456789abcdef"];
  __builtin_strcpy (&a, &MEM[(void *)&a + 4B]);
  sink (&a);
  a ={v} {CLOBBER};
  return;

}
Comment 1 Martin Sebor 2018-03-08 00:56:39 UTC
Author: msebor
Date: Thu Mar  8 00:56:07 2018
New Revision: 258348

URL: https://gcc.gnu.org/viewcvs?rev=258348&root=gcc&view=rev
Log:
PR tree-optimization/83519 - missing -Wrestrict on an overlapping strcpy to a non-member array

gcc/testsuite/ChangeLog:

	* gcc.dg/Wrestrict-13.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/Wrestrict-13.c
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 2 Martin Sebor 2018-03-08 00:57:07 UTC
This was fixed by r256180:

r256180 | prathamesh3492 | 2018-01-03 11:07:32 -0500 (Wed, 03 Jan 2018) | 9 lines

2018-01-03  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>

	PR tree-optimization/83501
	* tree-ssa-strlen.c (get_string_cst): New.
	(handle_char_store): Call get_string_cst.