1 /* PR c/78284 - warn on malloc with very large arguments
2 Test exercising the ability to detect and diagnose calls to allocation
3 functions decorated with attribute alloc_size that attempt to allocate
4 zero bytes. For standard allocation functions the return value is
5 implementation-defined and so relying on it may be a source of bugs. */
6 /* { dg-do compile } */
7 /* { dg-options "-O2 -Wall -Walloc-zero" } */
8
9 #define SCHAR_MAX __SCHAR_MAX__
10 #define SCHAR_MIN (-SCHAR_MAX - 1)
11 #define UCHAR_MAX (SCHAR_MAX * 2 + 1)
12
13 #define SHRT_MAX __SHRT_MAX__
14 #define SHRT_MIN (-SHRT_MAX - 1)
15 #define USHRT_MAX (SHRT_MAX * 2 + 1)
16
17 #define INT_MAX __INT_MAX__
18 #define INT_MIN (-INT_MAX - 1)
19 #define UINT_MAX (INT_MAX * 2U + 1)
20
21 #define LONG_MAX __LONG_MAX__
22 #define LONG_MIN (-LONG_MAX - 1L)
23 #define ULONG_MAX (LONG_MAX * 2LU + 1)
24
25 #define LLONG_MAX __LLONG_MAX__
26 #define LLONG_MIN (-LLONG_MAX - 1LL)
27 #define ULLONG_MAX (ULLONG_MAX * 2LLU + 1)
28
29 #define SIZE_MAX __SIZE_MAX__
30
31 typedef __SIZE_TYPE__ size_t;
32
33
34 #define ALLOC_SIZE(...) __attribute__ ((alloc_size (__VA_ARGS__)))
35
36 void* f_uchar_1 (unsigned char) ALLOC_SIZE (1);
37 void* f_uchar_2 (unsigned char, unsigned char) ALLOC_SIZE (1, 2);
38 void* f_schar_1 (signed char) ALLOC_SIZE (1);
39 void* f_schar_2 (signed char, signed char) ALLOC_SIZE (1, 2);
40
41 void* f_ushrt_1 (unsigned short) ALLOC_SIZE (1);
42 void* f_ushrt_2 (unsigned short, unsigned short) ALLOC_SIZE (1, 2);
43 void* f_shrt_1 (signed short) ALLOC_SIZE (1);
44 void* f_shrt_2 (signed short, signed short) ALLOC_SIZE (1, 2);
45
46 void* f_uint_1 (unsigned) ALLOC_SIZE (1);
47 void* f_uint_2 (unsigned, unsigned) ALLOC_SIZE (1, 2);
48 void* f_int_1 (int) ALLOC_SIZE (1);
49 void* f_int_2 (int, int) ALLOC_SIZE (1, 2);
50
51 void* f_ulong_1 (unsigned long) ALLOC_SIZE (1);
52 void* f_ulong_2 (unsigned long, unsigned long) ALLOC_SIZE (1, 2);
53 void* f_long_1 (long) ALLOC_SIZE (1);
54 void* f_long_2 (long, long) ALLOC_SIZE (1, 2);
55
56 void* f_ullong_1 (unsigned long long) ALLOC_SIZE (1);
57 void* f_ullong_2 (unsigned long long, unsigned long long) ALLOC_SIZE (1, 2);
58 void* f_llong_1 (long long) ALLOC_SIZE (1);
59 void* f_llong_2 (long long, long long) ALLOC_SIZE (1, 2);
60
61 void* f_size_1 (size_t) ALLOC_SIZE (1);
62 void* f_size_2 (size_t, size_t) ALLOC_SIZE (1, 2);
63
64 void* f_size_1_nonnull (size_t)
65 ALLOC_SIZE (1) __attribute__ ((returns_nonnull));
66 void* f_size_2_nonnull (size_t, size_t)
67 ALLOC_SIZE (1, 2) __attribute__ ((returns_nonnull));
68
69 void sink (void*);
70
71 void
test_uchar(unsigned char n)72 test_uchar (unsigned char n)
73 {
74 sink (f_uchar_1 (0)); /* { dg-warning "argument 1 value is zero" } */
75 sink (f_uchar_2 (0, 1)); /* { dg-warning "argument 1 value is zero" } */
76 sink (f_uchar_2 (1, 0)); /* { dg-warning "argument 2 value is zero" } */
77 sink (f_uchar_2 (n, 0)); /* { dg-warning "argument 2 value is zero" } */
78 sink (f_uchar_2 (0, n)); /* { dg-warning "argument 1 value is zero" } */
79
80 sink (f_uchar_1 (n));
81 n = 0;
82 sink (f_uchar_1 (n)); /* { dg-warning "argument 1 value is zero" } */
83 sink (f_uchar_2 (1, n)); /* { dg-warning "argument 2 value is zero" } */
84 }
85
86 void
test_schar(signed char n)87 test_schar (signed char n)
88 {
89 sink (f_schar_1 (0)); /* { dg-warning "argument 1 value is zero" } */
90 sink (f_schar_2 (0, 1)); /* { dg-warning "argument 1 value is zero" } */
91 sink (f_schar_2 (1, 0)); /* { dg-warning "argument 2 value is zero" } */
92 sink (f_schar_2 (n, 0)); /* { dg-warning "argument 2 value is zero" } */
93 sink (f_schar_2 (0, n)); /* { dg-warning "argument 1 value is zero" } */
94
95 sink (f_schar_1 (n));
96 n = 0;
97 sink (f_schar_1 (n)); /* { dg-warning "argument 1 value is zero" } */
98 sink (f_schar_2 (1, n)); /* { dg-warning "argument 2 value is zero" } */
99 }
100
101 void
test_ushrt(unsigned short n)102 test_ushrt (unsigned short n)
103 {
104 sink (f_ushrt_1 (0)); /* { dg-warning "argument 1 value is zero" } */
105 sink (f_ushrt_2 (0, 1)); /* { dg-warning "argument 1 value is zero" } */
106 sink (f_ushrt_2 (1, 0)); /* { dg-warning "argument 2 value is zero" } */
107 sink (f_ushrt_2 (n, 0)); /* { dg-warning "argument 2 value is zero" } */
108 sink (f_ushrt_2 (0, n)); /* { dg-warning "argument 1 value is zero" } */
109
110 sink (f_ushrt_1 (n));
111 n = 0;
112 sink (f_ushrt_1 (n)); /* { dg-warning "argument 1 value is zero" } */
113 sink (f_ushrt_2 (1, n)); /* { dg-warning "argument 2 value is zero" } */
114 }
115
116 void
test_shrt(short n)117 test_shrt (short n)
118 {
119 sink (f_shrt_1 (0)); /* { dg-warning "argument 1 value is zero" } */
120 sink (f_shrt_2 (0, 1)); /* { dg-warning "argument 1 value is zero" } */
121 sink (f_shrt_2 (1, 0)); /* { dg-warning "argument 2 value is zero" } */
122 sink (f_shrt_2 (n, 0)); /* { dg-warning "argument 2 value is zero" } */
123 sink (f_shrt_2 (0, n)); /* { dg-warning "argument 1 value is zero" } */
124
125 sink (f_shrt_1 (n));
126 n = 0;
127 sink (f_shrt_1 (n)); /* { dg-warning "argument 1 value is zero" } */
128 sink (f_shrt_2 (1, n)); /* { dg-warning "argument 2 value is zero" } */
129 }
130
131 void
test_uint(unsigned n)132 test_uint (unsigned n)
133 {
134 sink (f_uint_1 (0)); /* { dg-warning "argument 1 value is zero" } */
135 sink (f_uint_2 (0, 1)); /* { dg-warning "argument 1 value is zero" } */
136 sink (f_uint_2 (1, 0)); /* { dg-warning "argument 2 value is zero" } */
137 sink (f_uint_2 (n, 0)); /* { dg-warning "argument 2 value is zero" } */
138 sink (f_uint_2 (0, n)); /* { dg-warning "argument 1 value is zero" } */
139
140 sink (f_uint_1 (n));
141 n = 0;
142 sink (f_uint_1 (n)); /* { dg-warning "argument 1 value is zero" } */
143 sink (f_uint_2 (1, n)); /* { dg-warning "argument 2 value is zero" } */
144 }
145
146 void
test_int(int n)147 test_int (int n)
148 {
149 sink (f_int_1 (0)); /* { dg-warning "argument 1 value is zero" } */
150 sink (f_int_2 (0, 1)); /* { dg-warning "argument 1 value is zero" } */
151 sink (f_int_2 (1, 0)); /* { dg-warning "argument 2 value is zero" } */
152 sink (f_int_2 (n, 0)); /* { dg-warning "argument 2 value is zero" } */
153 sink (f_int_2 (0, n)); /* { dg-warning "argument 1 value is zero" } */
154
155 sink (f_int_1 (n));
156 n = 0;
157 sink (f_int_1 (n)); /* { dg-warning "argument 1 value is zero" } */
158 sink (f_int_2 (1, n)); /* { dg-warning "argument 2 value is zero" } */
159 }
160
161 void
test_ulong(unsigned long n)162 test_ulong (unsigned long n)
163 {
164 sink (f_ulong_1 (0)); /* { dg-warning "argument 1 value is zero" } */
165 sink (f_ulong_2 (0, 1)); /* { dg-warning "argument 1 value is zero" } */
166 sink (f_ulong_2 (1, 0)); /* { dg-warning "argument 2 value is zero" } */
167 sink (f_ulong_2 (n, 0)); /* { dg-warning "argument 2 value is zero" } */
168 sink (f_ulong_2 (0, n)); /* { dg-warning "argument 1 value is zero" } */
169
170 sink (f_ulong_1 (n));
171 n = 0;
172 sink (f_ulong_1 (n)); /* { dg-warning "argument 1 value is zero" } */
173 sink (f_ulong_2 (1, n)); /* { dg-warning "argument 2 value is zero" } */
174 }
175
176 void
test_long(long n)177 test_long (long n)
178 {
179 sink (f_long_1 (0)); /* { dg-warning "argument 1 value is zero" } */
180 sink (f_long_2 (0, 1)); /* { dg-warning "argument 1 value is zero" } */
181 sink (f_long_2 (1, 0)); /* { dg-warning "argument 2 value is zero" } */
182 sink (f_long_2 (n, 0)); /* { dg-warning "argument 2 value is zero" } */
183 sink (f_long_2 (0, n)); /* { dg-warning "argument 1 value is zero" } */
184
185 sink (f_long_1 (n));
186 n = 0;
187 sink (f_long_1 (n)); /* { dg-warning "argument 1 value is zero" } */
188 sink (f_long_2 (1, n)); /* { dg-warning "argument 2 value is zero" } */
189 }
190
191 void
test_size(size_t n)192 test_size (size_t n)
193 {
194 sink (f_size_1 (0)); /* { dg-warning "argument 1 value is zero" } */
195 sink (f_size_2 (0, 1)); /* { dg-warning "argument 1 value is zero" } */
196 sink (f_size_2 (1, 0)); /* { dg-warning "argument 2 value is zero" } */
197 sink (f_size_2 (n, 0)); /* { dg-warning "argument 2 value is zero" } */
198 sink (f_size_2 (0, n)); /* { dg-warning "argument 1 value is zero" } */
199
200 sink (f_size_1 (n));
201 n = 0;
202 sink (f_size_1 (n)); /* { dg-warning "argument 1 value is zero" } */
203 sink (f_size_2 (1, n)); /* { dg-warning "argument 2 value is zero" } */
204 }
205
206 /* Verify that calls to allocation function decorated with attribute
207 returns_nonnull don't cause warnings (unlike functions like malloc
208 that can return null in this case there's nothing to warn about
209 because a returns_nonnull function guarantees success). */
210
211 void
test_size_nonnull(size_t n)212 test_size_nonnull (size_t n)
213 {
214 sink (f_size_1_nonnull (0));
215 sink (f_size_2_nonnull (0, 1));
216 sink (f_size_2_nonnull (1, 0));
217 sink (f_size_2_nonnull (n, 0));
218 sink (f_size_2_nonnull (0, n));
219
220 sink (f_size_1_nonnull (n));
221 n = 0;
222 sink (f_size_1_nonnull (n));
223 sink (f_size_2_nonnull (1, n));
224 }
225
226 /* Verify that call to plain alloca(0) is not diagnosed. */
227
228 void
test_alloca(size_t n)229 test_alloca (size_t n)
230 {
231 extern void* alloca (size_t);
232
233 alloca (0);
234 }
235