blob: 16dc06d968bf8d1596a5884a993531a77c70b953 [file] [log] [blame]
/* 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" }
}