| /* PR tree-optimization/83456 - -Wrestrict false positive on a non-overlapping |
| memcpy in an inline function |
| Verify that calls to built-in functions are diagnosed when the pointer |
| arguments to their restrict-qualified parameters are the same (the absence |
| of the false positives reported in PR 83456 is tested in Wrestrict-12.c. |
| { dg-do compile } |
| { dg-options "-O2 -Wall -Wrestrict -Wno-stringop-truncation" } */ |
| |
| typedef __SIZE_TYPE__ size_t; |
| |
| extern void* memcpy (void* restrict, const void* restrict, size_t); |
| extern void* mempcpy (void* restrict, const void* restrict, size_t); |
| extern char* stpncpy (char* restrict, const char* restrict, size_t); |
| extern char* stpcpy (char* restrict, const char* restrict); |
| extern char* strncat (char* restrict, const char* restrict, size_t); |
| extern char* strcat (char* restrict, const char* restrict); |
| extern char* strncpy (char* restrict, const char* restrict, size_t); |
| extern char* strcpy (char* restrict, const char* restrict); |
| |
| struct S |
| { |
| char a[4]; |
| char *p; |
| } s; |
| |
| void sink (void*); |
| |
| void test_memcpy (char *p, struct S *q, size_t n) |
| { |
| /* The behavior of memcpy() is undefined only when when copying takes |
| place between overlapping objects. Since a call with a size of zero |
| does nothing, it should not be diagnosed. */ |
| memcpy (p, p, 0); |
| sink (p); |
| |
| memcpy (p, p, 1); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| memcpy (p, p, n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| memcpy (q->a, q->a, 0); |
| sink (q); |
| |
| memcpy (q->p, q->p, 1); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| memcpy (&q->a[0], q->a, n); /* { dg-warning "\\\[-Wrestrict]" "bug ????" { xfail *-*-* } } */ |
| sink (q); |
| |
| memcpy (q, q->a, n); /* { dg-warning "\\\[-Wrestrict]" "bug ????" { xfail *-*-* } } */ |
| sink (q); |
| } |
| |
| void test_mempcpy (char *p, struct S *q, size_t n) |
| { |
| mempcpy (p, p, 0); |
| sink (p); |
| |
| mempcpy (p, p, 1); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| mempcpy (p, p, n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| mempcpy (q->a, q->a, 0); |
| sink (q); |
| |
| mempcpy (q->p, q->p, 1); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| mempcpy (&q->a[0], q->a, n); /* { dg-warning "\\\[-Wrestrict]" "bug ????" { xfail *-*-* } } */ |
| sink (q); |
| |
| mempcpy (q, q->a, n); /* { dg-warning "\\\[-Wrestrict]" "bug ????" { xfail *-*-* } } */ |
| sink (q); |
| } |
| |
| void test_strncat (char *p, struct S *q, size_t n) |
| { |
| strncat (p, p, 0); |
| sink (p); |
| |
| strncat (p, p, 1); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| strncat (p, p, n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| strncat (q->a, q->a, n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strncat (&q->a[0], &q->a[0], n);/* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strncat (q->a, &q->a[0], n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strncat (q->p, &q->p[0], n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| } |
| |
| void test_strcat (char *p, struct S *q, size_t n) |
| { |
| strcat (p, p); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| strcat (p, p); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| strcat (p, p); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| strcat (q->a, q->a); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strcat (&q->a[0], &q->a[0]); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strcat (q->a, &q->a[0]); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strcat (q->p, &q->p[0]); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| } |
| |
| void test_stpncpy (char *p, struct S *q, size_t n) |
| { |
| stpncpy (p, p, 0); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| stpncpy (p, p, 1); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| stpncpy (p, p, n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| stpncpy (q->a, q->a, n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| stpncpy (&q->a[0], &q->a[0], n);/* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| stpncpy (q->a, &q->a[0], n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| stpncpy (q->p, &q->p[0], n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| } |
| |
| void test_stpcpy (char *p, struct S *q, size_t n) |
| { |
| stpcpy (p, p); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| stpcpy (p, p); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| stpcpy (p, p); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| stpcpy (q->a, q->a); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| stpcpy (&q->a[0], &q->a[0]); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| stpcpy (q->a, &q->a[0]); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| stpcpy (q->p, &q->p[0]); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| } |
| |
| void test_strncpy (char *p, struct S *q, size_t n) |
| { |
| strncpy (p, p, 0); |
| sink (p); |
| |
| strncpy (p, p, 1); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| strncpy (p, p, n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| strncpy (q->a, q->a, n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strncpy (&q->a[0], &q->a[0], n);/* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strncpy (q->a, &q->a[0], n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strncpy (q->p, &q->p[0], n); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| } |
| |
| void test_strcpy (char *p, struct S *q, size_t n) |
| { |
| strcpy (p, p); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| strcpy (p, p); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| strcpy (p, p); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (p); |
| |
| strcpy (q->a, q->a); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strcpy (&q->a[0], &q->a[0]); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strcpy (q->a, &q->a[0]); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| |
| strcpy (q->p, &q->p[0]); /* { dg-warning "\\\[-Wrestrict]" } */ |
| sink (q); |
| } |