https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84771
Bug ID: 84771 Summary: missing -Wrestrict passing the same address to restrict-qualified arguments of a user-defined function Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- In the test case below, -Wrestrict detects the first four instances of passing the same address to restrict-qualified arguments but misses the last two in the call to the user-defined function. The reason for that is that the checker for user-defined functions is implemented in the front-end and relies on operand_equal_p() to determine whether the arguments are equal, which isn't equipped to do this kind of analysis. To do a better job this part of the checker (i.e., for user-defined functions) should be moved to the gimple-ssa-warn-restrict pass. $ cat x.c && gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout x.c struct S { char a[4]; }; void f (struct S *p) { __builtin_strcpy ((char*)p, (char*)p); // -Wrestrict (good) __builtin_strcpy ((char*)p, p->a); // -Wrestrict (good) __builtin_strcpy ((char*)p, &p->a[0]); // -Wrestrict (good) } void g (void* restrict, void* restrict); void h (struct S *p) { g (p, p); // -Wrestrict (good) g (p, p->a); // missing -Wrestrict g (p->a, &p->a[0]); // missing -Wrestrict } x.c: In function ‘h’: x.c:14:3: warning: passing argument 1 to restrict-qualified parameter aliases with argument 2 [-Wrestrict] g (p, p); // -Wrestrict (good) ^ x.c: In function ‘f’: x.c:5:3: warning: ‘__builtin_strcpy’ source argument is the same as destination [-Wrestrict] __builtin_strcpy ((char*)p, (char*)p); // -Wrestrict (good) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ x.c:6:3: warning: ‘__builtin_strcpy’ accessing 1 byte at offsets 0 and 0 overlaps 1 byte at offset 0 [-Wrestrict] __builtin_strcpy ((char*)p, p->a); // -Wrestrict (good) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ x.c:7:3: warning: ‘__builtin_strcpy’ accessing 1 byte at offsets 0 and 0 overlaps 1 byte at offset 0 [-Wrestrict] __builtin_strcpy ((char*)p, &p->a[0]); // -Wrestrict (good) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;; Function f (f, funcdef_no=0, decl_uid=1960, cgraph_uid=0, symbol_order=0) f (struct S * p) { char[4] * _1; <bb 2> [local count: 1073741825]: _1 = &p_2(D)->a; __builtin_strcpy (p_2(D), _1); __builtin_strcpy (p_2(D), _1); [tail call] return; } ;; Function h (h, funcdef_no=1, decl_uid=1966, cgraph_uid=1, symbol_order=1) h (struct S * p) { char[4] * _1; <bb 2> [local count: 1073741825]: g (p_3(D), p_3(D)); _1 = &p_3(D)->a; g (p_3(D), _1); g (_1, _1); [tail call] return; }