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