1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
/* Test to exercise that -Warray-bounds warnings for memory and string
functions are issued even when they are declared in system headers
(i.e., not just when they are explicitly declared in the source
file.)
Also verify that the warnings are issued even for calls where the
source of the excessive array bound is in a different function than
the call.
{ dg-do compile }
{ dg-options "-O2 -Warray-bounds -Wno-stringop-overflow" } */
#include <stddef.h>
#include <string.h>
#define MAX (__SIZE_MAX__ / 2)
void sink (void*);
struct __attribute__ ((packed)) Array
{
char a13[13];
char a15[15];
char a17[17];
};
/* Exercise memcpy out-of-bounds offsets with an array of known size. */
static void
wrap_memcpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
{
memcpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar. with type .(struct )?Array." "memcpy" } */
}
void call_memcpy_src_xsize (char *d, size_t n)
{
struct Array ar;
sink (&ar);
wrap_memcpy_src_xsize (d, ar.a13, 46, n);
sink (&ar);
}
/* Exercise memcpy out-of-bounds offsets with an array of unknown size. */
static void
wrap_memcpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
{
memcpy (d, s + i, n); /* { dg-warning "pointer overflow between offset \[0-9\]+ and size 3" "memcpy" } */
}
void call_memcpy_src_diff_max (char *d, const char *s, size_t n)
{
wrap_memcpy_src_diff_max (d, s, MAX, 3);
}
static void
wrap_memcpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
{
memcpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar1. with type .(struct )?Array." "memcpy" } */
}
void call_memcpy_dst_xsize (const char *s, size_t n)
{
struct Array ar1; /* { dg-message ".ar1. declared here" } */
sink (&ar1);
wrap_memcpy_dst_xsize (ar1.a15, s, 34, n);
sink (&ar1);
}
static void
wrap_memcpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
{
memcpy (d + i, s, n); /* { dg-warning "offset -?\[0-9\]+ is out of the bounds \\\[0, 45] of object .ar2. with type .(struct )?Array." "memcpy" } */
}
void call_memcpy_dst_diff_max (const char *s, size_t n)
{
struct Array ar2; /* { dg-message ".ar2. declared here" } */
sink (&ar2);
wrap_memcpy_dst_diff_max (ar2.a15, s, MAX, n);
sink (&ar2);
}
static void wrap_strcat_src_xsize (char *d, const char *s, ptrdiff_t i)
{
strcat (d, s + i); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar3. with type .(struct )?Array." "strcat" } */
}
void call_strcat_src_xsize (char *d)
{
struct Array ar3; /* { dg-message ".ar3. declared here" } */
sink (&ar3);
wrap_strcat_src_xsize (d, ar3.a15, 15 + 17 + 1);
sink (&ar3);
}
static void wrap_strcat_dst_xsize (char *d, const char *s, ptrdiff_t i)
{
strcat (d + i, s); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar4. with type .(struct )?Array." "strcat" } */
}
void call_strcat_dst_xsize (const char *s)
{
struct Array ar4; /* { dg-message ".ar4. declared here" } */
sink (&ar4);
wrap_strcat_dst_xsize (ar4.a15, s, 15 + 17 + 2);
sink (&ar4);
}
static void wrap_strcpy_src_xsize (char *d, const char *s, ptrdiff_t i)
{
strcpy (d, s + i); /* { dg-warning "offset 48 is out of the bounds \\\[0, 45] of object .ar5. with type .(struct )?Array." "strcpy" } */
}
void call_strcpy_src_xsize (char *d)
{
struct Array ar5; /* { dg-message ".ar5. declared here" } */
sink (&ar5);
wrap_strcpy_src_xsize (d, ar5.a15, 15 + 17 + 3);
sink (&ar5);
}
static void wrap_strcpy_dst_xsize (char *d, const char *s, ptrdiff_t i)
{
strcpy (d + i, s); /* { dg-warning "offset 49 is out of the bounds \\\[0, 45] of object .ar6. with type .(struct )?Array." "strcpy" } */
}
void call_strcpy_dst_xsize (const char *s)
{
struct Array ar6; /* { dg-message ".ar6. declared here" } */
sink (&ar6);
wrap_strcpy_dst_xsize (ar6.a15, s, 15 + 17 + 4);
sink (&ar6);
}
/* Exercise strncpy out-of-bounds offsets with an array of known size. */
static void
wrap_strncpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
{
strncpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar7. with type '(struct )?Array." "strncpy" } */
}
void call_strncpy_src_xsize (char *d, size_t n)
{
struct Array ar7; /* { dg-message ".ar7. declared here" } */
sink (&ar7);
wrap_strncpy_src_xsize (d, ar7.a17, 17 + 1, n);
sink (&ar7);
}
/* Exercise strncpy out-of-bounds offsets with an array of unknown size. */
static void
wrap_strncpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
{
/* Unlike in the similar call to memcpy(), there is no pointer
overflow here because the size N is not added to the source
offset. */
strncpy (d, s + i, n);
}
void call_strncpy_src_diff_max (char *d, const char *s, size_t n)
{
wrap_strncpy_src_diff_max (d, s, MAX, 3);
}
static void
wrap_strncpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
{
strncpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar8. with type .(struct )?Array." "strncpy" } */
}
void call_strncpy_dst_xsize (const char *s, size_t n)
{
struct Array ar8; /* { dg-message ".ar8. declared here" } */
sink (&ar8);
wrap_strncpy_dst_xsize (ar8.a17, s, 17 + 2, n);
sink (&ar8);
}
static void
wrap_strncpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
{
strncpy (d + i, s, n); /* { dg-warning "offset -\[0-9\]+ is out of the bounds \\\[0, 45] of object .ar9. with type .(struct )?Array." "strncpy" } */
}
void call_strncpy_dst_diff_max (const char *s, size_t n)
{
struct Array ar9; /* { dg-message ".ar9. declared here" "strncpy" } */
sink (&ar9);
wrap_strncpy_dst_diff_max (ar9.a17, s, MAX, n);
sink (&ar9);
}
static void
wrap_strncpy_dstarray_diff_neg (char *d, const char *s, ptrdiff_t i, size_t n)
{
strncpy (d + i, s, n); /* { dg-warning "offset -\[0-9\]+ is out of the bounds \\\[0, 90] of object .ar10. with type .(struct )?Array ?\\\[2]." "strncpy" } */
}
void call_strncpy_dstarray_diff_neg (const char *s, size_t n)
{
struct Array ar10[2]; /* { dg-message ".ar10. declared here" } */
sink (&ar10);
int off = (char*)ar10[1].a17 - (char*)ar10 + 1;
wrap_strncpy_dstarray_diff_neg (ar10[1].a17, s, -off, n);
sink (&ar10);
}
|