1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
/* Verify the handling of anti-ranges/multi-ranges by allocation functions
and subsequent accesses.
{ dg-do compile }
{ dg-options "-O2" } */
typedef __SIZE_TYPE__ size_t;
void* malloc (size_t);
void bzero (void*, size_t);
void* memset (void*, int, size_t);
/* Exercise size_t (via malloc and memset) and unsigned/signed int. */
__attribute__ ((alloc_size (1))) void*
alloc_int (int);
__attribute__ ((access (write_only, 1, 2))) void
access_int (void*, int);
__attribute__ ((alloc_size (1))) void*
alloc_uint (unsigned);
__attribute__ ((access (write_only, 1, 2))) void
access_uint (void*, unsigned);
void* nowarn_malloc_memset_same_anti_range (size_t n)
{
/* Set N to the anti-range ~[3, 3]. */
if (n == 3)
n = 4;
void *p = malloc (n);
/* Verify there is no warning for an access to N bytes at P.
This means the warning has to assume the value of N in the call
to alloc() is in the larger subrange [4, UINT_MAX], while in
the call to access() in [0, 3]. */
return memset (p, 0, n);
}
/* Same as above but with two valid ranges. */
void* nowarn_malloc_memset_anti_range (size_t n1, size_t n2)
{
/* Set N1 to the anti-range ~[3, 3]. */
if (n1 == 3)
n1 = 4;
void *p = malloc (n1);
/* Set N2 to the anti-range ~[7, 7]. */
if (n2 == 7)
n2 = 8;
return memset (p, 0, n2);
}
void nowarn_alloc_access_same_anti_range_int (int n)
{
/* Set N to the anti-range ~[3, 3]. */
if (n == 3)
n = 4;
void *p = alloc_int (n);
/* Verify there is no warning for an access to N bytes at P.
This means the warning has to assume the value of N in the call
to alloc() is in the larger subrange [4, UINT_MAX], while in
the call to access() in [0, 3]. */
access_int (p, n);
}
/* Same as above but with two valid ranges. */
void nowarn_alloc_access_anti_range_int (int n1, int n2)
{
/* Set N1 to the anti-range ~[3, 3]. */
if (n1 == 3)
n1 = 4;
void *p = alloc_int (n1);
/* Set N2 to the anti-range ~[7, 7]. */
if (n2 == 7)
n2 = 8;
access_int (p, n2);
}
void nowarn_alloc_access_same_anti_range_uint (unsigned n)
{
/* Set N to the anti-range ~[3, 3]. */
if (n == 3)
n = 4;
void *p = alloc_uint (n);
/* Verify there is no warning for an access to N bytes at P.
This means the warning has to assume the value of N in the call
to alloc() is in the larger subrange [4, UINT_MAX], while in
the call to access() in [0, 3]. */
access_uint (p, n);
}
/* Same as above but with two valid ranges. */
void nowarn_alloc_access_anti_range_uint (unsigned n1, unsigned n2)
{
/* Set N1 to the anti-range ~[3, 3]. */
if (n1 == 3)
n1 = 4;
void *p = alloc_uint (n1);
/* Set N2 to the anti-range ~[7, 7]. */
if (n2 == 7)
n2 = 8;
access_uint (p, n2);
}
void* nowarn_malloc_anti_range_memset_range (size_t n1, size_t n2)
{
/* Set N1 to the anti-range ~[3, 3]. */
if (n1 == 3)
n1 = 4;
void *p = malloc (n1);
/* Set N2 to the range [5, MAX]. */
if (n2 < 5)
n2 = 5;
return memset (p, 0, n2);
}
void* nowarn_malloc_range_bzero_anti_range (size_t n1, size_t n2)
{
/* Set N1 to the anti-range ~[3, 3]. */
if (n1 > 4)
n1 = 4;
void *p = malloc (n1);
/* Set N2 to the range [5, MAX]. */
if (n2 <= 3 || 5 <= n2)
n2 = 4;
bzero (p, n2);
return p;
}
|