]>
Commit | Line | Data |
---|---|---|
da6cf191 | 1 | /* Warn on problematic uses of alloca and variable length arrays. |
fbd26352 | 2 | Copyright (C) 2016-2019 Free Software Foundation, Inc. |
da6cf191 | 3 | Contributed by Aldy Hernandez <aldyh@redhat.com>. |
4 | ||
5 | This file is part of GCC. | |
6 | ||
7 | GCC is free software; you can redistribute it and/or modify it under | |
8 | the terms of the GNU General Public License as published by the Free | |
9 | Software Foundation; either version 3, or (at your option) any later | |
10 | version. | |
11 | ||
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GCC; see the file COPYING3. If not see | |
19 | <http://www.gnu.org/licenses/>. */ | |
20 | ||
21 | #include "config.h" | |
22 | #include "system.h" | |
23 | #include "coretypes.h" | |
24 | #include "backend.h" | |
25 | #include "tree.h" | |
26 | #include "gimple.h" | |
27 | #include "tree-pass.h" | |
28 | #include "ssa.h" | |
29 | #include "gimple-pretty-print.h" | |
30 | #include "diagnostic-core.h" | |
31 | #include "fold-const.h" | |
32 | #include "gimple-iterator.h" | |
33 | #include "tree-ssa.h" | |
34 | #include "params.h" | |
35 | #include "tree-cfg.h" | |
8e18705e | 36 | #include "builtins.h" |
da6cf191 | 37 | #include "calls.h" |
38 | #include "cfgloop.h" | |
39 | #include "intl.h" | |
40 | ||
48cccec0 | 41 | static unsigned HOST_WIDE_INT adjusted_warn_limit (bool); |
42 | ||
da6cf191 | 43 | const pass_data pass_data_walloca = { |
44 | GIMPLE_PASS, | |
45 | "walloca", | |
46 | OPTGROUP_NONE, | |
47 | TV_NONE, | |
48 | PROP_cfg, // properties_required | |
49 | 0, // properties_provided | |
50 | 0, // properties_destroyed | |
51 | 0, // properties_start | |
52 | 0, // properties_finish | |
53 | }; | |
54 | ||
55 | class pass_walloca : public gimple_opt_pass | |
56 | { | |
57 | public: | |
58 | pass_walloca (gcc::context *ctxt) | |
59 | : gimple_opt_pass(pass_data_walloca, ctxt), first_time_p (false) | |
60 | {} | |
61 | opt_pass *clone () { return new pass_walloca (m_ctxt); } | |
62 | void set_pass_param (unsigned int n, bool param) | |
63 | { | |
64 | gcc_assert (n == 0); | |
65 | first_time_p = param; | |
66 | } | |
67 | virtual bool gate (function *); | |
68 | virtual unsigned int execute (function *); | |
69 | ||
70 | private: | |
71 | // Set to TRUE the first time we run this pass on a function. | |
72 | bool first_time_p; | |
73 | }; | |
74 | ||
75 | bool | |
76 | pass_walloca::gate (function *fun ATTRIBUTE_UNUSED) | |
77 | { | |
78 | // The first time this pass is called, it is called before | |
79 | // optimizations have been run and range information is unavailable, | |
80 | // so we can only perform strict alloca checking. | |
81 | if (first_time_p) | |
82 | return warn_alloca != 0; | |
83 | ||
8e18705e | 84 | // Warning is disabled when its size limit is greater than PTRDIFF_MAX |
85 | // for the target maximum, which makes the limit negative since when | |
86 | // represented in signed HOST_WIDE_INT. | |
48cccec0 | 87 | unsigned HOST_WIDE_INT max = tree_to_uhwi (TYPE_MAX_VALUE (ptrdiff_type_node)); |
88 | return (adjusted_warn_limit (false) <= max | |
89 | || adjusted_warn_limit (true) <= max); | |
da6cf191 | 90 | } |
91 | ||
92 | // Possible problematic uses of alloca. | |
93 | enum alloca_type { | |
94 | // Alloca argument is within known bounds that are appropriate. | |
95 | ALLOCA_OK, | |
96 | ||
97 | // Alloca argument is KNOWN to have a value that is too large. | |
98 | ALLOCA_BOUND_DEFINITELY_LARGE, | |
99 | ||
100 | // Alloca argument may be too large. | |
101 | ALLOCA_BOUND_MAYBE_LARGE, | |
102 | ||
103 | // Alloca argument is bounded but of an indeterminate size. | |
104 | ALLOCA_BOUND_UNKNOWN, | |
105 | ||
106 | // Alloca argument was casted from a signed integer. | |
107 | ALLOCA_CAST_FROM_SIGNED, | |
108 | ||
109 | // Alloca appears in a loop. | |
110 | ALLOCA_IN_LOOP, | |
111 | ||
112 | // Alloca argument is 0. | |
113 | ALLOCA_ARG_IS_ZERO, | |
114 | ||
115 | // Alloca call is unbounded. That is, there is no controlling | |
116 | // predicate for its argument. | |
117 | ALLOCA_UNBOUNDED | |
118 | }; | |
119 | ||
120 | // Type of an alloca call with its corresponding limit, if applicable. | |
251317e4 | 121 | class alloca_type_and_limit { |
122 | public: | |
da6cf191 | 123 | enum alloca_type type; |
124 | // For ALLOCA_BOUND_MAYBE_LARGE and ALLOCA_BOUND_DEFINITELY_LARGE | |
125 | // types, this field indicates the assumed limit if known or | |
126 | // integer_zero_node if unknown. For any other alloca types, this | |
127 | // field is undefined. | |
128 | wide_int limit; | |
129 | alloca_type_and_limit (); | |
130 | alloca_type_and_limit (enum alloca_type type, | |
131 | wide_int i) : type(type), limit(i) { } | |
7b19df43 | 132 | alloca_type_and_limit (enum alloca_type type) : type(type) |
133 | { if (type == ALLOCA_BOUND_MAYBE_LARGE | |
134 | || type == ALLOCA_BOUND_DEFINITELY_LARGE) | |
135 | limit = wi::to_wide (integer_zero_node); | |
136 | } | |
da6cf191 | 137 | }; |
138 | ||
48cccec0 | 139 | /* Return the value of the argument N to -Walloca-larger-than= or |
140 | -Wvla-larger-than= adjusted for the target data model so that | |
141 | when N == HOST_WIDE_INT_MAX, the adjusted value is set to | |
142 | PTRDIFF_MAX on the target. This is done to prevent warnings | |
143 | for unknown/unbounded allocations in the "permissive mode" | |
144 | while still diagnosing excessive and necessarily invalid | |
145 | allocations. */ | |
146 | ||
147 | static unsigned HOST_WIDE_INT | |
148 | adjusted_warn_limit (bool idx) | |
149 | { | |
150 | static HOST_WIDE_INT limits[2]; | |
151 | if (limits[idx]) | |
152 | return limits[idx]; | |
153 | ||
154 | limits[idx] = idx ? warn_vla_limit : warn_alloca_limit; | |
155 | if (limits[idx] != HOST_WIDE_INT_MAX) | |
156 | return limits[idx]; | |
157 | ||
158 | limits[idx] = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node)); | |
159 | return limits[idx]; | |
160 | } | |
161 | ||
162 | ||
da6cf191 | 163 | // NOTE: When we get better range info, this entire function becomes |
164 | // irrelevant, as it should be possible to get range info for an SSA | |
165 | // name at any point in the program. | |
166 | // | |
167 | // We have a few heuristics up our sleeve to determine if a call to | |
168 | // alloca() is within bounds. Try them out and return the type of | |
169 | // alloca call with its assumed limit (if applicable). | |
170 | // | |
171 | // Given a known argument (ARG) to alloca() and an EDGE (E) | |
172 | // calculating said argument, verify that the last statement in the BB | |
173 | // in E->SRC is a gate comparing ARG to an acceptable bound for | |
174 | // alloca(). See examples below. | |
175 | // | |
176 | // If set, ARG_CASTED is the possible unsigned argument to which ARG | |
177 | // was casted to. This is to handle cases where the controlling | |
178 | // predicate is looking at a casted value, not the argument itself. | |
179 | // arg_casted = (size_t) arg; | |
180 | // if (arg_casted < N) | |
181 | // goto bb3; | |
182 | // else | |
183 | // goto bb5; | |
184 | // | |
185 | // MAX_SIZE is WARN_ALLOCA= adjusted for VLAs. It is the maximum size | |
186 | // in bytes we allow for arg. | |
187 | ||
2e966e2a | 188 | static class alloca_type_and_limit |
8e18705e | 189 | alloca_call_type_by_arg (tree arg, tree arg_casted, edge e, |
190 | unsigned HOST_WIDE_INT max_size) | |
da6cf191 | 191 | { |
192 | basic_block bb = e->src; | |
193 | gimple_stmt_iterator gsi = gsi_last_bb (bb); | |
194 | gimple *last = gsi_stmt (gsi); | |
8e18705e | 195 | |
196 | const offset_int maxobjsize = tree_to_shwi (max_object_size ()); | |
197 | ||
198 | /* When MAX_SIZE is greater than or equal to PTRDIFF_MAX treat | |
199 | allocations that aren't visibly constrained as OK, otherwise | |
200 | report them as (potentially) unbounded. */ | |
201 | alloca_type unbounded_result = (max_size < maxobjsize.to_uhwi () | |
202 | ? ALLOCA_UNBOUNDED : ALLOCA_OK); | |
203 | ||
da6cf191 | 204 | if (!last || gimple_code (last) != GIMPLE_COND) |
8e18705e | 205 | { |
206 | return alloca_type_and_limit (unbounded_result); | |
207 | } | |
da6cf191 | 208 | |
209 | enum tree_code cond_code = gimple_cond_code (last); | |
210 | if (e->flags & EDGE_TRUE_VALUE) | |
211 | ; | |
212 | else if (e->flags & EDGE_FALSE_VALUE) | |
213 | cond_code = invert_tree_comparison (cond_code, false); | |
214 | else | |
8e18705e | 215 | return alloca_type_and_limit (unbounded_result); |
da6cf191 | 216 | |
217 | // Check for: | |
218 | // if (ARG .COND. N) | |
219 | // goto <bb 3>; | |
220 | // else | |
221 | // goto <bb 4>; | |
222 | // <bb 3>: | |
223 | // alloca(ARG); | |
224 | if ((cond_code == LE_EXPR | |
225 | || cond_code == LT_EXPR | |
226 | || cond_code == GT_EXPR | |
227 | || cond_code == GE_EXPR) | |
228 | && (gimple_cond_lhs (last) == arg | |
229 | || gimple_cond_lhs (last) == arg_casted)) | |
230 | { | |
231 | if (TREE_CODE (gimple_cond_rhs (last)) == INTEGER_CST) | |
232 | { | |
233 | tree rhs = gimple_cond_rhs (last); | |
234 | int tst = wi::cmpu (wi::to_widest (rhs), max_size); | |
235 | if ((cond_code == LT_EXPR && tst == -1) | |
236 | || (cond_code == LE_EXPR && (tst == -1 || tst == 0))) | |
237 | return alloca_type_and_limit (ALLOCA_OK); | |
238 | else | |
239 | { | |
240 | // Let's not get too specific as to how large the limit | |
241 | // may be. Someone's clearly an idiot when things | |
242 | // degrade into "if (N > Y) alloca(N)". | |
243 | if (cond_code == GT_EXPR || cond_code == GE_EXPR) | |
244 | rhs = integer_zero_node; | |
e3d0f65c | 245 | return alloca_type_and_limit (ALLOCA_BOUND_MAYBE_LARGE, |
246 | wi::to_wide (rhs)); | |
da6cf191 | 247 | } |
248 | } | |
249 | else | |
c5ed61e5 | 250 | { |
251 | /* Analogous to ALLOCA_UNBOUNDED, when MAX_SIZE is greater | |
252 | than or equal to PTRDIFF_MAX, treat allocations with | |
253 | an unknown bound as OK. */ | |
254 | alloca_type unknown_result | |
255 | = (max_size < maxobjsize.to_uhwi () | |
256 | ? ALLOCA_BOUND_UNKNOWN : ALLOCA_OK); | |
257 | return alloca_type_and_limit (unknown_result); | |
258 | } | |
da6cf191 | 259 | } |
260 | ||
261 | // Similarly, but check for a comparison with an unknown LIMIT. | |
262 | // if (LIMIT .COND. ARG) | |
263 | // alloca(arg); | |
264 | // | |
265 | // Where LIMIT has a bound of unknown range. | |
266 | // | |
267 | // Note: All conditions of the form (ARG .COND. XXXX) where covered | |
268 | // by the previous check above, so we only need to look for (LIMIT | |
269 | // .COND. ARG) here. | |
270 | tree limit = gimple_cond_lhs (last); | |
271 | if ((gimple_cond_rhs (last) == arg | |
272 | || gimple_cond_rhs (last) == arg_casted) | |
273 | && TREE_CODE (limit) == SSA_NAME) | |
274 | { | |
275 | wide_int min, max; | |
be44111e | 276 | value_range_kind range_type = get_range_info (limit, &min, &max); |
da6cf191 | 277 | |
278 | if (range_type == VR_UNDEFINED || range_type == VR_VARYING) | |
279 | return alloca_type_and_limit (ALLOCA_BOUND_UNKNOWN); | |
280 | ||
281 | // ?? It looks like the above `if' is unnecessary, as we never | |
282 | // get any VR_RANGE or VR_ANTI_RANGE here. If we had a range | |
283 | // for LIMIT, I suppose we would have taken care of it in | |
284 | // alloca_call_type(), or handled above where we handle (ARG .COND. N). | |
285 | // | |
286 | // If this ever triggers, we should probably figure out why and | |
287 | // handle it, though it is likely to be just an ALLOCA_UNBOUNDED. | |
8e18705e | 288 | return alloca_type_and_limit (unbounded_result); |
da6cf191 | 289 | } |
290 | ||
8e18705e | 291 | return alloca_type_and_limit (unbounded_result); |
da6cf191 | 292 | } |
293 | ||
294 | // Return TRUE if SSA's definition is a cast from a signed type. | |
295 | // If so, set *INVALID_CASTED_TYPE to the signed type. | |
296 | ||
297 | static bool | |
298 | cast_from_signed_p (tree ssa, tree *invalid_casted_type) | |
299 | { | |
300 | gimple *def = SSA_NAME_DEF_STMT (ssa); | |
301 | if (def | |
302 | && !gimple_nop_p (def) | |
303 | && gimple_assign_cast_p (def) | |
304 | && !TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def)))) | |
305 | { | |
306 | *invalid_casted_type = TREE_TYPE (gimple_assign_rhs1 (def)); | |
307 | return true; | |
308 | } | |
309 | return false; | |
310 | } | |
311 | ||
312 | // Return TRUE if X has a maximum range of MAX, basically covering the | |
313 | // entire domain, in which case it's no range at all. | |
314 | ||
315 | static bool | |
316 | is_max (tree x, wide_int max) | |
317 | { | |
318 | return wi::max_value (TREE_TYPE (x)) == max; | |
319 | } | |
320 | ||
321 | // Analyze the alloca call in STMT and return the alloca type with its | |
322 | // corresponding limit (if applicable). IS_VLA is set if the alloca | |
2b34677f | 323 | // call was created by the gimplifier for a VLA. |
da6cf191 | 324 | // |
325 | // If the alloca call may be too large because of a cast from a signed | |
326 | // type to an unsigned type, set *INVALID_CASTED_TYPE to the | |
327 | // problematic signed type. | |
328 | ||
2e966e2a | 329 | static class alloca_type_and_limit |
da6cf191 | 330 | alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type) |
331 | { | |
332 | gcc_assert (gimple_alloca_call_p (stmt)); | |
a57264ec | 333 | bool tentative_cast_from_signed = false; |
da6cf191 | 334 | tree len = gimple_call_arg (stmt, 0); |
335 | tree len_casted = NULL; | |
336 | wide_int min, max; | |
2b34677f | 337 | edge_iterator ei; |
338 | edge e; | |
da6cf191 | 339 | |
8e18705e | 340 | gcc_assert (!is_vla || warn_vla_limit >= 0); |
341 | gcc_assert (is_vla || warn_alloca_limit >= 0); | |
da6cf191 | 342 | |
343 | // Adjust warn_alloca_max_size for VLAs, by taking the underlying | |
344 | // type into account. | |
48cccec0 | 345 | unsigned HOST_WIDE_INT max_size = adjusted_warn_limit (is_vla); |
da6cf191 | 346 | |
347 | // Check for the obviously bounded case. | |
348 | if (TREE_CODE (len) == INTEGER_CST) | |
349 | { | |
350 | if (tree_to_uhwi (len) > max_size) | |
e3d0f65c | 351 | return alloca_type_and_limit (ALLOCA_BOUND_DEFINITELY_LARGE, |
352 | wi::to_wide (len)); | |
da6cf191 | 353 | if (integer_zerop (len)) |
8e18705e | 354 | { |
355 | const offset_int maxobjsize | |
356 | = wi::to_offset (max_object_size ()); | |
357 | alloca_type result = (max_size < maxobjsize | |
358 | ? ALLOCA_ARG_IS_ZERO : ALLOCA_OK); | |
359 | return alloca_type_and_limit (result); | |
360 | } | |
2b34677f | 361 | |
362 | return alloca_type_and_limit (ALLOCA_OK); | |
da6cf191 | 363 | } |
2b34677f | 364 | |
da6cf191 | 365 | // Check the range info if available. |
2b34677f | 366 | if (TREE_CODE (len) == SSA_NAME) |
da6cf191 | 367 | { |
be44111e | 368 | value_range_kind range_type = get_range_info (len, &min, &max); |
da6cf191 | 369 | if (range_type == VR_RANGE) |
370 | { | |
371 | if (wi::leu_p (max, max_size)) | |
2b34677f | 372 | return alloca_type_and_limit (ALLOCA_OK); |
da6cf191 | 373 | else |
374 | { | |
375 | // A cast may have created a range we don't care | |
376 | // about. For instance, a cast from 16-bit to | |
377 | // 32-bit creates a range of 0..65535, even if there | |
378 | // is not really a determinable range in the | |
379 | // underlying code. In this case, look through the | |
380 | // cast at the original argument, and fall through | |
381 | // to look at other alternatives. | |
382 | // | |
383 | // We only look at through the cast when its from | |
384 | // unsigned to unsigned, otherwise we may risk | |
385 | // looking at SIGNED_INT < N, which is clearly not | |
386 | // what we want. In this case, we'd be interested | |
387 | // in a VR_RANGE of [0..N]. | |
388 | // | |
389 | // Note: None of this is perfect, and should all go | |
390 | // away with better range information. But it gets | |
391 | // most of the cases. | |
392 | gimple *def = SSA_NAME_DEF_STMT (len); | |
01ec83a1 | 393 | if (gimple_assign_cast_p (def)) |
da6cf191 | 394 | { |
01ec83a1 | 395 | tree rhs1 = gimple_assign_rhs1 (def); |
396 | tree rhs1type = TREE_TYPE (rhs1); | |
397 | ||
398 | // Bail if the argument type is not valid. | |
399 | if (!INTEGRAL_TYPE_P (rhs1type)) | |
400 | return alloca_type_and_limit (ALLOCA_OK); | |
401 | ||
402 | if (TYPE_UNSIGNED (rhs1type)) | |
403 | { | |
404 | len_casted = rhs1; | |
405 | range_type = get_range_info (len_casted, &min, &max); | |
406 | } | |
da6cf191 | 407 | } |
408 | // An unknown range or a range of the entire domain is | |
409 | // really no range at all. | |
410 | if (range_type == VR_VARYING | |
411 | || (!len_casted && is_max (len, max)) | |
412 | || (len_casted && is_max (len_casted, max))) | |
413 | { | |
414 | // Fall through. | |
415 | } | |
5a01fc0e | 416 | else if (range_type == VR_ANTI_RANGE) |
417 | return alloca_type_and_limit (ALLOCA_UNBOUNDED); | |
8e18705e | 418 | |
419 | if (range_type != VR_VARYING) | |
420 | { | |
421 | const offset_int maxobjsize | |
422 | = wi::to_offset (max_object_size ()); | |
423 | alloca_type result = (max_size < maxobjsize | |
424 | ? ALLOCA_BOUND_MAYBE_LARGE : ALLOCA_OK); | |
425 | return alloca_type_and_limit (result, max); | |
426 | } | |
da6cf191 | 427 | } |
428 | } | |
429 | else if (range_type == VR_ANTI_RANGE) | |
430 | { | |
431 | // There may be some wrapping around going on. Catch it | |
432 | // with this heuristic. Hopefully, this VR_ANTI_RANGE | |
433 | // nonsense will go away, and we won't have to catch the | |
434 | // sign conversion problems with this crap. | |
a57264ec | 435 | // |
436 | // This is here to catch things like: | |
437 | // void foo(signed int n) { | |
438 | // if (n < 100) | |
439 | // alloca(n); | |
440 | // ... | |
441 | // } | |
da6cf191 | 442 | if (cast_from_signed_p (len, invalid_casted_type)) |
a57264ec | 443 | { |
444 | // Unfortunately this also triggers: | |
445 | // | |
446 | // __SIZE_TYPE__ n = (__SIZE_TYPE__)blah; | |
447 | // if (n < 100) | |
448 | // alloca(n); | |
449 | // | |
450 | // ...which is clearly bounded. So, double check that | |
451 | // the paths leading up to the size definitely don't | |
452 | // have a bound. | |
453 | tentative_cast_from_signed = true; | |
454 | } | |
da6cf191 | 455 | } |
456 | // No easily determined range and try other things. | |
457 | } | |
458 | ||
459 | // If we couldn't find anything, try a few heuristics for things we | |
460 | // can easily determine. Check these misc cases but only accept | |
461 | // them if all predecessors have a known bound. | |
2e966e2a | 462 | class alloca_type_and_limit ret = alloca_type_and_limit (ALLOCA_OK); |
2b34677f | 463 | FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->preds) |
da6cf191 | 464 | { |
2b34677f | 465 | gcc_assert (!len_casted || TYPE_UNSIGNED (TREE_TYPE (len_casted))); |
466 | ret = alloca_call_type_by_arg (len, len_casted, e, max_size); | |
467 | if (ret.type != ALLOCA_OK) | |
468 | break; | |
469 | } | |
470 | ||
471 | if (ret.type != ALLOCA_OK && tentative_cast_from_signed) | |
472 | ret = alloca_type_and_limit (ALLOCA_CAST_FROM_SIGNED); | |
473 | ||
474 | // If we have a declared maximum size, we can take it into account. | |
475 | if (ret.type != ALLOCA_OK | |
476 | && gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX)) | |
477 | { | |
478 | tree arg = gimple_call_arg (stmt, 2); | |
479 | if (compare_tree_int (arg, max_size) <= 0) | |
480 | ret = alloca_type_and_limit (ALLOCA_OK); | |
481 | else | |
8e18705e | 482 | { |
483 | const offset_int maxobjsize | |
484 | = wi::to_offset (max_object_size ()); | |
485 | alloca_type result = (max_size < maxobjsize | |
486 | ? ALLOCA_BOUND_MAYBE_LARGE : ALLOCA_OK); | |
487 | ret = alloca_type_and_limit (result, wi::to_wide (arg)); | |
488 | } | |
da6cf191 | 489 | } |
490 | ||
491 | return ret; | |
492 | } | |
493 | ||
2b34677f | 494 | // Return TRUE if STMT is in a loop, otherwise return FALSE. |
da6cf191 | 495 | |
496 | static bool | |
2b34677f | 497 | in_loop_p (gimple *stmt) |
da6cf191 | 498 | { |
499 | basic_block bb = gimple_bb (stmt); | |
2b34677f | 500 | return |
501 | bb->loop_father && bb->loop_father->header != ENTRY_BLOCK_PTR_FOR_FN (cfun); | |
da6cf191 | 502 | } |
503 | ||
504 | unsigned int | |
505 | pass_walloca::execute (function *fun) | |
506 | { | |
507 | basic_block bb; | |
508 | FOR_EACH_BB_FN (bb, fun) | |
509 | { | |
510 | for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); | |
511 | gsi_next (&si)) | |
512 | { | |
513 | gimple *stmt = gsi_stmt (si); | |
514 | location_t loc = gimple_location (stmt); | |
515 | ||
516 | if (!gimple_alloca_call_p (stmt)) | |
517 | continue; | |
da6cf191 | 518 | |
2b34677f | 519 | const bool is_vla |
520 | = gimple_call_alloca_for_var_p (as_a <gcall *> (stmt)); | |
da6cf191 | 521 | |
522 | // Strict mode whining for VLAs is handled by the front-end, | |
523 | // so we can safely ignore this case. Also, ignore VLAs if | |
524 | // the user doesn't care about them. | |
8e18705e | 525 | if (is_vla) |
da6cf191 | 526 | { |
8e18705e | 527 | if (warn_vla > 0 || warn_vla_limit < 0) |
528 | continue; | |
529 | } | |
530 | else if (warn_alloca) | |
531 | { | |
ab9211d0 | 532 | warning_at (loc, OPT_Walloca, "use of %<alloca%>"); |
da6cf191 | 533 | continue; |
534 | } | |
8e18705e | 535 | else if (warn_alloca_limit < 0) |
536 | continue; | |
da6cf191 | 537 | |
538 | tree invalid_casted_type = NULL; | |
2e966e2a | 539 | class alloca_type_and_limit t |
da6cf191 | 540 | = alloca_call_type (stmt, is_vla, &invalid_casted_type); |
541 | ||
48cccec0 | 542 | unsigned HOST_WIDE_INT adjusted_alloca_limit |
543 | = adjusted_warn_limit (false); | |
2b34677f | 544 | // Even if we think the alloca call is OK, make sure it's not in a |
545 | // loop, except for a VLA, since VLAs are guaranteed to be cleaned | |
546 | // up when they go out of scope, including in a loop. | |
547 | if (t.type == ALLOCA_OK && !is_vla && in_loop_p (stmt)) | |
8e18705e | 548 | { |
549 | /* As in other instances, only diagnose this when the limit | |
550 | is less than the maximum valid object size. */ | |
551 | const offset_int maxobjsize | |
552 | = wi::to_offset (max_object_size ()); | |
48cccec0 | 553 | if (adjusted_alloca_limit < maxobjsize.to_uhwi ()) |
8e18705e | 554 | t = alloca_type_and_limit (ALLOCA_IN_LOOP); |
555 | } | |
da6cf191 | 556 | |
557 | enum opt_code wcode | |
558 | = is_vla ? OPT_Wvla_larger_than_ : OPT_Walloca_larger_than_; | |
559 | char buff[WIDE_INT_MAX_PRECISION / 4 + 4]; | |
560 | switch (t.type) | |
561 | { | |
562 | case ALLOCA_OK: | |
563 | break; | |
564 | case ALLOCA_BOUND_MAYBE_LARGE: | |
bc35ef65 | 565 | { |
566 | auto_diagnostic_group d; | |
567 | if (warning_at (loc, wcode, | |
568 | is_vla ? G_("argument to variable-length " | |
569 | "array may be too large") | |
570 | : G_("argument to %<alloca%> may be too " | |
571 | "large")) | |
572 | && t.limit != 0) | |
573 | { | |
574 | print_decu (t.limit, buff); | |
ab9211d0 | 575 | inform (loc, "limit is %wu bytes, but argument " |
576 | "may be as large as %s", | |
48cccec0 | 577 | is_vla ? warn_vla_limit : adjusted_alloca_limit, |
578 | buff); | |
bc35ef65 | 579 | } |
580 | } | |
da6cf191 | 581 | break; |
582 | case ALLOCA_BOUND_DEFINITELY_LARGE: | |
bc35ef65 | 583 | { |
584 | auto_diagnostic_group d; | |
585 | if (warning_at (loc, wcode, | |
586 | is_vla ? G_("argument to variable-length" | |
587 | " array is too large") | |
588 | : G_("argument to %<alloca%> is too large")) | |
589 | && t.limit != 0) | |
590 | { | |
591 | print_decu (t.limit, buff); | |
ab9211d0 | 592 | inform (loc, "limit is %wu bytes, but argument is %s", |
48cccec0 | 593 | is_vla ? warn_vla_limit : adjusted_alloca_limit, |
bc35ef65 | 594 | buff); |
595 | } | |
596 | } | |
da6cf191 | 597 | break; |
598 | case ALLOCA_BOUND_UNKNOWN: | |
599 | warning_at (loc, wcode, | |
600 | is_vla ? G_("variable-length array bound is unknown") | |
601 | : G_("%<alloca%> bound is unknown")); | |
602 | break; | |
603 | case ALLOCA_UNBOUNDED: | |
604 | warning_at (loc, wcode, | |
605 | is_vla ? G_("unbounded use of variable-length array") | |
606 | : G_("unbounded use of %<alloca%>")); | |
607 | break; | |
608 | case ALLOCA_IN_LOOP: | |
609 | gcc_assert (!is_vla); | |
ab9211d0 | 610 | warning_at (loc, wcode, "use of %<alloca%> within a loop"); |
da6cf191 | 611 | break; |
612 | case ALLOCA_CAST_FROM_SIGNED: | |
613 | gcc_assert (invalid_casted_type != NULL_TREE); | |
614 | warning_at (loc, wcode, | |
615 | is_vla ? G_("argument to variable-length array " | |
616 | "may be too large due to " | |
617 | "conversion from %qT to %qT") | |
618 | : G_("argument to %<alloca%> may be too large " | |
619 | "due to conversion from %qT to %qT"), | |
620 | invalid_casted_type, size_type_node); | |
621 | break; | |
622 | case ALLOCA_ARG_IS_ZERO: | |
623 | warning_at (loc, wcode, | |
624 | is_vla ? G_("argument to variable-length array " | |
625 | "is zero") | |
626 | : G_("argument to %<alloca%> is zero")); | |
627 | break; | |
628 | default: | |
629 | gcc_unreachable (); | |
630 | } | |
631 | } | |
632 | } | |
633 | return 0; | |
634 | } | |
635 | ||
636 | gimple_opt_pass * | |
637 | make_pass_walloca (gcc::context *ctxt) | |
638 | { | |
639 | return new pass_walloca (ctxt); | |
640 | } |