blob: cf536527fb9aade3218657c2e0a93170d32f4555 [file] [log] [blame]
/* PR tree-optimization/89350 - Wrong -Wstringop-overflow warning
on a variable offset from the end of an array
Test exercising -Wstringop-truncation with -Wall.
-Wstringop-truncation is disabled to avoid warnings for strncpy
calls whose bound matches the size of the destination getting
in the way of -Wstringop-overflow.
{ dg-do compile }
{ dg-options "-O2 -Wall -Wno-stringop-truncation -ftrack-macro-expansion=0" } */
#include "range.h"
extern void* memcpy (void*, const void*, size_t);
extern void* memset (void*, int, size_t);
extern char* strcpy (char*, const char*);
extern char* strncpy (char*, const char*, size_t);
void sink (void*);
#define CAT(pfx, line) pfx ## line
#define CONCAT(pfx, line) CAT (pfx, line)
#define UNIQ_NAME(pfx) CONCAT (pfx, __LINE__)
/* Exercise a call to memset with a distinct destination object each
time to prevent GCC from reusing the destination pointer in later
tests. */
#define T(off1, off2, n) \
do { \
extern char UNIQ_NAME (ga)[7]; \
char *d = UNIQ_NAME (ga) + off1; \
d += off2; \
memset (d, 0, n); \
sink (d); \
} while (0)
/* Exercise calls to memset with a destination pointer pointing to
an array plus constant offset plus variable offset, in that order. */
void test_memset_array_cst_range_off (void)
{
T (1, SR (-7, 7), 7);
T (1, SR (-1, 1), 7);
T (1, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (1, SR ( 1, 2), 1);
T (1, SR ( 1, 2), 5);
T (1, SR ( 0, 1), 6);
T (1, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR (-7, 7), 7);
T (2, SR (-2, 7), 7);
T (2, SR (-1, 1), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR ( 1, 2), 1);
T (2, SR ( 1, 2), 3);
T (2, SR ( 1, 2), 4);
T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (7, UR (-7, 0), 7);
T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (7, UR (-3, 2), 3);
T (7, UR (-2, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}
/* Exercise calls to memset with a destination pointer pointing to
an array plus variable offset plus constant offset. */
void test_memset_array_range_cst_off (void)
{
T (SR (-7, 7), 1, 7);
T (SR (-1, 1), 1, 7);
T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 5);
T (SR ( 0, 1), 1, 6);
T (UR ( 1, 2), 1, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR (-7, 7), 2, 7);
T (SR (-1, 1), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR (-1, 1), 2, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR ( 1, 2), 2, 1);
T (SR ( 1, 2), 2, 3);
T (SR ( 1, 2), 2, 4);
T (SR ( 1, 2), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR ( 0, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (UR ( 1, 2), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}
void test_memset_array_range_range_off (void)
{
T (UR (0, 1), UR (0, 1), 7);
T (UR (3, 5), UR (2, 7), 1);
T (UR (3, 7), UR (2, 9), 2);
T (UR (3, 9), UR (2, 9), 3); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (UR (0, 1), UR (1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}
#undef T
#define T(off1, off2, n) \
do { \
extern char UNIQ_NAME (ga)[7]; \
char *d = UNIQ_NAME (ga) + off1; \
d += off2; \
memcpy (d, s, n); \
sink (d); \
} while (0)
void test_memcpy_array_cst_range_off (const void *s)
{
T (1, SR (-7, 7), 7);
T (1, SR (-1, 1), 7);
T (1, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (1, SR ( 1, 2), 1);
T (1, SR ( 1, 2), 5);
T (1, SR ( 0, 1), 6);
T (1, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR (-7, 7), 7);
T (2, SR (-2, 7), 7);
T (2, SR (-1, 1), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR ( 1, 2), 1);
T (2, SR ( 1, 2), 3);
T (2, SR ( 1, 2), 4);
T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (7, UR (-7, 0), 7);
T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (7, UR (-3, 2), 3);
T (7, UR (-2, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}
void test_memcpy_array_range_cst_off (const void *s)
{
T (SR (-7, 7), 1, 7);
T (SR (-1, 1), 1, 7);
T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 5);
T (SR ( 0, 1), 1, 6);
T (UR ( 1, 2), 1, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR (-7, 7), 2, 7);
T (SR (-1, 1), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR (-1, 1), 2, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR ( 1, 2), 2, 1);
T (SR ( 1, 2), 2, 3);
T (SR ( 1, 2), 2, 4);
T (SR ( 1, 2), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR ( 0, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (UR ( 1, 2), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}
void test_memcpy_array_range_range_off (const void *s)
{
T (UR (0, 1), UR (0, 1), 7);
T (UR (3, 5), UR (2, 7), 1);
T (UR (3, 7), UR (2, 9), 2);
T (UR (3, 9), UR (2, 9), 3); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (UR (0, 1), UR (1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}
#undef T
#define T(off1, off2, n) \
do { \
extern char UNIQ_NAME (ga)[7]; \
char *d = UNIQ_NAME (ga) + off1; \
d += off2; \
const char str[] = "0123456789"; \
const char *s = str + sizeof str - 1 - n; \
strcpy (d, s); \
sink (d); \
} while (0)
void test_strcpy_array_cst_range_off (void)
{
T (1, SR (-7, 7), 6);
T (1, SR (-1, 1), 6);
T (1, SR (-1, 1), 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (1, SR ( 1, 2), 0);
T (1, SR ( 1, 2), 4);
T (1, SR ( 0, 1), 5);
T (1, UR ( 1, 2), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR (-7, 7), 6);
T (2, SR (-2, 7), 6);
T (2, SR (-1, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR (-1, 1), 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR ( 1, 2), 0);
T (2, SR ( 1, 2), 2);
T (2, SR ( 1, 2), 3);
T (2, SR ( 1, 2), 4); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR ( 0, 1), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (2, UR ( 1, 2), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (7, UR (-7, 0), 6);
T (7, UR (-7, 0), 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (7, UR (-3, 2), 2);
T (7, UR (-2, 2), 4); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}
void test_strcpy_array_range_cst_off (const char *s)
{
T (SR (-7, 7), 1, 6);
T (SR (-1, 1), 1, 6);
T (SR (-1, 1), 1, 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 0);
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 4);
T (SR ( 0, 1), 1, 5);
T (UR ( 1, 2), 1, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR (-7, 7), 2, 6);
T (SR (-1, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR (-1, 1), 2, 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR ( 1, 2), 2, 0);
T (SR ( 1, 2), 2, 1);
T (SR ( 1, 2), 2, 2);
T (SR ( 1, 2), 2, 3);
T (SR ( 1, 2), 2, 4); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR ( 0, 1), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (UR ( 1, 2), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}
#undef T
#define T(off1, off2, n) \
do { \
extern char UNIQ_NAME (ga)[7]; \
char *d = UNIQ_NAME (ga) + off1; \
d += off2; \
strncpy (d, s, n); \
sink (d); \
} while (0)
void test_strncpy_array_cst_range_off (const char *s)
{
T (1, SR (-7, 7), 7);
T (1, SR (-1, 1), 7);
T (1, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (1, SR ( 1, 2), 1);
T (1, SR ( 1, 2), 5);
T (1, SR ( 0, 1), 6);
T (1, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR ( -7, 7), 7);
T (2, SR ( -1, 1), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR ( -1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR ( 1, 2), 1);
T (2, SR ( 1, 2), 3);
T (2, SR ( 1, 2), 4);
T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (7, UR (-7, 0), 7);
T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (7, UR (-3, 2), 3);
T (7, UR (-2, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}
void test_strncpy_array_range_cst_off (const char *s)
{
T (SR (-7, 7), 1, 7);
T (SR (-1, 1), 1, 7);
T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 5);
T (SR ( 0, 1), 1, 6);
T (UR ( 1, 2), 1, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR (-7, 7), 2, 7);
T (SR (-1, 1), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR (-1, 1), 2, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR ( 1, 2), 2, 1);
T (SR ( 1, 2), 2, 3);
T (SR ( 1, 2), 2, 4);
T (SR ( 1, 2), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (SR ( 0, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (UR ( 1, 2), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}
void test_strncpy_array_range_range_off (const char *s)
{
T (UR (0, 1), UR (0, 1), 7);
T (UR (3, 5), UR (2, 7), 1);
T (UR (3, 7), UR (2, 9), 2);
T (UR (3, 9), UR (2, 9), 3); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
T (UR (0, 1), UR (1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}