Mercurial > hg > CbC > CbC_gcc
comparison gcc/gimple-ssa-warn-alloca.c @ 132:d34655255c78
update gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 10:21:07 +0900 |
parents | 84e7813d76e9 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
130:e108057fa461 | 132:d34655255c78 |
---|---|
1 /* Warn on problematic uses of alloca and variable length arrays. | 1 /* Warn on problematic uses of alloca and variable length arrays. |
2 Copyright (C) 2016-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2016-2018 Free Software Foundation, Inc. |
3 Contributed by Aldy Hernandez <aldyh@redhat.com>. | 3 Contributed by Aldy Hernandez <aldyh@redhat.com>. |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
31 #include "fold-const.h" | 31 #include "fold-const.h" |
32 #include "gimple-iterator.h" | 32 #include "gimple-iterator.h" |
33 #include "tree-ssa.h" | 33 #include "tree-ssa.h" |
34 #include "params.h" | 34 #include "params.h" |
35 #include "tree-cfg.h" | 35 #include "tree-cfg.h" |
36 #include "builtins.h" | |
36 #include "calls.h" | 37 #include "calls.h" |
37 #include "cfgloop.h" | 38 #include "cfgloop.h" |
38 #include "intl.h" | 39 #include "intl.h" |
40 | |
41 static unsigned HOST_WIDE_INT adjusted_warn_limit (bool); | |
39 | 42 |
40 const pass_data pass_data_walloca = { | 43 const pass_data pass_data_walloca = { |
41 GIMPLE_PASS, | 44 GIMPLE_PASS, |
42 "walloca", | 45 "walloca", |
43 OPTGROUP_NONE, | 46 OPTGROUP_NONE, |
76 // optimizations have been run and range information is unavailable, | 79 // optimizations have been run and range information is unavailable, |
77 // so we can only perform strict alloca checking. | 80 // so we can only perform strict alloca checking. |
78 if (first_time_p) | 81 if (first_time_p) |
79 return warn_alloca != 0; | 82 return warn_alloca != 0; |
80 | 83 |
81 return ((unsigned HOST_WIDE_INT) warn_alloca_limit > 0 | 84 // Warning is disabled when its size limit is greater than PTRDIFF_MAX |
82 || (unsigned HOST_WIDE_INT) warn_vla_limit > 0); | 85 // for the target maximum, which makes the limit negative since when |
86 // represented in signed HOST_WIDE_INT. | |
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); | |
83 } | 90 } |
84 | 91 |
85 // Possible problematic uses of alloca. | 92 // Possible problematic uses of alloca. |
86 enum alloca_type { | 93 enum alloca_type { |
87 // Alloca argument is within known bounds that are appropriate. | 94 // Alloca argument is within known bounds that are appropriate. |
119 // field is undefined. | 126 // field is undefined. |
120 wide_int limit; | 127 wide_int limit; |
121 alloca_type_and_limit (); | 128 alloca_type_and_limit (); |
122 alloca_type_and_limit (enum alloca_type type, | 129 alloca_type_and_limit (enum alloca_type type, |
123 wide_int i) : type(type), limit(i) { } | 130 wide_int i) : type(type), limit(i) { } |
124 alloca_type_and_limit (enum alloca_type type) : type(type) { } | 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 } | |
125 }; | 136 }; |
137 | |
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 | |
126 | 161 |
127 // NOTE: When we get better range info, this entire function becomes | 162 // NOTE: When we get better range info, this entire function becomes |
128 // irrelevant, as it should be possible to get range info for an SSA | 163 // irrelevant, as it should be possible to get range info for an SSA |
129 // name at any point in the program. | 164 // name at any point in the program. |
130 // | 165 // |
148 // | 183 // |
149 // MAX_SIZE is WARN_ALLOCA= adjusted for VLAs. It is the maximum size | 184 // MAX_SIZE is WARN_ALLOCA= adjusted for VLAs. It is the maximum size |
150 // in bytes we allow for arg. | 185 // in bytes we allow for arg. |
151 | 186 |
152 static struct alloca_type_and_limit | 187 static struct alloca_type_and_limit |
153 alloca_call_type_by_arg (tree arg, tree arg_casted, edge e, unsigned max_size) | 188 alloca_call_type_by_arg (tree arg, tree arg_casted, edge e, |
189 unsigned HOST_WIDE_INT max_size) | |
154 { | 190 { |
155 basic_block bb = e->src; | 191 basic_block bb = e->src; |
156 gimple_stmt_iterator gsi = gsi_last_bb (bb); | 192 gimple_stmt_iterator gsi = gsi_last_bb (bb); |
157 gimple *last = gsi_stmt (gsi); | 193 gimple *last = gsi_stmt (gsi); |
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 | |
158 if (!last || gimple_code (last) != GIMPLE_COND) | 203 if (!last || gimple_code (last) != GIMPLE_COND) |
159 return alloca_type_and_limit (ALLOCA_UNBOUNDED); | 204 { |
205 return alloca_type_and_limit (unbounded_result); | |
206 } | |
160 | 207 |
161 enum tree_code cond_code = gimple_cond_code (last); | 208 enum tree_code cond_code = gimple_cond_code (last); |
162 if (e->flags & EDGE_TRUE_VALUE) | 209 if (e->flags & EDGE_TRUE_VALUE) |
163 ; | 210 ; |
164 else if (e->flags & EDGE_FALSE_VALUE) | 211 else if (e->flags & EDGE_FALSE_VALUE) |
165 cond_code = invert_tree_comparison (cond_code, false); | 212 cond_code = invert_tree_comparison (cond_code, false); |
166 else | 213 else |
167 return alloca_type_and_limit (ALLOCA_UNBOUNDED); | 214 return alloca_type_and_limit (unbounded_result); |
168 | 215 |
169 // Check for: | 216 // Check for: |
170 // if (ARG .COND. N) | 217 // if (ARG .COND. N) |
171 // goto <bb 3>; | 218 // goto <bb 3>; |
172 // else | 219 // else |
197 return alloca_type_and_limit (ALLOCA_BOUND_MAYBE_LARGE, | 244 return alloca_type_and_limit (ALLOCA_BOUND_MAYBE_LARGE, |
198 wi::to_wide (rhs)); | 245 wi::to_wide (rhs)); |
199 } | 246 } |
200 } | 247 } |
201 else | 248 else |
202 return alloca_type_and_limit (ALLOCA_BOUND_UNKNOWN); | 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 } | |
203 } | 258 } |
204 | 259 |
205 // Similarly, but check for a comparison with an unknown LIMIT. | 260 // Similarly, but check for a comparison with an unknown LIMIT. |
206 // if (LIMIT .COND. ARG) | 261 // if (LIMIT .COND. ARG) |
207 // alloca(arg); | 262 // alloca(arg); |
215 if ((gimple_cond_rhs (last) == arg | 270 if ((gimple_cond_rhs (last) == arg |
216 || gimple_cond_rhs (last) == arg_casted) | 271 || gimple_cond_rhs (last) == arg_casted) |
217 && TREE_CODE (limit) == SSA_NAME) | 272 && TREE_CODE (limit) == SSA_NAME) |
218 { | 273 { |
219 wide_int min, max; | 274 wide_int min, max; |
220 value_range_type range_type = get_range_info (limit, &min, &max); | 275 value_range_kind range_type = get_range_info (limit, &min, &max); |
221 | 276 |
222 if (range_type == VR_UNDEFINED || range_type == VR_VARYING) | 277 if (range_type == VR_UNDEFINED || range_type == VR_VARYING) |
223 return alloca_type_and_limit (ALLOCA_BOUND_UNKNOWN); | 278 return alloca_type_and_limit (ALLOCA_BOUND_UNKNOWN); |
224 | 279 |
225 // ?? It looks like the above `if' is unnecessary, as we never | 280 // ?? It looks like the above `if' is unnecessary, as we never |
227 // for LIMIT, I suppose we would have taken care of it in | 282 // for LIMIT, I suppose we would have taken care of it in |
228 // alloca_call_type(), or handled above where we handle (ARG .COND. N). | 283 // alloca_call_type(), or handled above where we handle (ARG .COND. N). |
229 // | 284 // |
230 // If this ever triggers, we should probably figure out why and | 285 // If this ever triggers, we should probably figure out why and |
231 // handle it, though it is likely to be just an ALLOCA_UNBOUNDED. | 286 // handle it, though it is likely to be just an ALLOCA_UNBOUNDED. |
232 return alloca_type_and_limit (ALLOCA_UNBOUNDED); | 287 return alloca_type_and_limit (unbounded_result); |
233 } | 288 } |
234 | 289 |
235 return alloca_type_and_limit (ALLOCA_UNBOUNDED); | 290 return alloca_type_and_limit (unbounded_result); |
236 } | 291 } |
237 | 292 |
238 // Return TRUE if SSA's definition is a cast from a signed type. | 293 // Return TRUE if SSA's definition is a cast from a signed type. |
239 // If so, set *INVALID_CASTED_TYPE to the signed type. | 294 // If so, set *INVALID_CASTED_TYPE to the signed type. |
240 | 295 |
279 tree len_casted = NULL; | 334 tree len_casted = NULL; |
280 wide_int min, max; | 335 wide_int min, max; |
281 edge_iterator ei; | 336 edge_iterator ei; |
282 edge e; | 337 edge e; |
283 | 338 |
284 gcc_assert (!is_vla || (unsigned HOST_WIDE_INT) warn_vla_limit > 0); | 339 gcc_assert (!is_vla || warn_vla_limit >= 0); |
285 gcc_assert (is_vla || (unsigned HOST_WIDE_INT) warn_alloca_limit > 0); | 340 gcc_assert (is_vla || warn_alloca_limit >= 0); |
286 | 341 |
287 // Adjust warn_alloca_max_size for VLAs, by taking the underlying | 342 // Adjust warn_alloca_max_size for VLAs, by taking the underlying |
288 // type into account. | 343 // type into account. |
289 unsigned HOST_WIDE_INT max_size; | 344 unsigned HOST_WIDE_INT max_size = adjusted_warn_limit (is_vla); |
290 if (is_vla) | |
291 max_size = (unsigned HOST_WIDE_INT) warn_vla_limit; | |
292 else | |
293 max_size = (unsigned HOST_WIDE_INT) warn_alloca_limit; | |
294 | 345 |
295 // Check for the obviously bounded case. | 346 // Check for the obviously bounded case. |
296 if (TREE_CODE (len) == INTEGER_CST) | 347 if (TREE_CODE (len) == INTEGER_CST) |
297 { | 348 { |
298 if (tree_to_uhwi (len) > max_size) | 349 if (tree_to_uhwi (len) > max_size) |
299 return alloca_type_and_limit (ALLOCA_BOUND_DEFINITELY_LARGE, | 350 return alloca_type_and_limit (ALLOCA_BOUND_DEFINITELY_LARGE, |
300 wi::to_wide (len)); | 351 wi::to_wide (len)); |
301 if (integer_zerop (len)) | 352 if (integer_zerop (len)) |
302 return alloca_type_and_limit (ALLOCA_ARG_IS_ZERO); | 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 } | |
303 | 360 |
304 return alloca_type_and_limit (ALLOCA_OK); | 361 return alloca_type_and_limit (ALLOCA_OK); |
305 } | 362 } |
306 | 363 |
307 // Check the range info if available. | 364 // Check the range info if available. |
308 if (TREE_CODE (len) == SSA_NAME) | 365 if (TREE_CODE (len) == SSA_NAME) |
309 { | 366 { |
310 value_range_type range_type = get_range_info (len, &min, &max); | 367 value_range_kind range_type = get_range_info (len, &min, &max); |
311 if (range_type == VR_RANGE) | 368 if (range_type == VR_RANGE) |
312 { | 369 { |
313 if (wi::leu_p (max, max_size)) | 370 if (wi::leu_p (max, max_size)) |
314 return alloca_type_and_limit (ALLOCA_OK); | 371 return alloca_type_and_limit (ALLOCA_OK); |
315 else | 372 else |
355 { | 412 { |
356 // Fall through. | 413 // Fall through. |
357 } | 414 } |
358 else if (range_type == VR_ANTI_RANGE) | 415 else if (range_type == VR_ANTI_RANGE) |
359 return alloca_type_and_limit (ALLOCA_UNBOUNDED); | 416 return alloca_type_and_limit (ALLOCA_UNBOUNDED); |
360 else if (range_type != VR_VARYING) | 417 |
361 return alloca_type_and_limit (ALLOCA_BOUND_MAYBE_LARGE, max); | 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 } | |
362 } | 426 } |
363 } | 427 } |
364 else if (range_type == VR_ANTI_RANGE) | 428 else if (range_type == VR_ANTI_RANGE) |
365 { | 429 { |
366 // There may be some wrapping around going on. Catch it | 430 // There may be some wrapping around going on. Catch it |
412 { | 476 { |
413 tree arg = gimple_call_arg (stmt, 2); | 477 tree arg = gimple_call_arg (stmt, 2); |
414 if (compare_tree_int (arg, max_size) <= 0) | 478 if (compare_tree_int (arg, max_size) <= 0) |
415 ret = alloca_type_and_limit (ALLOCA_OK); | 479 ret = alloca_type_and_limit (ALLOCA_OK); |
416 else | 480 else |
417 ret = alloca_type_and_limit (ALLOCA_BOUND_MAYBE_LARGE, | 481 { |
418 wi::to_wide (arg)); | 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 } | |
419 } | 488 } |
420 | 489 |
421 return ret; | 490 return ret; |
422 } | 491 } |
423 | 492 |
443 gimple *stmt = gsi_stmt (si); | 512 gimple *stmt = gsi_stmt (si); |
444 location_t loc = gimple_location (stmt); | 513 location_t loc = gimple_location (stmt); |
445 | 514 |
446 if (!gimple_alloca_call_p (stmt)) | 515 if (!gimple_alloca_call_p (stmt)) |
447 continue; | 516 continue; |
448 gcc_assert (gimple_call_num_args (stmt) >= 1); | |
449 | 517 |
450 const bool is_vla | 518 const bool is_vla |
451 = gimple_call_alloca_for_var_p (as_a <gcall *> (stmt)); | 519 = gimple_call_alloca_for_var_p (as_a <gcall *> (stmt)); |
452 | 520 |
453 // Strict mode whining for VLAs is handled by the front-end, | 521 // Strict mode whining for VLAs is handled by the front-end, |
454 // so we can safely ignore this case. Also, ignore VLAs if | 522 // so we can safely ignore this case. Also, ignore VLAs if |
455 // the user doesn't care about them. | 523 // the user doesn't care about them. |
456 if (is_vla | 524 if (is_vla) |
457 && (warn_vla > 0 || !warn_vla_limit)) | |
458 continue; | |
459 | |
460 if (!is_vla && (warn_alloca || !warn_alloca_limit)) | |
461 { | 525 { |
462 if (warn_alloca) | 526 if (warn_vla > 0 || warn_vla_limit < 0) |
463 warning_at (loc, OPT_Walloca, G_("use of %<alloca%>")); | 527 continue; |
528 } | |
529 else if (warn_alloca) | |
530 { | |
531 warning_at (loc, OPT_Walloca, G_("use of %<alloca%>")); | |
464 continue; | 532 continue; |
465 } | 533 } |
534 else if (warn_alloca_limit < 0) | |
535 continue; | |
466 | 536 |
467 tree invalid_casted_type = NULL; | 537 tree invalid_casted_type = NULL; |
468 struct alloca_type_and_limit t | 538 struct alloca_type_and_limit t |
469 = alloca_call_type (stmt, is_vla, &invalid_casted_type); | 539 = alloca_call_type (stmt, is_vla, &invalid_casted_type); |
470 | 540 |
541 unsigned HOST_WIDE_INT adjusted_alloca_limit | |
542 = adjusted_warn_limit (false); | |
471 // Even if we think the alloca call is OK, make sure it's not in a | 543 // Even if we think the alloca call is OK, make sure it's not in a |
472 // loop, except for a VLA, since VLAs are guaranteed to be cleaned | 544 // loop, except for a VLA, since VLAs are guaranteed to be cleaned |
473 // up when they go out of scope, including in a loop. | 545 // up when they go out of scope, including in a loop. |
474 if (t.type == ALLOCA_OK && !is_vla && in_loop_p (stmt)) | 546 if (t.type == ALLOCA_OK && !is_vla && in_loop_p (stmt)) |
475 t = alloca_type_and_limit (ALLOCA_IN_LOOP); | 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 ()); | |
552 if (adjusted_alloca_limit < maxobjsize.to_uhwi ()) | |
553 t = alloca_type_and_limit (ALLOCA_IN_LOOP); | |
554 } | |
476 | 555 |
477 enum opt_code wcode | 556 enum opt_code wcode |
478 = is_vla ? OPT_Wvla_larger_than_ : OPT_Walloca_larger_than_; | 557 = is_vla ? OPT_Wvla_larger_than_ : OPT_Walloca_larger_than_; |
479 char buff[WIDE_INT_MAX_PRECISION / 4 + 4]; | 558 char buff[WIDE_INT_MAX_PRECISION / 4 + 4]; |
480 switch (t.type) | 559 switch (t.type) |
481 { | 560 { |
482 case ALLOCA_OK: | 561 case ALLOCA_OK: |
483 break; | 562 break; |
484 case ALLOCA_BOUND_MAYBE_LARGE: | 563 case ALLOCA_BOUND_MAYBE_LARGE: |
485 if (warning_at (loc, wcode, | 564 { |
486 is_vla ? G_("argument to variable-length array " | 565 auto_diagnostic_group d; |
487 "may be too large") | 566 if (warning_at (loc, wcode, |
488 : G_("argument to %<alloca%> may be too large")) | 567 is_vla ? G_("argument to variable-length " |
489 && t.limit != 0) | 568 "array may be too large") |
490 { | 569 : G_("argument to %<alloca%> may be too " |
491 print_decu (t.limit, buff); | 570 "large")) |
492 inform (loc, G_("limit is %u bytes, but argument " | 571 && t.limit != 0) |
493 "may be as large as %s"), | 572 { |
494 is_vla ? warn_vla_limit : warn_alloca_limit, buff); | 573 print_decu (t.limit, buff); |
495 } | 574 inform (loc, G_("limit is %wu bytes, but argument " |
575 "may be as large as %s"), | |
576 is_vla ? warn_vla_limit : adjusted_alloca_limit, | |
577 buff); | |
578 } | |
579 } | |
496 break; | 580 break; |
497 case ALLOCA_BOUND_DEFINITELY_LARGE: | 581 case ALLOCA_BOUND_DEFINITELY_LARGE: |
498 if (warning_at (loc, wcode, | 582 { |
499 is_vla ? G_("argument to variable-length array " | 583 auto_diagnostic_group d; |
500 "is too large") | 584 if (warning_at (loc, wcode, |
501 : G_("argument to %<alloca%> is too large")) | 585 is_vla ? G_("argument to variable-length" |
502 && t.limit != 0) | 586 " array is too large") |
503 { | 587 : G_("argument to %<alloca%> is too large")) |
504 print_decu (t.limit, buff); | 588 && t.limit != 0) |
505 inform (loc, G_("limit is %u bytes, but argument is %s"), | 589 { |
506 is_vla ? warn_vla_limit : warn_alloca_limit, buff); | 590 print_decu (t.limit, buff); |
507 } | 591 inform (loc, G_("limit is %wu bytes, but argument is %s"), |
592 is_vla ? warn_vla_limit : adjusted_alloca_limit, | |
593 buff); | |
594 } | |
595 } | |
508 break; | 596 break; |
509 case ALLOCA_BOUND_UNKNOWN: | 597 case ALLOCA_BOUND_UNKNOWN: |
510 warning_at (loc, wcode, | 598 warning_at (loc, wcode, |
511 is_vla ? G_("variable-length array bound is unknown") | 599 is_vla ? G_("variable-length array bound is unknown") |
512 : G_("%<alloca%> bound is unknown")); | 600 : G_("%<alloca%> bound is unknown")); |