| /* Verify -Wstringop-overread is issued for reading more than the maximum |
| object size but not for writing. |
| { dg-do compile } |
| { dg-options "-O2 -Wno-stringop-overflow -ftrack-macro-expansion=0" } */ |
| |
| #define PTRDIFF_MAX __PTRDIFF_MAX__ |
| #define SIZE_MAX __SIZE_MAX__ |
| |
| #define NOIPA __attribute__ ((noipa)) |
| |
| typedef __SIZE_TYPE__ size_t; |
| |
| void* memchr (const void*, int, size_t); |
| int memcmp (const void*, const void*, size_t); |
| void* memcpy (const void*, const void*, size_t); |
| |
| int strncmp (const char*, const char*, size_t); |
| char* strncat (char*, const char*, size_t); |
| char* strncpy (char*, const char*, size_t); |
| size_t strnlen (const char*, size_t); |
| |
| void sink (int, ...); |
| #define sink(...) sink (0, __VA_ARGS__) |
| #define T(exp) sink (exp) |
| |
| NOIPA void test_memchr (const void *p, int x) |
| { |
| size_t dmax = PTRDIFF_MAX; |
| size_t smax = SIZE_MAX; |
| |
| T (memchr (p, x, dmax)); |
| |
| T (memchr (p, x, dmax + 1)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" } |
| T (memchr (p, x, dmax * 2)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" } |
| T (memchr (p, x, smax)); // { dg-warning "\\\[-Wstringop-overread" } |
| } |
| |
| |
| NOIPA void test_memcmp (const void *p, const void *q) |
| { |
| size_t dmax = PTRDIFF_MAX; |
| size_t smax = SIZE_MAX; |
| |
| T (memcmp (p, q, dmax)); |
| |
| T (memcmp (p, q, dmax + 1)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" } |
| T (memcmp (p, q, dmax * 2)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" } |
| T (memcmp (p, q, smax)); // { dg-warning "\\\[-Wstringop-overread" } |
| } |
| |
| |
| NOIPA void test_memcpy (void *p, const void *q) |
| { |
| size_t dmax = PTRDIFF_MAX; |
| size_t smax = SIZE_MAX; |
| |
| T (memcpy (p, q, dmax)); |
| |
| T (memcpy (p, q, dmax + 1)); // -Wstringop-overflow disabled |
| T (memcpy (p, q, dmax * 2)); // ditto |
| T (memcpy (p, q, smax)); // ditto |
| } |
| |
| |
| NOIPA void test_strncmp (const char *p, const char *q) |
| { |
| size_t dmax = PTRDIFF_MAX; |
| size_t smax = SIZE_MAX; |
| |
| T (strncmp (p, q, dmax)); |
| |
| T (strncmp (p, q, dmax + 1)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" "strncmp" } |
| T (strncmp (p, q, dmax * 2)); // { dg-warning "\\\[-Wstringop-overread" "strncmp" } |
| T (strncmp (p, q, smax)); // { dg-warning "\\\[-Wstringop-overread" "strncmp" } |
| } |
| |
| NOIPA void test_strncat (char *p, const char *q) |
| { |
| size_t dmax = PTRDIFF_MAX; |
| size_t smax = SIZE_MAX; |
| |
| T (strncat (p, q, dmax)); |
| |
| T (strncat (p, q, dmax + 1)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" } |
| T (strncat (p, q, dmax * 2)); // { dg-warning "\\\[-Wstringop-overread" } |
| T (strncat (p, q, smax)); // { dg-warning "\\\[-Wstringop-overread" } |
| } |
| |
| NOIPA void test_strncpy (char *p, const char *q) |
| { |
| #if 0 |
| /* Disabled: strncpy calls with an excissve bound trigger both |
| -Wstringop-overflow and, when the former option is disabled, |
| -Wstringop-overread. The latter should probably not trigger. */ |
| |
| size_t dmax = PTRDIFF_MAX; |
| size_t smax = SIZE_MAX; |
| |
| T (strncpy (p, q, dmax)); |
| |
| T (strncpy (p, q, dmax + 1)); // -Wstringop-overflow disabled |
| T (strncpy (p, q, dmax * 2)); // ditto |
| T (strncpy (p, q, smax)); // ditto |
| #endif |
| } |
| |
| NOIPA void test_strnlen (const char *p) |
| { |
| size_t dmax = PTRDIFF_MAX; |
| size_t smax = SIZE_MAX; |
| |
| T (strnlen (p, dmax)); |
| |
| T (strnlen (p, dmax + 1)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" } |
| T (strnlen (p, dmax * 2)); // { dg-warning "\\\[-Wstringop-overread" } |
| T (strnlen (p, smax)); // { dg-warning "\\\[-Wstringop-overread" } |
| } |