As reported in bug 78918, comment #7, the enhanced -Wrestrict warning issues a false positive on the following code. The false positive is caused by issuing the warning during folding, after bar() has been inlined but before the call to memcpy has been eliminated. The reason for issuing the warning in this case (i.e., equal operands) is to help detect bugs in code built without optimization when an unguarded overlapping call to the library function would be made, but it may not be worth the bug reports for the safe cases like this one. $ cat z.c && gcc -O2 -S -Wall z.c extern void* memcpy (void*, const void*, __SIZE_TYPE__); inline void bar (void *d, void *s, unsigned N) { if (s != d) memcpy (d, s, N); } void foo (void* src) { bar (src, src, 1); } z.c: In function ‘foo’: z.c:6:5: warning: ‘memcpy’ source argument is the same as destination [-Wrestrict] memcpy (d, s, N); ^~~~~~~~~~~~~~~~
Here's a slightly different test case, this one from bug 84095 comment 14 (reduced from bug 84095 comment 17). I'll confirm this bug based on that one. $ cat t.c && gcc -O2 -S -Wall t.c extern void* memcpy (void*, const void*, __SIZE_TYPE__); char a[4]; void f (unsigned n) { for (int i = 0; i < 1; i++) { if (!i) continue; memcpy (a, a, n); } } t.c: In function ‘f’: t.c:12:7: warning: ‘memcpy’ source argument is the same as destination [-Wrestrict] memcpy (a, a, n); ^~~~~~~~~~~~~~~~
And another test case from bug 84095 comment #9, also due to the check in gimple-fold.c. This one seems closer to the first test case in comment #0. $ cat t.c && gcc -O2 -S -Wall t.c extern void* memcpy (void*, const void*, __SIZE_TYPE__); struct netdevice { void *priv; }; struct ip_tunnel { struct netdevice *dev; int ip6rd[3]; }; struct sit_net { struct netdevice *fb_tunnel_dev; }; void ipip6_tunnel_clone_6rd (struct netdevice *dev, struct sit_net *sitn) { struct ip_tunnel *t = dev->priv; if (t->dev == sitn->fb_tunnel_dev) return; struct ip_tunnel *t0 = sitn->fb_tunnel_dev->priv; memcpy(&t->ip6rd, &t0->ip6rd, sizeof(t->ip6rd)); } void sit_init_net (struct sit_net *sitn, struct netdevice *fb_tunnel_dev) { sitn->fb_tunnel_dev = fb_tunnel_dev; ipip6_tunnel_clone_6rd (sitn->fb_tunnel_dev, sitn); } t.c: In function ‘sit_init_net’: t.c:23:3: warning: ‘memcpy’ source argument is the same as destination [-Wrestrict] memcpy(&t->ip6rd, &t0->ip6rd, sizeof(t->ip6rd)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See also bug 32667 for some background into GCC emitting perfectly overlapping calls to memcpy for some aggregate assignments. The code that controls the diagnostic tries to work around that bug: /* If SRC and DEST are the same (and not volatile), return DEST{,+LEN,+LEN-1}. */ if (operand_equal_p (src, dest, 0)) { /* Avoid diagnosing exact overlap in calls to __builtin_memcpy. It's safe and may even be emitted by GCC itself (see bug 32667). However, diagnose it in explicit calls to the memcpy function. */ if (check_overlap && *IDENTIFIER_POINTER (DECL_NAME (func)) != '_') warning_at (loc, OPT_Wrestrict, "%qD source argument is the same as destination", func);
Patch: https://gcc.gnu.org/ml/gcc-patches/2018-03/msg00358.html
Author: msebor Date: Mon Mar 12 18:04:16 2018 New Revision: 258455 URL: https://gcc.gnu.org/viewcvs?rev=258455&root=gcc&view=rev Log: PR tree-optimization/83456 - -Wrestrict false positive on a non-overlapping memcpy in an inline function gcc/ChangeLog: PR tree-optimization/83456 * gimple-fold.c (gimple_fold_builtin_memory_op): Avoid warning for perfectly overlapping calls to memcpy. (gimple_fold_builtin_memory_chk): Same. (gimple_fold_builtin_strcpy): Handle no-warning. (gimple_fold_builtin_stxcpy_chk): Same. * tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Handle no-warning. gcc/c-family/ChangeLog: PR tree-optimization/83456 * gcc/c-family/c-common.c (check_function_restrict): Return bool. Restore checking of bounded built-in functions. (check_function_arguments): Also return the result of warn_for_restrict. * gcc/c-family/c-common.c (check_function_restrict): Return bool. * gcc/c-family/c-warn.c (warn_for_restrict): Return bool. gcc/testsuite/ChangeLog: PR tree-optimization/83456 * c-c++-common/Wrestrict-2.c: Remove test cases. * c-c++-common/Wrestrict.c: Same. * gcc.dg/Wrestrict-12.c: New test. * gcc.dg/Wrestrict-14.c: New test. Added: trunk/gcc/testsuite/gcc.dg/Wrestrict-12.c trunk/gcc/testsuite/gcc.dg/Wrestrict-14.c Modified: trunk/gcc/ChangeLog trunk/gcc/c-family/ChangeLog trunk/gcc/c-family/c-common.c trunk/gcc/c-family/c-common.h trunk/gcc/c-family/c-warn.c trunk/gcc/gimple-fold.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/c-c++-common/Wrestrict-2.c trunk/gcc/testsuite/c-c++-common/Wrestrict.c trunk/gcc/tree-ssa-strlen.c
Patch committed in r258455.