PR tree-optimization/86401
[official-gcc.git] / gcc / testsuite / c-c++-common / Warray-bounds-2.c
blobb7e61ddec23d5906e5e61e34d65d3c2eb4e2598e
1 /* Test to exercise that -Warray-bounds warnings for memory and string
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 static void
28 wrap_memcpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
30 memcpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar. with type .(struct )?Array." "memcpy" } */
33 void call_memcpy_src_xsize (char *d, size_t n)
35 struct Array ar;
36 sink (&ar);
37 wrap_memcpy_src_xsize (d, ar.a13, 46, n);
38 sink (&ar);
41 /* Exercise memcpy out-of-bounds offsets with an array of unknown size. */
43 static void
44 wrap_memcpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
46 memcpy (d, s + i, n); /* { dg-warning "pointer overflow between offset \[0-9\]+ and size 3" "memcpy" } */
49 void call_memcpy_src_diff_max (char *d, const char *s, size_t n)
51 wrap_memcpy_src_diff_max (d, s, MAX, 3);
54 static void
55 wrap_memcpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
57 memcpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar1. with type .(struct )?Array." "memcpy" } */
60 void call_memcpy_dst_xsize (const char *s, size_t n)
62 struct Array ar1; /* { dg-message ".ar1. declared here" } */
63 sink (&ar1);
64 wrap_memcpy_dst_xsize (ar1.a15, s, 34, n);
65 sink (&ar1);
68 static void
69 wrap_memcpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
71 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" } */
74 void call_memcpy_dst_diff_max (const char *s, size_t n)
76 struct Array ar2; /* { dg-message ".ar2. declared here" } */
77 sink (&ar2);
78 wrap_memcpy_dst_diff_max (ar2.a15, s, MAX, n);
79 sink (&ar2);
83 static void wrap_strcat_src_xsize (char *d, const char *s, ptrdiff_t i)
85 strcat (d, s + i); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar3. with type .(struct )?Array." "strcat" } */
88 void call_strcat_src_xsize (char *d)
90 struct Array ar3; /* { dg-message ".ar3. declared here" } */
91 sink (&ar3);
92 wrap_strcat_src_xsize (d, ar3.a15, 15 + 17 + 1);
93 sink (&ar3);
96 static void wrap_strcat_dst_xsize (char *d, const char *s, ptrdiff_t i)
98 strcat (d + i, s); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar4. with type .(struct )?Array." "strcat" } */
101 void call_strcat_dst_xsize (const char *s)
103 struct Array ar4; /* { dg-message ".ar4. declared here" } */
104 sink (&ar4);
105 wrap_strcat_dst_xsize (ar4.a15, s, 15 + 17 + 2);
106 sink (&ar4);
110 static void wrap_strcpy_src_xsize (char *d, const char *s, ptrdiff_t i)
112 strcpy (d, s + i); /* { dg-warning "offset 48 is out of the bounds \\\[0, 45] of object .ar5. with type .(struct )?Array." "strcpy" } */
115 void call_strcpy_src_xsize (char *d)
117 struct Array ar5; /* { dg-message ".ar5. declared here" } */
118 sink (&ar5);
119 wrap_strcpy_src_xsize (d, ar5.a15, 15 + 17 + 3);
120 sink (&ar5);
123 static void wrap_strcpy_dst_xsize (char *d, const char *s, ptrdiff_t i)
125 strcpy (d + i, s); /* { dg-warning "offset 49 is out of the bounds \\\[0, 45] of object .ar6. with type .(struct )?Array." "strcpy" } */
128 void call_strcpy_dst_xsize (const char *s)
130 struct Array ar6; /* { dg-message ".ar6. declared here" } */
131 sink (&ar6);
132 wrap_strcpy_dst_xsize (ar6.a15, s, 15 + 17 + 4);
133 sink (&ar6);
137 /* Exercise strncpy out-of-bounds offsets with an array of known size. */
139 static void
140 wrap_strncpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
142 strncpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar7. with type '(struct )?Array." "strncpy" } */
145 void call_strncpy_src_xsize (char *d, size_t n)
147 struct Array ar7; /* { dg-message ".ar7. declared here" } */
148 sink (&ar7);
149 wrap_strncpy_src_xsize (d, ar7.a17, 17 + 1, n);
150 sink (&ar7);
153 /* Exercise strncpy out-of-bounds offsets with an array of unknown size. */
155 static void
156 wrap_strncpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
158 /* Unlike in the similar call to memcpy(), there is no pointer
159 overflow here because the size N is not added to the source
160 offset. */
161 strncpy (d, s + i, n);
164 void call_strncpy_src_diff_max (char *d, const char *s, size_t n)
166 wrap_strncpy_src_diff_max (d, s, MAX, 3);
169 static void
170 wrap_strncpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
172 strncpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar8. with type .(struct )?Array." "strncpy" } */
175 void call_strncpy_dst_xsize (const char *s, size_t n)
177 struct Array ar8; /* { dg-message ".ar8. declared here" } */
178 sink (&ar8);
179 wrap_strncpy_dst_xsize (ar8.a17, s, 17 + 2, n);
180 sink (&ar8);
183 static void
184 wrap_strncpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
186 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" } */
189 void call_strncpy_dst_diff_max (const char *s, size_t n)
191 struct Array ar9; /* { dg-message ".ar9. declared here" "strncpy" } */
192 sink (&ar9);
193 wrap_strncpy_dst_diff_max (ar9.a17, s, MAX, n);
194 sink (&ar9);
197 static void
198 wrap_strncpy_dstarray_diff_neg (char *d, const char *s, ptrdiff_t i, size_t n)
200 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" } */
203 void call_strncpy_dstarray_diff_neg (const char *s, size_t n)
205 struct Array ar10[2]; /* { dg-message ".ar10. declared here" } */
206 sink (&ar10);
208 int off = (char*)ar10[1].a17 - (char*)ar10 + 1;
209 wrap_strncpy_dstarray_diff_neg (ar10[1].a17, s, -off, n);
211 sink (&ar10);