]>
Commit | Line | Data |
---|---|---|
83685efd MS |
1 | /* Verify that writes at excessive offsets into objects of unknown size |
2 | pointed to by function arguments are diagnosed. | |
3 | { dg-do compile } | |
4 | { dg-options "-O2" } */ | |
5 | ||
6 | #define DIFF_MAX __PTRDIFF_MAX__ | |
7 | ||
8 | typedef __PTRDIFF_TYPE__ ptrdiff_t; | |
9 | typedef __SIZE_TYPE__ size_t; | |
10 | ||
11 | void* memset (void*, int, size_t); | |
12 | ||
13 | void sink (void*); | |
14 | ||
15 | char* fcall (void); | |
16 | ||
17 | void char_ptr_cst_off_cst_size (char *p) | |
18 | // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'p'" "note" { target *-*-* } .-1 } | |
19 | { | |
20 | size_t idx = DIFF_MAX - 3; | |
21 | ||
22 | memset (p + idx, 0, 3); | |
23 | sink (p); | |
24 | ||
25 | ++idx; | |
26 | memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 2" } | |
27 | sink (p); | |
28 | ||
29 | ++idx; | |
30 | memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 1" } | |
31 | ||
32 | ++idx; | |
33 | memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 0" } | |
34 | } | |
35 | ||
36 | ||
37 | void char_ptr_var_difoff_cst_size (ptrdiff_t idx) | |
38 | { | |
39 | char *p = fcall (); | |
40 | /* The offset is a range with a very large lower bound and an upper | |
41 | bound of DIFF_MAX. There's not point in also mentioning the latter | |
42 | (it wouldn't make the note any more meaningful) so verify it only | |
43 | mentions the lower bound. | |
44 | { dg-message "at offset \\d+ into destination object of size \\\[0, \\d+] (allocated|returned) by 'fcall'" "note" { target *-*-* } .-5 } */ | |
45 | ||
46 | if (idx < DIFF_MAX - 3) | |
47 | idx = DIFF_MAX - 3; | |
48 | ||
49 | memset (p + idx, 0, 3); | |
50 | sink (p); | |
51 | ||
52 | memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" } | |
53 | } | |
54 | ||
55 | ||
56 | void char_ptr_var_szoff_cst_size (size_t idx) | |
57 | { | |
58 | extern char* gptr; | |
59 | // { dg-message "at offset \\d+ into destination object 'gptr'" "note" { target *-*-* } .-1 } | |
60 | ||
61 | char *p = gptr; | |
62 | ||
63 | if (idx < DIFF_MAX - 3) | |
64 | idx = DIFF_MAX - 3; | |
65 | ||
66 | memset (p + idx, 0, 3); | |
67 | sink (p); | |
68 | ||
69 | memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" "" { xfail *-*-* } } | |
70 | ||
71 | if (idx > DIFF_MAX) | |
72 | idx = DIFF_MAX; | |
73 | ||
74 | memset (p + idx, 0, 7); // { dg-warning "writing 7 bytes into a region of size 3" } | |
75 | } | |
76 | ||
77 | ||
78 | void char_ptr_var_difoff_var_size (char *p, ptrdiff_t idx, size_t n) | |
79 | // { dg-message "at offset \\d+ into destination object 'p'" "note" { target *-*-* } .-1 } | |
80 | { | |
81 | if (idx < DIFF_MAX - 3) | |
82 | idx = DIFF_MAX - 3; | |
83 | ||
84 | if (n < 3 || 7 < n) | |
85 | n = 3; | |
86 | ||
87 | memset (p + idx, 0, n); | |
88 | sink (p); | |
89 | ||
90 | ++n; | |
91 | memset (p + idx, 0, n); // { dg-warning "writing between 4 and 8 bytes into a region of size 3" } | |
92 | } | |
93 | ||
94 | ||
95 | void char_ptr_var_szoff_var_size (char *p, size_t idx, size_t n) | |
96 | // { dg-message "at offset \\\[\[1-9\]\[0-9\]+, \[1-9\]\[0-9\]+] into destination object 'p'" "note" { xfail *-*-* } .-1 } | |
97 | { | |
98 | if (idx < DIFF_MAX - 3) | |
99 | idx = DIFF_MAX - 3; | |
100 | ||
101 | if (n < 3 || 7 < n) | |
102 | n = 3; | |
103 | ||
104 | memset (p + idx, 0, n); | |
105 | sink (p); | |
106 | ||
107 | ++n; | |
108 | /* With an unsigned offset large values are interpreted as negative | |
109 | so the addition (p + idx) is effectively treated as subtraction, | |
110 | making an overflow indistinguishable from a valid (if unlikely) | |
111 | store. */ | |
112 | memset (p + idx, 0, n); // { dg-warning "writing between 4 and 8 bytes into a region of size 3" "pr?????" { xfail *-*-* } } | |
113 | } | |
114 | ||
115 | ||
116 | void int_ptr_cst_off_cst_size (int *p) | |
117 | // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'p'" "note" { target *-*-* } .-1 } | |
118 | { | |
119 | size_t idx = DIFF_MAX / sizeof *p; | |
120 | ||
121 | memset (p + idx, 0, 3); | |
122 | sink (p); | |
123 | ||
124 | memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" } | |
125 | } |