PR target/83368
[official-gcc.git] / gcc / testsuite / c-c++-common / Warray-bounds-2.c
blobbecb3d4f9aaa31676b1d109232d1af4d4ca33623
1 /* Test to exercise that -Warray-bounds warnings for memory and sring
2 functions are issued even when they are declared in system headers
3 (i.e., not just when they are explicitly declared in the source
4 file.)
5 Also verify that the warnings are issued even for calls where the
6 source of the excessive array bound is in a different function than
7 the call.
8 { dg-do compile }
9 { dg-options "-O2 -Warray-bounds -Wno-stringop-overflow" } */
11 #include <stddef.h>
12 #include <string.h>
14 #define MAX (__SIZE_MAX__ / 2)
16 void sink (void*);
18 struct __attribute__ ((packed)) Array
20 char a13[13];
21 char a15[15];
22 char a17[17];
25 /* Exercise memcpy out-of-bounds offsets with an array of known size. */
27 void wrap_memcpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
29 memcpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar. with type .(struct )?Array." "memcpy" } */
32 void call_memcpy_src_xsize (char *d, size_t n)
34 struct Array ar;
35 sink (&ar);
36 wrap_memcpy_src_xsize (d, ar.a13, 46, n);
37 sink (&ar);
40 /* Exercise memcpy out-of-bounds offsets with an array of unknown size. */
42 void wrap_memcpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
44 memcpy (d, s + i, n); /* { dg-warning "pointer overflow between offset \[0-9\]+ and size 3" "memcpy" } */
47 void call_memcpy_src_diff_max (char *d, const char *s, size_t n)
49 wrap_memcpy_src_diff_max (d, s, MAX, 3);
52 void wrap_memcpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
54 memcpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar1. with type .(struct )?Array." "memcpy" } */
57 void call_memcpy_dst_xsize (const char *s, size_t n)
59 struct Array ar1; /* { dg-message ".ar1. declared here" } */
60 sink (&ar1);
61 wrap_memcpy_dst_xsize (ar1.a15, s, 34, n);
62 sink (&ar1);
65 void wrap_memcpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
67 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" } */
70 void call_memcpy_dst_diff_max (const char *s, size_t n)
72 struct Array ar2; /* { dg-message ".ar2. declared here" } */
73 sink (&ar2);
74 wrap_memcpy_dst_diff_max (ar2.a15, s, MAX, n);
75 sink (&ar2);
79 void wrap_strcat_src_xsize (char *d, const char *s, ptrdiff_t i)
81 strcat (d, s + i); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar3. with type .(struct )?Array." "strcat" } */
84 void call_strcat_src_xsize (char *d)
86 struct Array ar3; /* { dg-message ".ar3. declared here" } */
87 sink (&ar3);
88 wrap_strcat_src_xsize (d, ar3.a15, 15 + 17 + 1);
89 sink (&ar3);
92 void wrap_strcat_dst_xsize (char *d, const char *s, ptrdiff_t i)
94 strcat (d + i, s); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar4. with type .(struct )?Array." "strcat" } */
97 void call_strcat_dst_xsize (const char *s)
99 struct Array ar4; /* { dg-message ".ar4. declared here" } */
100 sink (&ar4);
101 wrap_strcat_dst_xsize (ar4.a15, s, 15 + 17 + 2);
102 sink (&ar4);
106 void wrap_strcpy_src_xsize (char *d, const char *s, ptrdiff_t i)
108 strcpy (d, s + i); /* { dg-warning "offset 48 is out of the bounds \\\[0, 45] of object .ar5. with type .(struct )?Array." "strcpy" } */
111 void call_strcpy_src_xsize (char *d)
113 struct Array ar5; /* { dg-message ".ar5. declared here" } */
114 sink (&ar5);
115 wrap_strcpy_src_xsize (d, ar5.a15, 15 + 17 + 3);
116 sink (&ar5);
119 void wrap_strcpy_dst_xsize (char *d, const char *s, ptrdiff_t i)
121 strcpy (d + i, s); /* { dg-warning "offset 49 is out of the bounds \\\[0, 45] of object .ar6. with type .(struct )?Array." "strcpy" } */
124 void call_strcpy_dst_xsize (const char *s)
126 struct Array ar6; /* { dg-message ".ar6. declared here" } */
127 sink (&ar6);
128 wrap_strcpy_dst_xsize (ar6.a15, s, 15 + 17 + 4);
129 sink (&ar6);
133 /* Exercise strncpy out-of-bounds offsets with an array of known size. */
135 void wrap_strncpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
137 strncpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar7. with type '(struct )?Array." "strncpy" } */
140 void call_strncpy_src_xsize (char *d, size_t n)
142 struct Array ar7; /* { dg-message ".ar7. declared here" } */
143 sink (&ar7);
144 wrap_strncpy_src_xsize (d, ar7.a17, 17 + 1, n);
145 sink (&ar7);
148 /* Exercise strncpy out-of-bounds offsets with an array of unknown size. */
150 void wrap_strncpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
152 /* Unlike in the similar call to memcpy(), there is no pointer
153 overflow here because the size N is not added to the source
154 offset. */
155 strncpy (d, s + i, n);
158 void call_strncpy_src_diff_max (char *d, const char *s, size_t n)
160 wrap_strncpy_src_diff_max (d, s, MAX, 3);
163 void wrap_strncpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
165 strncpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar8. with type .(struct )?Array." "strncpy" } */
168 void call_strncpy_dst_xsize (const char *s, size_t n)
170 struct Array ar8; /* { dg-message ".ar8. declared here" } */
171 sink (&ar8);
172 wrap_strncpy_dst_xsize (ar8.a17, s, 17 + 2, n);
173 sink (&ar8);
176 void wrap_strncpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
178 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" } */
181 void call_strncpy_dst_diff_max (const char *s, size_t n)
183 struct Array ar9; /* { dg-message ".ar9. declared here" } */
184 sink (&ar9);
185 wrap_strncpy_dst_diff_max (ar9.a17, s, MAX, n);
186 sink (&ar9);
189 void wrap_strncpy_dstarray_diff_neg (char *d, const char *s, ptrdiff_t i,
190 size_t n)
192 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" } */
195 void call_strncpy_dstarray_diff_neg (const char *s, size_t n)
197 struct Array ar10[2]; /* { dg-message ".ar10. declared here" } */
198 sink (&ar10);
200 int off = (char*)ar10[1].a17 - (char*)ar10 + 1;
201 wrap_strncpy_dstarray_diff_neg (ar10[1].a17, s, -off, n);
203 sink (&ar10);