Fix ICE in substring-handling building 502.gcc_r (PR 87562)
[official-gcc.git] / gcc / testsuite / c-c++-common / Warray-bounds-2.c
blobda5f64df9b7b314b84305b85dd22f6bdb75bb9b5
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 #undef memcpy
15 #undef strcpy
16 #undef strncpy
18 #define MAX (__SIZE_MAX__ / 2)
20 void sink (void*);
22 struct __attribute__ ((packed)) Array
24 char a13[13];
25 char a15[15];
26 char a17[17];
29 /* Exercise memcpy out-of-bounds offsets with an array of known size. */
31 static void
32 wrap_memcpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
34 memcpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar. with type .(struct )?Array." "memcpy" } */
37 void call_memcpy_src_xsize (char *d, size_t n)
39 struct Array ar;
40 sink (&ar);
41 wrap_memcpy_src_xsize (d, ar.a13, 46, n);
42 sink (&ar);
45 /* Exercise memcpy out-of-bounds offsets with an array of unknown size. */
47 static void
48 wrap_memcpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
50 memcpy (d, s + i, n); /* { dg-warning "pointer overflow between offset \[0-9\]+ and size 3" "memcpy" } */
53 void call_memcpy_src_diff_max (char *d, const char *s, size_t n)
55 wrap_memcpy_src_diff_max (d, s, MAX, 3);
58 static void
59 wrap_memcpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
61 memcpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar1. with type .(struct )?Array." "memcpy" } */
64 void call_memcpy_dst_xsize (const char *s, size_t n)
66 struct Array ar1; /* { dg-message ".ar1. declared here" } */
67 sink (&ar1);
68 wrap_memcpy_dst_xsize (ar1.a15, s, 34, n);
69 sink (&ar1);
72 static void
73 wrap_memcpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
75 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" } */
78 void call_memcpy_dst_diff_max (const char *s, size_t n)
80 struct Array ar2; /* { dg-message ".ar2. declared here" } */
81 sink (&ar2);
82 wrap_memcpy_dst_diff_max (ar2.a15, s, MAX, n);
83 sink (&ar2);
87 static void wrap_strcat_src_xsize (char *d, const char *s, ptrdiff_t i)
89 strcat (d, s + i); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar3. with type .(struct )?Array." "strcat" } */
92 void call_strcat_src_xsize (char *d)
94 struct Array ar3; /* { dg-message ".ar3. declared here" } */
95 sink (&ar3);
96 wrap_strcat_src_xsize (d, ar3.a15, 15 + 17 + 1);
97 sink (&ar3);
100 static void wrap_strcat_dst_xsize (char *d, const char *s, ptrdiff_t i)
102 strcat (d + i, s); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar4. with type .(struct )?Array." "strcat" } */
105 void call_strcat_dst_xsize (const char *s)
107 struct Array ar4; /* { dg-message ".ar4. declared here" } */
108 sink (&ar4);
109 wrap_strcat_dst_xsize (ar4.a15, s, 15 + 17 + 2);
110 sink (&ar4);
114 static void wrap_strcpy_src_xsize (char *d, const char *s, ptrdiff_t i)
116 strcpy (d, s + i); /* { dg-warning "offset 48 is out of the bounds \\\[0, 45] of object .ar5. with type .(struct )?Array." "strcpy" } */
119 void call_strcpy_src_xsize (char *d)
121 struct Array ar5; /* { dg-message ".ar5. declared here" } */
122 sink (&ar5);
123 wrap_strcpy_src_xsize (d, ar5.a15, 15 + 17 + 3);
124 sink (&ar5);
127 static void wrap_strcpy_dst_xsize (char *d, const char *s, ptrdiff_t i)
129 strcpy (d + i, s); /* { dg-warning "offset 49 is out of the bounds \\\[0, 45] of object .ar6. with type .(struct )?Array." "strcpy" } */
132 void call_strcpy_dst_xsize (const char *s)
134 struct Array ar6; /* { dg-message ".ar6. declared here" } */
135 sink (&ar6);
136 wrap_strcpy_dst_xsize (ar6.a15, s, 15 + 17 + 4);
137 sink (&ar6);
141 /* Exercise strncpy out-of-bounds offsets with an array of known size. */
143 static void
144 wrap_strncpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
146 strncpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar7. with type '(struct )?Array." "strncpy" } */
149 void call_strncpy_src_xsize (char *d, size_t n)
151 struct Array ar7; /* { dg-message ".ar7. declared here" } */
152 sink (&ar7);
153 wrap_strncpy_src_xsize (d, ar7.a17, 17 + 1, n);
154 sink (&ar7);
157 /* Exercise strncpy out-of-bounds offsets with an array of unknown size. */
159 static void
160 wrap_strncpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
162 /* Unlike in the similar call to memcpy(), there is no pointer
163 overflow here because the size N is not added to the source
164 offset. */
165 strncpy (d, s + i, n);
168 void call_strncpy_src_diff_max (char *d, const char *s, size_t n)
170 wrap_strncpy_src_diff_max (d, s, MAX, 3);
173 static void
174 wrap_strncpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
176 strncpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar8. with type .(struct )?Array." "strncpy" } */
179 void call_strncpy_dst_xsize (const char *s, size_t n)
181 struct Array ar8; /* { dg-message ".ar8. declared here" } */
182 sink (&ar8);
183 wrap_strncpy_dst_xsize (ar8.a17, s, 17 + 2, n);
184 sink (&ar8);
187 static void
188 wrap_strncpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
190 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" } */
193 void call_strncpy_dst_diff_max (const char *s, size_t n)
195 struct Array ar9; /* { dg-message ".ar9. declared here" "strncpy" } */
196 sink (&ar9);
197 wrap_strncpy_dst_diff_max (ar9.a17, s, MAX, n);
198 sink (&ar9);
201 static void
202 wrap_strncpy_dstarray_diff_neg (char *d, const char *s, ptrdiff_t i, size_t n)
204 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" } */
207 void call_strncpy_dstarray_diff_neg (const char *s, size_t n)
209 struct Array ar10[2]; /* { dg-message ".ar10. declared here" } */
210 sink (&ar10);
212 int off = (char*)ar10[1].a17 - (char*)ar10 + 1;
213 wrap_strncpy_dstarray_diff_neg (ar10[1].a17, s, -off, n);
215 sink (&ar10);
218 /* { dg-prune-output "outside array bounds" } */