blob: 835c634fd27bffbefa8fb08596c643b41aeef576 [file] [log] [blame]
/* Exercise that -Warray-bounds is issued for out-of-bounds offsets
in calls to built-in functions.
{ dg-do compile }
{ dg-options "-O2 -Warray-bounds=2 -Wno-stringop-overflow -ftrack-macro-expansion=0" } */
#include "../gcc.dg/range.h"
#if __cplusplus
# define restrict __restrict
extern "C" {
#endif
extern void* memcpy (void* restrict, const void* restrict, size_t);
extern void* mempcpy (void* restrict, const void* restrict, size_t);
extern void* memmove (void*, const void*, size_t);
extern char* stpcpy (char* restrict, const char* restrict);
extern char* strcat (char* restrict, const char* restrict);
extern char* strcpy (char* restrict, const char* restrict);
extern char* strncpy (char* restrict, const char* restrict, size_t);
#if __cplusplus
} /* extern "C" */
#endif
struct MA { char a5[5], a7[7]; };
void sink (void*, ...);
void test_memcpy_bounds_memarray_range (void)
{
#undef TM
#define TM(mem, dst, src, n) \
do { \
struct MA ma; \
sink (&ma); /* Initialize arrays. */ \
memcpy (dst, src, n); \
sink (&ma); \
} while (0)
ptrdiff_t j = SR (1, 2);
TM (ma.a5, ma.a5 + j, ma.a5, 1);
TM (ma.a5, ma.a5 + j, ma.a5, 3);
/* The copy below is invalid for two reasons: 1) it overlaps and 2) it
writes past the end of ma.a5. The warning is a little cryptic here
because the GIMPLE is:
_4 = &ma.a5 + prephitmp_14;
MEM <unsigned char[5]> [(char * {ref-all})_4]
= MEM <unsigned char[5]> [(char * {ref-all})&ma];
and could be improved. Just verify that one is issued but not its
full text. */
TM (ma.a5, ma.a5 + j, ma.a5, 5); /* { dg-warning "\\\[-Warray-bounds" "pr101374" { xfail *-*-* } } */
TM (ma.a5, ma.a5 + j, ma.a5, 7); /* { dg-warning "offset \\\[5, 7] from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]. at offset 0" } */
TM (ma.a5, ma.a5 + j, ma.a5, 9); /* { dg-warning "offset \\\[5, 9] from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]. at offset 0" } */
}
#if __i386__ || __x86_64__
/* Disabled for non-x86 targets due to bug 83543. */
void test_strcpy_bounds_memarray_range (void)
{
#undef TM
#define TM(a5init, a7init, dst, src) \
do { \
struct MA ma = { a5init, a7init }; \
strcpy (dst, src); \
sink (&ma); \
} while (0)
ptrdiff_t i = SR (1, 2);
TM ("0", "", ma.a5 + i, ma.a5);
TM ("01", "", ma.a5 + i, ma.a5);
TM ("012", "", ma.a5 + i, ma.a5);
TM ("0123", "", ma.a5 + i, ma.a5); /* { dg-warning "offset 5 from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char *\\\[5]. at offset 0" "pr83543" { xfail { ! { i?86-*-* x86_64-*-* } } } } */
TM ("", "012345", ma.a7 + i, ma.a7); /* { dg-warning "offset 12 from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a7. with type .char ?\\\[7]. at offset 5" "pr83543" { xfail { ! { i?86-*-* x86_64-*-* } } } } */
}
#endif