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
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
9 { dg-options "-O2 -Warray-bounds -Wno-stringop-overflow -fno-tree-vrp" } */
11 #if __has_include (<stddef.h>)
14 /* For cross-compilers. */
15 typedef __PTRDIFF_TYPE__
ptrdiff_t;
16 typedef __SIZE_TYPE__
size_t;
19 #if __has_include (<string.h>)
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);
33 #define MAX (__SIZE_MAX__ / 2)
37 struct __attribute__ ((packed
)) Array
44 /* Exercise memcpy out-of-bounds offsets with an array of known size. */
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
)
56 wrap_memcpy_src_xsize (d
, ar
.a13
, 46, n
);
60 /* Exercise memcpy out-of-bounds offsets with an array of unknown size. */
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);
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" } */
83 wrap_memcpy_dst_xsize (ar1
.a15
, s
, 34, n
);
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" } */
97 wrap_memcpy_dst_diff_max (ar2
.a15
, s
, MAX
, n
);
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" } */
111 wrap_strcat_src_xsize (d
, ar3
.a15
, 15 + 17 + 1);
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" } */
124 wrap_strcat_dst_xsize (ar4
.a15
, s
, 15 + 17 + 2);
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" } */
138 wrap_strcpy_src_xsize (d
, ar5
.a15
, 15 + 17 + 3);
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" } */
151 wrap_strcpy_dst_xsize (ar6
.a15
, s
, 15 + 17 + 4);
156 /* Exercise strncpy out-of-bounds offsets with an array of known size. */
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" } */
168 wrap_strncpy_src_xsize (d
, ar7
.a17
, 17 + 1, n
);
172 /* Exercise strncpy out-of-bounds offsets with an array of unknown size. */
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);
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);
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" } */
210 wrap_strncpy_dst_xsize (ar8
.a17
, s
, 17 + 2, n
);
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" } */
224 wrap_strncpy_dst_diff_max (ar9
.a17
, s
, MAX
, n
);
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" } */
239 int off
= (char*)ar10
[1].a17
- (char*)ar10
+ 1;
240 wrap_strncpy_dstarray_diff_neg (ar10
[1].a17
, s
, -off
, n
);