Require target lra in gcc.dg/pr108095.c
[official-gcc.git] / gcc / testsuite / c-c++-common / Warray-bounds-2.c
blob7400a29d4beec62444dc8dd8e2b9839a1924ce99
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 -fno-tree-vrp" } */
11 #if __has_include (<stddef.h>)
12 # include <stddef.h>
13 #else
14 /* For cross-compilers. */
15 typedef __PTRDIFF_TYPE__ ptrdiff_t;
16 typedef __SIZE_TYPE__ size_t;
17 #endif
19 #if __has_include (<string.h>)
20 # include <string.h>
21 # undef memcpy
22 # undef strcat
23 # undef strcpy
24 # undef strncpy
25 #else
26 extern void* memcpy (void*, const void*, size_t);
27 extern char* strcat (char*, const char*);
28 extern char* strcpy (char*, const char*);
29 extern char* strncpy (char*, const char*, size_t);
30 #endif
33 #define MAX (__SIZE_MAX__ / 2)
35 void sink (void*);
37 struct __attribute__ ((packed)) Array
39 char a13[13];
40 char a15[15];
41 char a17[17];
44 /* Exercise memcpy out-of-bounds offsets with an array of known size. */
46 static void
47 wrap_memcpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
49 memcpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar. with type .(struct )?Array." "memcpy" } */
52 void call_memcpy_src_xsize (char *d, size_t n)
54 struct Array ar;
55 sink (&ar);
56 wrap_memcpy_src_xsize (d, ar.a13, 46, n);
57 sink (&ar);
60 /* Exercise memcpy out-of-bounds offsets with an array of unknown size. */
62 static void
63 wrap_memcpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
65 memcpy (d, s + i, n); /* { dg-warning "pointer overflow between offset \[0-9\]+ and size 3" "memcpy" } */
68 void call_memcpy_src_diff_max (char *d, const char *s, size_t n)
70 wrap_memcpy_src_diff_max (d, s, MAX, 3);
73 static void
74 wrap_memcpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
76 memcpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar1. with type .(struct )?Array." "memcpy" } */
79 void call_memcpy_dst_xsize (const char *s, size_t n)
81 struct Array ar1; /* { dg-message ".ar1. declared here" } */
82 sink (&ar1);
83 wrap_memcpy_dst_xsize (ar1.a15, s, 34, n);
84 sink (&ar1);
87 static void
88 wrap_memcpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
90 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" } */
93 void call_memcpy_dst_diff_max (const char *s, size_t n)
95 struct Array ar2; /* { dg-message ".ar2. declared here" } */
96 sink (&ar2);
97 wrap_memcpy_dst_diff_max (ar2.a15, s, MAX, n);
98 sink (&ar2);
102 static void wrap_strcat_src_xsize (char *d, const char *s, ptrdiff_t i)
104 strcat (d, s + i); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar3. with type .(struct )?Array." "strcat" } */
107 void call_strcat_src_xsize (char *d)
109 struct Array ar3; /* { dg-message ".ar3. declared here" } */
110 sink (&ar3);
111 wrap_strcat_src_xsize (d, ar3.a15, 15 + 17 + 1);
112 sink (&ar3);
115 static void wrap_strcat_dst_xsize (char *d, const char *s, ptrdiff_t i)
117 strcat (d + i, s); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar4. with type .(struct )?Array." "strcat" } */
120 void call_strcat_dst_xsize (const char *s)
122 struct Array ar4; /* { dg-message ".ar4. declared here" } */
123 sink (&ar4);
124 wrap_strcat_dst_xsize (ar4.a15, s, 15 + 17 + 2);
125 sink (&ar4);
129 static void wrap_strcpy_src_xsize (char *d, const char *s, ptrdiff_t i)
131 strcpy (d, s + i); /* { dg-warning "offset 48 is out of the bounds \\\[0, 45] of object .ar5. with type .(struct )?Array." "strcpy" } */
134 void call_strcpy_src_xsize (char *d)
136 struct Array ar5; /* { dg-message ".ar5. declared here" } */
137 sink (&ar5);
138 wrap_strcpy_src_xsize (d, ar5.a15, 15 + 17 + 3);
139 sink (&ar5);
142 static void wrap_strcpy_dst_xsize (char *d, const char *s, ptrdiff_t i)
144 strcpy (d + i, s); /* { dg-warning "offset 49 is out of the bounds \\\[0, 45] of object .ar6. with type .(struct )?Array." "strcpy" } */
147 void call_strcpy_dst_xsize (const char *s)
149 struct Array ar6; /* { dg-message ".ar6. declared here" } */
150 sink (&ar6);
151 wrap_strcpy_dst_xsize (ar6.a15, s, 15 + 17 + 4);
152 sink (&ar6);
156 /* Exercise strncpy out-of-bounds offsets with an array of known size. */
158 static void
159 wrap_strncpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
161 strncpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar7. with type '(struct )?Array." "strncpy" } */
164 void call_strncpy_src_xsize (char *d, size_t n)
166 struct Array ar7; /* { dg-message ".ar7. declared here" } */
167 sink (&ar7);
168 wrap_strncpy_src_xsize (d, ar7.a17, 17 + 1, n);
169 sink (&ar7);
172 /* Exercise strncpy out-of-bounds offsets with an array of unknown size. */
174 static void
175 wrap_strncpy_src_diff_max_m1 (char *d, const char *s, ptrdiff_t i, size_t n)
177 /* Unlike in the similar call to memcpy(), there is no pointer
178 overflow here because the size N is not added to the source
179 offset MAX - 1 (only 1 is for the access to its first element,
180 which is tested below). */
181 strncpy (d, s + i, n);
184 void call_strncpy_src_diff_max_m1 (char *d, const char *s, size_t n)
186 wrap_strncpy_src_diff_max_m1 (d, s, MAX - 1, 3);
189 static void
190 wrap_strncpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
192 strncpy (d, s + i, n); /* { dg-warning "pointer overflow between offset \[0-9\]+ and size \\\[1, 0]" } */
195 void call_strncpy_src_diff_max (char *d, const char *s, size_t n)
197 wrap_strncpy_src_diff_max (d, s, MAX, 3);
200 static void
201 wrap_strncpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
203 strncpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar8. with type .(struct )?Array." "strncpy" } */
206 void call_strncpy_dst_xsize (const char *s, size_t n)
208 struct Array ar8; /* { dg-message ".ar8. declared here" } */
209 sink (&ar8);
210 wrap_strncpy_dst_xsize (ar8.a17, s, 17 + 2, n);
211 sink (&ar8);
214 static void
215 wrap_strncpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
217 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" } */
220 void call_strncpy_dst_diff_max (const char *s, size_t n)
222 struct Array ar9; /* { dg-message ".ar9. declared here" "strncpy" } */
223 sink (&ar9);
224 wrap_strncpy_dst_diff_max (ar9.a17, s, MAX, n);
225 sink (&ar9);
228 static void
229 wrap_strncpy_dstarray_diff_neg (char *d, const char *s, ptrdiff_t i, size_t n)
231 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" } */
234 void call_strncpy_dstarray_diff_neg (const char *s, size_t n)
236 struct Array ar10[2]; /* { dg-message ".ar10. declared here" } */
237 sink (&ar10);
239 int off = (char*)ar10[1].a17 - (char*)ar10 + 1;
240 wrap_strncpy_dstarray_diff_neg (ar10[1].a17, s, -off, n);
242 sink (&ar10);