1/* Pass to detect and issue warnings for violations of the restrict 2 qualifier. 3 Copyright (C) 2017-2020 Free Software Foundation, Inc. 4 Contributed by Martin Sebor <msebor@redhat.com>. 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free 10 Software Foundation; either version 3, or (at your option) any later 11 version. 12 13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GCC; see the file COPYING3. If not see 20 <http://www.gnu.org/licenses/>. */ 21 22#include "config.h" 23#include "system.h" 24#include "coretypes.h" 25#include "backend.h" 26#include "tree.h" 27#include "gimple.h" 28#include "domwalk.h" 29#include "tree-pass.h" 30#include "builtins.h" 31#include "ssa.h" 32#include "gimple-pretty-print.h" 33#include "gimple-ssa-warn-restrict.h" 34#include "diagnostic-core.h" 35#include "fold-const.h" 36#include "gimple-iterator.h" 37#include "tree-dfa.h" 38#include "tree-ssa.h" 39#include "tree-cfg.h" 40#include "tree-object-size.h" 41#include "calls.h" 42#include "cfgloop.h" 43#include "intl.h" 44 45namespace { 46 47const pass_data pass_data_wrestrict = { 48 GIMPLE_PASS, 49 "wrestrict", 50 OPTGROUP_NONE, 51 TV_NONE, 52 PROP_cfg, /* Properties_required. */ 53 0, /* properties_provided. */ 54 0, /* properties_destroyed. */ 55 0, /* properties_start */ 56 0, /* properties_finish */ 57}; 58 59/* Pass to detect violations of strict aliasing requirements in calls 60 to built-in string and raw memory functions. */ 61class pass_wrestrict : public gimple_opt_pass 62{ 63 public: 64 pass_wrestrict (gcc::context *ctxt) 65 : gimple_opt_pass (pass_data_wrestrict, ctxt) 66 { } 67 68 opt_pass *clone () { return new pass_wrestrict (m_ctxt); } 69 70 virtual bool gate (function *); 71 virtual unsigned int execute (function *); 72}; 73 74bool 75pass_wrestrict::gate (function *fun ATTRIBUTE_UNUSED) 76{ 77 return warn_array_bounds || warn_restrict || warn_stringop_overflow; 78} 79 80/* Class to walk the basic blocks of a function in dominator order. */ 81class wrestrict_dom_walker : public dom_walker 82{ 83 public: 84 wrestrict_dom_walker () : dom_walker (CDI_DOMINATORS) {} 85 86 edge before_dom_children (basic_block) FINAL OVERRIDE; 87 bool handle_gimple_call (gimple_stmt_iterator *); 88 89 private: 90 void check_call (gimple *); 91}; 92 93edge 94wrestrict_dom_walker::before_dom_children (basic_block bb) 95{ 96 /* Iterate over statements, looking for function calls. */ 97 for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); 98 gsi_next (&si)) 99 { 100 gimple *stmt = gsi_stmt (si); 101 if (!is_gimple_call (stmt)) 102 continue; 103 104 check_call (stmt); 105 } 106 107 return NULL; 108} 109 110/* Execute the pass for function FUN, walking in dominator order. */ 111 112unsigned 113pass_wrestrict::execute (function *fun) 114{ 115 calculate_dominance_info (CDI_DOMINATORS); 116 117 wrestrict_dom_walker walker; 118 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun)); 119 120 return 0; 121} 122 123/* Description of a memory reference by a built-in function. This 124 is similar to ao_ref but made especially suitable for -Wrestrict 125 and not for optimization. */ 126class builtin_memref 127{ 128public: 129 /* The original pointer argument to the built-in function. */ 130 tree ptr; 131 /* The referenced subobject or NULL if not available, and the base 132 object of the memory reference or NULL. */ 133 tree ref; 134 tree base; 135 136 /* The size of the BASE object, PTRDIFF_MAX if indeterminate, 137 and negative until (possibly lazily) initialized. */ 138 offset_int basesize; 139 /* Same for the subobject. */ 140 offset_int refsize; 141 142 /* The non-negative offset of the referenced subobject. Used to avoid 143 warnings for (apparently) possibly but not definitively overlapping 144 accesses to member arrays. Negative when unknown/invalid. */ 145 offset_int refoff; 146 147 /* The offset range relative to the base. */ 148 offset_int offrange[2]; 149 /* The size range of the access to this reference. */ 150 offset_int sizrange[2]; 151 152 /* Cached result of get_max_objsize(). */ 153 const offset_int maxobjsize; 154 155 /* True for "bounded" string functions like strncat, and strncpy 156 and their variants that specify either an exact or upper bound 157 on the size of the accesses they perform. For strncat both 158 the source and destination references are bounded. For strncpy 159 only the destination reference is. */ 160 bool strbounded_p; 161 162 builtin_memref (tree, tree); 163 164 tree offset_out_of_bounds (int, offset_int[3]) const; 165 166private: 167 168 /* Ctor helper to set or extend OFFRANGE based on argument. */ 169 void extend_offset_range (tree); 170 171 /* Ctor helper to determine BASE and OFFRANGE from argument. */ 172 void set_base_and_offset (tree); 173}; 174 175/* Description of a memory access by a raw memory or string built-in 176 function involving a pair of builtin_memref's. */ 177class builtin_access 178{ 179 public: 180 /* Destination and source memory reference. */ 181 builtin_memref* const dstref; 182 builtin_memref* const srcref; 183 /* The size range of the access. It's the greater of the accesses 184 to the two references. */ 185 HOST_WIDE_INT sizrange[2]; 186 187 /* The minimum and maximum offset of an overlap of the access 188 (if it does, in fact, overlap), and the size of the overlap. */ 189 HOST_WIDE_INT ovloff[2]; 190 HOST_WIDE_INT ovlsiz[2]; 191 192 /* True to consider valid only accesses to the smallest subobject 193 and false for raw memory functions. */ 194 bool strict () const 195 { 196 return (detect_overlap != &builtin_access::generic_overlap 197 && detect_overlap != &builtin_access::no_overlap); 198 } 199 200 builtin_access (gimple *, builtin_memref &, builtin_memref &); 201 202 /* Entry point to determine overlap. */ 203 bool overlap (); 204 205 offset_int write_off (tree) const; 206 207 void dump (FILE *) const; 208 209 private: 210 /* Implementation functions used to determine overlap. */ 211 bool generic_overlap (); 212 bool strcat_overlap (); 213 bool strcpy_overlap (); 214 215 bool no_overlap () 216 { 217 return false; 218 } 219 220 offset_int overlap_size (const offset_int [2], const offset_int[2], 221 offset_int [2]); 222 223 private: 224 /* Temporaries used to compute the final result. */ 225 offset_int dstoff[2]; 226 offset_int srcoff[2]; 227 offset_int dstsiz[2]; 228 offset_int srcsiz[2]; 229 230 /* Pointer to a member function to call to determine overlap. */ 231 bool (builtin_access::*detect_overlap) (); 232}; 233 234/* Initialize a memory reference representation from a pointer EXPR and 235 a size SIZE in bytes. If SIZE is NULL_TREE then the size is assumed 236 to be unknown. */ 237 238builtin_memref::builtin_memref (tree expr, tree size) 239: ptr (expr), 240 ref (), 241 base (), 242 basesize (-1), 243 refsize (-1), 244 refoff (HOST_WIDE_INT_MIN), 245 offrange (), 246 sizrange (), 247 maxobjsize (tree_to_shwi (max_object_size ())), 248 strbounded_p () 249{ 250 /* Unfortunately, wide_int default ctor is a no-op so array members 251 of the type must be set individually. */ 252 offrange[0] = offrange[1] = 0; 253 sizrange[0] = sizrange[1] = 0; 254 255 if (!expr) 256 return; 257 258 /* Find the BASE object or pointer referenced by EXPR and set 259 the offset range OFFRANGE in the process. */ 260 set_base_and_offset (expr); 261 262 if (size) 263 { 264 tree range[2]; 265 /* Determine the size range, allowing for the result to be [0, 0] 266 for SIZE in the anti-range ~[0, N] where N >= PTRDIFF_MAX. */ 267 get_size_range (size, range, true); 268 sizrange[0] = wi::to_offset (range[0]); 269 sizrange[1] = wi::to_offset (range[1]); 270 /* get_size_range returns SIZE_MAX for the maximum size. 271 Constrain it to the real maximum of PTRDIFF_MAX. */ 272 if (sizrange[0] <= maxobjsize && sizrange[1] > maxobjsize) 273 sizrange[1] = maxobjsize; 274 } 275 else 276 sizrange[1] = maxobjsize; 277 278 if (!DECL_P (base)) 279 return; 280 281 /* If the offset could be in the range of the referenced object 282 constrain its bounds so neither exceeds those of the object. */ 283 if (offrange[0] < 0 && offrange[1] > 0) 284 offrange[0] = 0; 285 286 offset_int maxoff = maxobjsize; 287 tree basetype = TREE_TYPE (base); 288 if (TREE_CODE (basetype) == ARRAY_TYPE) 289 { 290 if (ref && array_at_struct_end_p (ref)) 291 ; /* Use the maximum possible offset for last member arrays. */ 292 else if (tree basesize = TYPE_SIZE_UNIT (basetype)) 293 if (TREE_CODE (basesize) == INTEGER_CST) 294 /* Size could be non-constant for a variable-length type such 295 as a struct with a VLA member (a GCC extension). */ 296 maxoff = wi::to_offset (basesize); 297 } 298 299 if (offrange[0] >= 0) 300 { 301 if (offrange[1] < 0) 302 offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize; 303 else if (offrange[0] <= maxoff && offrange[1] > maxoff) 304 offrange[1] = maxoff; 305 } 306} 307 308/* Based on the initial length of the destination STARTLEN, returns 309 the offset of the first write access from the beginning of 310 the destination. Nonzero only for strcat-type of calls. */ 311 312offset_int builtin_access::write_off (tree startlen) const 313{ 314 if (detect_overlap != &builtin_access::strcat_overlap 315 || !startlen || TREE_CODE (startlen) != INTEGER_CST) 316 return 0; 317 318 return wi::to_offset (startlen); 319} 320 321/* Ctor helper to set or extend OFFRANGE based on the OFFSET argument. 322 Pointer offsets are represented as unsigned sizetype but must be 323 treated as signed. */ 324 325void 326builtin_memref::extend_offset_range (tree offset) 327{ 328 if (TREE_CODE (offset) == INTEGER_CST) 329 { 330 offset_int off = int_cst_value (offset); 331 if (off != 0) 332 { 333 offrange[0] += off; 334 offrange[1] += off; 335 } 336 return; 337 } 338 339 if (TREE_CODE (offset) == SSA_NAME) 340 { 341 /* A pointer offset is represented as sizetype but treated 342 as signed. */ 343 wide_int min, max; 344 value_range_kind rng = get_range_info (offset, &min, &max); 345 if (rng == VR_ANTI_RANGE && wi::lts_p (max, min)) 346 { 347 /* Convert an anti-range whose upper bound is less than 348 its lower bound to a signed range. */ 349 offrange[0] += offset_int::from (max + 1, SIGNED); 350 offrange[1] += offset_int::from (min - 1, SIGNED); 351 return; 352 } 353 354 if (rng == VR_RANGE 355 && (DECL_P (base) || wi::lts_p (min, max))) 356 { 357 /* Preserve the bounds of the range for an offset into 358 a known object (it may be adjusted later relative to 359 a constant offset from its beginning). Otherwise use 360 the bounds only when they are ascending when treated 361 as signed. */ 362 offrange[0] += offset_int::from (min, SIGNED); 363 offrange[1] += offset_int::from (max, SIGNED); 364 return; 365 } 366 367 /* Handle an anti-range the same as no range at all. */ 368 gimple *stmt = SSA_NAME_DEF_STMT (offset); 369 tree type; 370 if (is_gimple_assign (stmt) 371 && (type = TREE_TYPE (gimple_assign_rhs1 (stmt))) 372 && INTEGRAL_TYPE_P (type)) 373 { 374 tree_code code = gimple_assign_rhs_code (stmt); 375 if (code == NOP_EXPR) 376 { 377 /* Use the bounds of the type of the NOP_EXPR operand 378 even if it's signed. The result doesn't trigger 379 warnings but makes their output more readable. */ 380 offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type)); 381 offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type)); 382 return; 383 } 384 } 385 } 386 387 const offset_int maxoff = tree_to_shwi (max_object_size ()) >> 1; 388 const offset_int minoff = -maxoff - 1; 389 390 offrange[0] += minoff; 391 offrange[1] += maxoff; 392} 393 394/* Determines the base object or pointer of the reference EXPR 395 and the offset range from the beginning of the base. */ 396 397void 398builtin_memref::set_base_and_offset (tree expr) 399{ 400 tree offset = NULL_TREE; 401 402 if (TREE_CODE (expr) == SSA_NAME) 403 { 404 /* Try to tease the offset out of the pointer. */ 405 gimple *stmt = SSA_NAME_DEF_STMT (expr); 406 if (!base 407 && gimple_assign_single_p (stmt) 408 && gimple_assign_rhs_code (stmt) == ADDR_EXPR) 409 expr = gimple_assign_rhs1 (stmt); 410 else if (is_gimple_assign (stmt)) 411 { 412 tree_code code = gimple_assign_rhs_code (stmt); 413 if (code == NOP_EXPR) 414 { 415 tree rhs = gimple_assign_rhs1 (stmt); 416 if (POINTER_TYPE_P (TREE_TYPE (rhs))) 417 expr = gimple_assign_rhs1 (stmt); 418 else 419 { 420 base = expr; 421 return; 422 } 423 } 424 else if (code == POINTER_PLUS_EXPR) 425 { 426 expr = gimple_assign_rhs1 (stmt); 427 offset = gimple_assign_rhs2 (stmt); 428 } 429 else 430 { 431 base = expr; 432 return; 433 } 434 } 435 else 436 { 437 /* FIXME: Handle PHI nodes in case like: 438 _12 = &MEM[(void *)&a + 2B] + _10; 439 440 <bb> [local count: 1073741824]: 441 # prephitmp_13 = PHI <_12, &MEM[(void *)&a + 2B]> 442 memcpy (prephitmp_13, p_7(D), 6); */ 443 base = expr; 444 return; 445 } 446 } 447 448 if (TREE_CODE (expr) == ADDR_EXPR) 449 expr = TREE_OPERAND (expr, 0); 450 451 /* Stash the reference for offset validation. */ 452 ref = expr; 453 454 poly_int64 bitsize, bitpos; 455 tree var_off; 456 machine_mode mode; 457 int sign, reverse, vol; 458 459 /* Determine the base object or pointer of the reference and 460 the constant bit offset from the beginning of the base. 461 If the offset has a non-constant component, it will be in 462 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and 463 unused here. */ 464 base = get_inner_reference (expr, &bitsize, &bitpos, &var_off, 465 &mode, &sign, &reverse, &vol); 466 467 /* get_inner_reference is not expected to return null. */ 468 gcc_assert (base != NULL); 469 470 if (offset) 471 extend_offset_range (offset); 472 473 poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT); 474 475 /* Convert the poly_int64 offset to offset_int. The offset 476 should be constant but be prepared for it not to be just in 477 case. */ 478 offset_int cstoff; 479 if (bytepos.is_constant (&cstoff)) 480 { 481 offrange[0] += cstoff; 482 offrange[1] += cstoff; 483 484 /* Besides the reference saved above, also stash the offset 485 for validation. */ 486 if (TREE_CODE (expr) == COMPONENT_REF) 487 refoff = cstoff; 488 } 489 else 490 offrange[1] += maxobjsize; 491 492 if (var_off) 493 { 494 if (TREE_CODE (var_off) == INTEGER_CST) 495 { 496 cstoff = wi::to_offset (var_off); 497 offrange[0] += cstoff; 498 offrange[1] += cstoff; 499 } 500 else 501 offrange[1] += maxobjsize; 502 } 503 504 if (TREE_CODE (base) == MEM_REF) 505 { 506 tree memrefoff = fold_convert (ptrdiff_type_node, TREE_OPERAND (base, 1)); 507 extend_offset_range (memrefoff); 508 509 if (refoff != HOST_WIDE_INT_MIN 510 && TREE_CODE (expr) == COMPONENT_REF) 511 { 512 /* Bump up the offset of the referenced subobject to reflect 513 the offset to the enclosing object. For example, so that 514 in 515 struct S { char a, b[3]; } s[2]; 516 strcpy (s[1].b, "1234"); 517 REFOFF is set to s[1].b - (char*)s. */ 518 offset_int off = tree_to_shwi (memrefoff); 519 refoff += off; 520 521 if (!integer_zerop (memrefoff) 522 && !COMPLETE_TYPE_P (TREE_TYPE (expr)) 523 && multiple_of_p (sizetype, memrefoff, 524 TYPE_SIZE_UNIT (TREE_TYPE (base)))) 525 /* A non-zero offset into an array of struct with flexible array 526 members implies that the array is empty because there is no 527 way to initialize such a member when it belongs to an array. 528 This must be some sort of a bug. */ 529 refsize = 0; 530 } 531 532 base = TREE_OPERAND (base, 0); 533 } 534 535 if (TREE_CODE (ref) == COMPONENT_REF) 536 if (tree size = component_ref_size (ref)) 537 if (TREE_CODE (size) == INTEGER_CST) 538 refsize = wi::to_offset (size); 539 540 if (TREE_CODE (base) == SSA_NAME) 541 set_base_and_offset (base); 542} 543 544/* Return error_mark_node if the signed offset exceeds the bounds 545 of the address space (PTRDIFF_MAX). Otherwise, return either BASE 546 or REF when the offset exceeds the bounds of the BASE or REF object, 547 and set OOBOFF to the past-the-end offset formed by the reference, 548 including its size. OOBOFF is initially setto the range of offsets, 549 and OOBOFF[2] to the offset of the first write access (nonzero for 550 the strcat family). When STRICT is nonzero use REF size, when 551 available, otherwise use BASE size. When STRICT is greater than 1, 552 use the size of the last array member as the bound, otherwise treat 553 such a member as a flexible array member. Return NULL when the offset 554 is in bounds. */ 555 556tree 557builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[3]) const 558{ 559 if (!ptr) 560 return NULL_TREE; 561 562 /* The offset of the first write access or zero. */ 563 offset_int wroff = ooboff[2]; 564 565 /* A temporary, possibly adjusted, copy of the offset range. */ 566 offset_int offrng[2] = { ooboff[0], ooboff[1] }; 567 568 if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE) 569 { 570 /* Check for offset in an anti-range with a negative lower bound. 571 For such a range, consider only the non-negative subrange. */ 572 if (offrng[1] < offrng[0] && offrng[1] < 0) 573 offrng[1] = maxobjsize; 574 } 575 576 /* Conservative offset of the last byte of the referenced object. */ 577 offset_int endoff; 578 579 /* The bounds need not be ordered. Set HIB to use as the index 580 of the larger of the bounds and LOB as the opposite. */ 581 bool hib = wi::les_p (offrng[0], offrng[1]); 582 bool lob = !hib; 583 584 /* Set to the size remaining in the object after subtracting 585 REFOFF. It may become negative as a result of negative indices 586 into the enclosing object, such as in: 587 extern struct S { char a[4], b[3], c[1]; } *p; 588 strcpy (p[-3].b, "123"); */ 589 offset_int size = basesize; 590 tree obj = base; 591 592 const bool decl_p = DECL_P (obj); 593 594 if (basesize < 0) 595 { 596 endoff = offrng[lob] + (sizrange[0] - wroff); 597 598 /* For a reference through a pointer to an object of unknown size 599 all initial offsets are considered valid, positive as well as 600 negative, since the pointer itself can point past the beginning 601 of the object. However, the sum of the lower bound of the offset 602 and that of the size must be less than or equal than PTRDIFF_MAX. */ 603 if (endoff > maxobjsize) 604 return error_mark_node; 605 606 /* When the referenced subobject is known, the end offset must be 607 within its bounds. Otherwise there is nothing to do. */ 608 if (strict 609 && !decl_p 610 && ref 611 && refsize >= 0 612 && TREE_CODE (ref) == COMPONENT_REF) 613 { 614 /* If REFOFF is negative, SIZE will become negative here. */ 615 size = refoff + refsize; 616 obj = ref; 617 } 618 else 619 return NULL_TREE; 620 } 621 622 /* A reference to an object of known size must be within the bounds 623 of either the base object or the subobject (see above for when 624 a subobject can be used). */ 625 if ((decl_p && offrng[hib] < 0) || offrng[lob] > size) 626 return obj; 627 628 /* The extent of the reference must also be within the bounds of 629 the base object (if known) or the subobject or the maximum object 630 size otherwise. */ 631 endoff = offrng[lob] + sizrange[0]; 632 if (endoff > maxobjsize) 633 return error_mark_node; 634 635 if (strict 636 && decl_p 637 && ref 638 && refsize >= 0 639 && TREE_CODE (ref) == COMPONENT_REF) 640 { 641 /* If the reference is to a member subobject of a declared object, 642 the offset must be within the bounds of the subobject. */ 643 size = refoff + refsize; 644 obj = ref; 645 } 646 647 if (endoff <= size) 648 return NULL_TREE; 649 650 /* Set the out-of-bounds offset range to be one greater than 651 that delimited by the reference including its size. */ 652 ooboff[lob] = size; 653 654 if (endoff > ooboff[lob]) 655 ooboff[hib] = endoff - 1; 656 else 657 ooboff[hib] = offrng[lob] + sizrange[1]; 658 659 return obj; 660} 661 662/* Create an association between the memory references DST and SRC 663 for access by a call EXPR to a memory or string built-in funtion. */ 664 665builtin_access::builtin_access (gimple *call, builtin_memref &dst, 666 builtin_memref &src) 667: dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (), 668 dstoff (), srcoff (), dstsiz (), srcsiz () 669{ 670 dstoff[0] = dst.offrange[0]; 671 dstoff[1] = dst.offrange[1]; 672 673 /* Zero out since the offset_int ctors invoked above are no-op. */ 674 srcoff[0] = srcoff[1] = 0; 675 dstsiz[0] = dstsiz[1] = 0; 676 srcsiz[0] = srcsiz[1] = 0; 677 678 /* Object Size Type to use to determine the size of the destination 679 and source objects. Overridden below for raw memory functions. */ 680 int ostype = 1; 681 682 /* True when the size of one reference depends on the offset of 683 itself or the other. */ 684 bool depends_p = true; 685 686 /* True when the size of the destination reference DSTREF has been 687 determined from SRCREF and so needs to be adjusted by the latter's 688 offset. Only meaningful for bounded string functions like strncpy. */ 689 bool dstadjust_p = false; 690 691 /* The size argument number (depends on the built-in). */ 692 unsigned sizeargno = 2; 693 694 tree func = gimple_call_fndecl (call); 695 switch (DECL_FUNCTION_CODE (func)) 696 { 697 case BUILT_IN_MEMCPY: 698 case BUILT_IN_MEMCPY_CHK: 699 case BUILT_IN_MEMPCPY: 700 case BUILT_IN_MEMPCPY_CHK: 701 ostype = 0; 702 depends_p = false; 703 detect_overlap = &builtin_access::generic_overlap; 704 break; 705 706 case BUILT_IN_MEMMOVE: 707 case BUILT_IN_MEMMOVE_CHK: 708 /* For memmove there is never any overlap to check for. */ 709 ostype = 0; 710 depends_p = false; 711 detect_overlap = &builtin_access::no_overlap; 712 break; 713 714 case BUILT_IN_MEMSET: 715 case BUILT_IN_MEMSET_CHK: 716 /* For memset there is never any overlap to check for. */ 717 ostype = 0; 718 depends_p = false; 719 detect_overlap = &builtin_access::no_overlap; 720 break; 721 722 case BUILT_IN_STPNCPY: 723 case BUILT_IN_STPNCPY_CHK: 724 case BUILT_IN_STRNCPY: 725 case BUILT_IN_STRNCPY_CHK: 726 dstref->strbounded_p = true; 727 detect_overlap = &builtin_access::strcpy_overlap; 728 break; 729 730 case BUILT_IN_STPCPY: 731 case BUILT_IN_STPCPY_CHK: 732 case BUILT_IN_STRCPY: 733 case BUILT_IN_STRCPY_CHK: 734 detect_overlap = &builtin_access::strcpy_overlap; 735 break; 736 737 case BUILT_IN_STRCAT: 738 case BUILT_IN_STRCAT_CHK: 739 detect_overlap = &builtin_access::strcat_overlap; 740 break; 741 742 case BUILT_IN_STRNCAT: 743 case BUILT_IN_STRNCAT_CHK: 744 dstref->strbounded_p = true; 745 srcref->strbounded_p = true; 746 detect_overlap = &builtin_access::strcat_overlap; 747 break; 748 749 default: 750 /* Handle other string functions here whose access may need 751 to be validated for in-bounds offsets and non-overlapping 752 copies. */ 753 return; 754 } 755 756 const offset_int maxobjsize = dst.maxobjsize; 757 758 /* Try to determine the size of the base object. compute_objsize 759 expects a pointer so create one if BASE is a non-pointer object. */ 760 tree addr; 761 if (dst.basesize < 0) 762 { 763 addr = dst.base; 764 if (!POINTER_TYPE_P (TREE_TYPE (addr))) 765 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr); 766 767 if (tree dstsize = compute_objsize (addr, ostype)) 768 dst.basesize = wi::to_offset (dstsize); 769 else if (POINTER_TYPE_P (TREE_TYPE (addr))) 770 dst.basesize = HOST_WIDE_INT_MIN; 771 else 772 dst.basesize = maxobjsize; 773 } 774 775 if (src.base && src.basesize < 0) 776 { 777 addr = src.base; 778 if (!POINTER_TYPE_P (TREE_TYPE (addr))) 779 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr); 780 781 if (tree srcsize = compute_objsize (addr, ostype)) 782 src.basesize = wi::to_offset (srcsize); 783 else if (POINTER_TYPE_P (TREE_TYPE (addr))) 784 src.basesize = HOST_WIDE_INT_MIN; 785 else 786 src.basesize = maxobjsize; 787 } 788 789 /* Make adjustments for references to the same object by string 790 built-in functions to reflect the constraints imposed by 791 the function. */ 792 793 /* For bounded string functions determine the range of the bound 794 on the access. For others, the range stays unbounded. */ 795 offset_int bounds[2] = { maxobjsize, maxobjsize }; 796 if (dstref->strbounded_p) 797 { 798 unsigned nargs = gimple_call_num_args (call); 799 if (nargs <= sizeargno) 800 return; 801 802 tree size = gimple_call_arg (call, sizeargno); 803 tree range[2]; 804 if (get_size_range (size, range, true)) 805 { 806 bounds[0] = wi::to_offset (range[0]); 807 bounds[1] = wi::to_offset (range[1]); 808 } 809 810 /* If both references' size ranges are indeterminate use the last 811 (size) argument from the function call as a substitute. This 812 may only be necessary for strncpy (but not for memcpy where 813 the size range would have been already determined this way). */ 814 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize 815 && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize) 816 { 817 dstref->sizrange[0] = bounds[0]; 818 dstref->sizrange[1] = bounds[1]; 819 } 820 } 821 822 bool dstsize_set = false; 823 /* The size range of one reference involving the same base object 824 can be determined from the size range of the other reference. 825 This makes it possible to compute accurate offsets for warnings 826 involving functions like strcpy where the length of just one of 827 the two arguments is known (determined by tree-ssa-strlen). */ 828 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize) 829 { 830 /* When the destination size is unknown set it to the size of 831 the source. */ 832 dstref->sizrange[0] = srcref->sizrange[0]; 833 dstref->sizrange[1] = srcref->sizrange[1]; 834 dstsize_set = true; 835 } 836 else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize) 837 { 838 /* When the size of the source access is unknown set it to the size 839 of the destination first and adjust it later if necessary. */ 840 srcref->sizrange[0] = dstref->sizrange[0]; 841 srcref->sizrange[1] = dstref->sizrange[1]; 842 843 if (depends_p) 844 { 845 if (dstref->strbounded_p) 846 { 847 /* Read access by strncpy is constrained by the third 848 argument but except for a zero bound is at least one. */ 849 srcref->sizrange[0] = bounds[1] > 0 ? 1 : 0; 850 offset_int bound = wi::umin (srcref->basesize, bounds[1]); 851 if (bound < srcref->sizrange[1]) 852 srcref->sizrange[1] = bound; 853 } 854 /* For string functions, adjust the size range of the source 855 reference by the inverse boundaries of the offset (because 856 the higher the offset into the string the shorter its 857 length). */ 858 if (srcref->offrange[1] >= 0 859 && srcref->offrange[1] < srcref->sizrange[0]) 860 srcref->sizrange[0] -= srcref->offrange[1]; 861 else 862 srcref->sizrange[0] = 1; 863 864 if (srcref->offrange[0] > 0) 865 { 866 if (srcref->offrange[0] < srcref->sizrange[1]) 867 srcref->sizrange[1] -= srcref->offrange[0]; 868 else 869 srcref->sizrange[1] = 0; 870 } 871 872 dstadjust_p = true; 873 } 874 } 875 876 if (detect_overlap == &builtin_access::generic_overlap) 877 { 878 if (dstref->strbounded_p) 879 { 880 dstref->sizrange[0] = bounds[0]; 881 dstref->sizrange[1] = bounds[1]; 882 883 if (dstref->sizrange[0] < srcref->sizrange[0]) 884 srcref->sizrange[0] = dstref->sizrange[0]; 885 886 if (dstref->sizrange[1] < srcref->sizrange[1]) 887 srcref->sizrange[1] = dstref->sizrange[1]; 888 } 889 } 890 else if (detect_overlap == &builtin_access::strcpy_overlap) 891 { 892 if (!dstref->strbounded_p) 893 { 894 /* For strcpy, adjust the destination size range to match that 895 of the source computed above. */ 896 if (depends_p && dstadjust_p) 897 { 898 dstref->sizrange[0] = srcref->sizrange[0]; 899 dstref->sizrange[1] = srcref->sizrange[1]; 900 } 901 } 902 } 903 else if (!dstsize_set && detect_overlap == &builtin_access::strcat_overlap) 904 { 905 dstref->sizrange[0] += srcref->sizrange[0] - 1; 906 dstref->sizrange[1] += srcref->sizrange[1] - 1; 907 } 908 909 if (dstref->strbounded_p) 910 { 911 /* For strncpy, adjust the destination size range to match that 912 of the source computed above. */ 913 dstref->sizrange[0] = bounds[0]; 914 dstref->sizrange[1] = bounds[1]; 915 916 if (bounds[0] < srcref->sizrange[0]) 917 srcref->sizrange[0] = bounds[0]; 918 919 if (bounds[1] < srcref->sizrange[1]) 920 srcref->sizrange[1] = bounds[1]; 921 } 922} 923 924offset_int 925builtin_access::overlap_size (const offset_int a[2], const offset_int b[2], 926 offset_int *off) 927{ 928 const offset_int *p = a; 929 const offset_int *q = b; 930 931 /* Point P at the bigger of the two ranges and Q at the smaller. */ 932 if (wi::lts_p (a[1] - a[0], b[1] - b[0])) 933 { 934 p = b; 935 q = a; 936 } 937 938 if (p[0] < q[0]) 939 { 940 if (p[1] < q[0]) 941 return 0; 942 943 *off = q[0]; 944 return wi::smin (p[1], q[1]) - q[0]; 945 } 946 947 if (q[1] < p[0]) 948 return 0; 949 950 off[0] = p[0]; 951 return q[1] - p[0]; 952} 953 954/* Return true if the bounded mempry (memcpy amd similar) or string function 955 access (strncpy and similar) ACS overlaps. */ 956 957bool 958builtin_access::generic_overlap () 959{ 960 builtin_access &acs = *this; 961 const builtin_memref *dstref = acs.dstref; 962 const builtin_memref *srcref = acs.srcref; 963 964 gcc_assert (dstref->base == srcref->base); 965 966 const offset_int maxobjsize = acs.dstref->maxobjsize; 967 968 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize; 969 970 /* Adjust the larger bounds of the offsets (which may be the first 971 element if the lower bound is larger than the upper bound) to 972 make them valid for the smallest access (if possible) but no smaller 973 than the smaller bounds. */ 974 gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1])); 975 976 if (maxsize < acs.dstoff[1] + acs.dstsiz[0]) 977 acs.dstoff[1] = maxsize - acs.dstsiz[0]; 978 if (acs.dstoff[1] < acs.dstoff[0]) 979 acs.dstoff[1] = acs.dstoff[0]; 980 981 gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1])); 982 983 if (maxsize < acs.srcoff[1] + acs.srcsiz[0]) 984 acs.srcoff[1] = maxsize - acs.srcsiz[0]; 985 if (acs.srcoff[1] < acs.srcoff[0]) 986 acs.srcoff[1] = acs.srcoff[0]; 987 988 /* Determine the minimum and maximum space for the access given 989 the offsets. */ 990 offset_int space[2]; 991 space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]); 992 space[1] = space[0]; 993 994 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]); 995 if (acs.srcsiz[0] > 0) 996 { 997 if (d < space[0]) 998 space[0] = d; 999 1000 if (space[1] < d) 1001 space[1] = d; 1002 } 1003 else 1004 space[1] = acs.dstsiz[1]; 1005 1006 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]); 1007 if (d < space[0]) 1008 space[0] = d; 1009 1010 if (space[1] < d) 1011 space[1] = d; 1012 1013 /* Treat raw memory functions both of whose references are bounded 1014 as special and permit uncertain overlaps to go undetected. For 1015 all kinds of constant offset and constant size accesses, if 1016 overlap isn't certain it is not possible. */ 1017 bool overlap_possible = space[0] < acs.dstsiz[1]; 1018 if (!overlap_possible) 1019 return false; 1020 1021 bool overlap_certain = space[1] < acs.dstsiz[0]; 1022 1023 /* True when the size of one reference depends on the offset of 1024 the other. */ 1025 bool depends_p = detect_overlap != &builtin_access::generic_overlap; 1026 1027 if (!overlap_certain) 1028 { 1029 if (!dstref->strbounded_p && !depends_p) 1030 /* Memcpy only considers certain overlap. */ 1031 return false; 1032 1033 /* There's no way to distinguish an access to the same member 1034 of a structure from one to two distinct members of the same 1035 structure. Give up to avoid excessive false positives. */ 1036 tree basetype = TREE_TYPE (dstref->base); 1037 1038 if (POINTER_TYPE_P (basetype)) 1039 basetype = TREE_TYPE (basetype); 1040 else 1041 while (TREE_CODE (basetype) == ARRAY_TYPE) 1042 basetype = TREE_TYPE (basetype); 1043 1044 if (RECORD_OR_UNION_TYPE_P (basetype)) 1045 return false; 1046 } 1047 1048 /* True for stpcpy and strcpy. */ 1049 bool stxcpy_p = (!dstref->strbounded_p 1050 && detect_overlap == &builtin_access::strcpy_overlap); 1051 1052 if (dstref->refoff >= 0 1053 && srcref->refoff >= 0 1054 && dstref->refoff != srcref->refoff 1055 && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p)) 1056 return false; 1057 1058 offset_int siz[2] = { maxobjsize + 1, 0 }; 1059 1060 ovloff[0] = HOST_WIDE_INT_MAX; 1061 ovloff[1] = HOST_WIDE_INT_MIN; 1062 1063 if (stxcpy_p) 1064 { 1065 /* Iterate over the extreme locations (on the horizontal axis formed 1066 by their offsets) and sizes of two regions and find their smallest 1067 and largest overlap and the corresponding offsets. */ 1068 for (unsigned i = 0; i != 2; ++i) 1069 { 1070 const offset_int a[2] = { 1071 acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i] 1072 }; 1073 1074 const offset_int b[2] = { 1075 acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i] 1076 }; 1077 1078 offset_int off; 1079 offset_int sz = overlap_size (a, b, &off); 1080 if (sz < siz[0]) 1081 siz[0] = sz; 1082 1083 if (siz[1] <= sz) 1084 siz[1] = sz; 1085 1086 if (sz != 0) 1087 { 1088 if (wi::lts_p (off, ovloff[0])) 1089 ovloff[0] = off.to_shwi (); 1090 if (wi::lts_p (ovloff[1], off)) 1091 ovloff[1] = off.to_shwi (); 1092 } 1093 } 1094 } 1095 else 1096 { 1097 /* Iterate over the extreme locations (on the horizontal axis 1098 formed by their offsets) and sizes of the two regions and 1099 find their smallest and largest overlap and the corresponding 1100 offsets. */ 1101 1102 for (unsigned io = 0; io != 2; ++io) 1103 for (unsigned is = 0; is != 2; ++is) 1104 { 1105 const offset_int a[2] = { 1106 acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is] 1107 }; 1108 1109 for (unsigned jo = 0; jo != 2; ++jo) 1110 for (unsigned js = 0; js != 2; ++js) 1111 { 1112 const offset_int b[2] = { 1113 acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js] 1114 }; 1115 1116 offset_int off; 1117 offset_int sz = overlap_size (a, b, &off); 1118 if (sz < siz[0]) 1119 siz[0] = sz; 1120 1121 if (siz[1] <= sz) 1122 siz[1] = sz; 1123 1124 if (sz != 0) 1125 { 1126 if (wi::lts_p (off, ovloff[0])) 1127 ovloff[0] = off.to_shwi (); 1128 if (wi::lts_p (ovloff[1], off)) 1129 ovloff[1] = off.to_shwi (); 1130 } 1131 } 1132 } 1133 } 1134 1135 ovlsiz[0] = siz[0].to_shwi (); 1136 ovlsiz[1] = siz[1].to_shwi (); 1137 1138 /* Adjust the overlap offset range to reflect the overlap size range. */ 1139 if (ovlsiz[0] == 0 && ovlsiz[1] > 1) 1140 ovloff[1] = ovloff[0] + ovlsiz[1] - 1; 1141 1142 return true; 1143} 1144 1145/* Return true if the strcat-like access overlaps. */ 1146 1147bool 1148builtin_access::strcat_overlap () 1149{ 1150 builtin_access &acs = *this; 1151 const builtin_memref *dstref = acs.dstref; 1152 const builtin_memref *srcref = acs.srcref; 1153 1154 gcc_assert (dstref->base == srcref->base); 1155 1156 const offset_int maxobjsize = acs.dstref->maxobjsize; 1157 1158 gcc_assert (dstref->base && dstref->base == srcref->base); 1159 1160 /* Adjust for strcat-like accesses. */ 1161 1162 /* As a special case for strcat, set the DSTREF offsets to the length 1163 of the destination string since the function starts writing over 1164 its terminating nul, and set the destination size to 1 for the length 1165 of the nul. */ 1166 acs.dstoff[0] += dstsiz[0] - srcref->sizrange[0]; 1167 acs.dstoff[1] += dstsiz[1] - srcref->sizrange[1]; 1168 1169 bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0; 1170 1171 /* The lower bound is zero when the size is unknown because then 1172 overlap is not certain. */ 1173 acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1; 1174 acs.dstsiz[1] = 1; 1175 1176 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize; 1177 1178 /* For references to the same base object, determine if there's a pair 1179 of valid offsets into the two references such that access between 1180 them doesn't overlap. Adjust both upper bounds to be valid for 1181 the smaller size (i.e., at most MAXSIZE - SIZE). */ 1182 1183 if (maxsize < acs.dstoff[1] + acs.dstsiz[0]) 1184 acs.dstoff[1] = maxsize - acs.dstsiz[0]; 1185 1186 if (maxsize < acs.srcoff[1] + acs.srcsiz[0]) 1187 acs.srcoff[1] = maxsize - acs.srcsiz[0]; 1188 1189 /* Check to see if there's enough space for both accesses without 1190 overlap. Determine the optimistic (maximum) amount of available 1191 space. */ 1192 offset_int space; 1193 if (acs.dstoff[0] <= acs.srcoff[0]) 1194 { 1195 if (acs.dstoff[1] < acs.srcoff[1]) 1196 space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0]; 1197 else 1198 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0]; 1199 } 1200 else 1201 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0]; 1202 1203 /* Overlap is certain if the distance between the farthest offsets 1204 of the opposite accesses is less than the sum of the lower bounds 1205 of the sizes of the two accesses. */ 1206 bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0]; 1207 1208 /* For a constant-offset, constant size access, consider the largest 1209 distance between the offset bounds and the lower bound of the access 1210 size. If the overlap isn't certain return success. */ 1211 if (!overlap_certain 1212 && acs.dstoff[0] == acs.dstoff[1] 1213 && acs.srcoff[0] == acs.srcoff[1] 1214 && acs.dstsiz[0] == acs.dstsiz[1] 1215 && acs.srcsiz[0] == acs.srcsiz[1]) 1216 return false; 1217 1218 /* Overlap is not certain but may be possible. */ 1219 1220 offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0]; 1221 1222 /* Determine the conservative (minimum) amount of space. */ 1223 space = wi::abs (acs.dstoff[0] - acs.srcoff[0]); 1224 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]); 1225 if (d < space) 1226 space = d; 1227 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]); 1228 if (d < space) 1229 space = d; 1230 1231 /* For a strict test (used for strcpy and similar with unknown or 1232 variable bounds or sizes), consider the smallest distance between 1233 the offset bounds and either the upper bound of the access size 1234 if known, or the lower bound otherwise. */ 1235 if (access_min <= space && (access_min != 0 || !strfunc_unknown_args)) 1236 return false; 1237 1238 /* When strcat overlap is certain it is always a single byte: 1239 the terminating NUL, regardless of offsets and sizes. When 1240 overlap is only possible its range is [0, 1]. */ 1241 acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0; 1242 acs.ovlsiz[1] = 1; 1243 1244 offset_int endoff 1245 = dstref->offrange[0] + (dstref->sizrange[0] - srcref->sizrange[0]); 1246 if (endoff <= srcref->offrange[0]) 1247 acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi (); 1248 else 1249 acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi (); 1250 1251 acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1, 1252 srcref->sizrange[0]).to_shwi (); 1253 if (dstref->offrange[0] == dstref->offrange[1]) 1254 { 1255 if (srcref->offrange[0] == srcref->offrange[1]) 1256 acs.ovloff[1] = acs.ovloff[0]; 1257 else 1258 acs.ovloff[1] 1259 = wi::smin (maxobjsize, 1260 srcref->offrange[1] + srcref->sizrange[1]).to_shwi (); 1261 } 1262 else 1263 acs.ovloff[1] 1264 = wi::smin (maxobjsize, 1265 dstref->offrange[1] + dstref->sizrange[1]).to_shwi (); 1266 1267 if (acs.sizrange[0] == 0) 1268 acs.sizrange[0] = 1; 1269 acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi (); 1270 return true; 1271} 1272 1273/* Return true if the strcpy-like access overlaps. */ 1274 1275bool 1276builtin_access::strcpy_overlap () 1277{ 1278 return generic_overlap (); 1279} 1280 1281 1282/* Return true if DSTREF and SRCREF describe accesses that either overlap 1283 one another or that, in order not to overlap, would imply that the size 1284 of the referenced object(s) exceeds the maximum size of an object. Set 1285 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though 1286 they may overlap in a way that's not apparent from the available data), 1287 return false. */ 1288 1289bool 1290builtin_access::overlap () 1291{ 1292 builtin_access &acs = *this; 1293 1294 const offset_int maxobjsize = dstref->maxobjsize; 1295 1296 acs.sizrange[0] = wi::smax (dstref->sizrange[0], 1297 srcref->sizrange[0]).to_shwi (); 1298 acs.sizrange[1] = wi::smax (dstref->sizrange[1], 1299 srcref->sizrange[1]).to_shwi (); 1300 1301 /* Check to see if the two references refer to regions that are 1302 too large not to overlap in the address space (whose maximum 1303 size is PTRDIFF_MAX). */ 1304 offset_int size = dstref->sizrange[0] + srcref->sizrange[0]; 1305 if (maxobjsize < size) 1306 { 1307 acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi (); 1308 acs.ovlsiz[0] = (size - maxobjsize).to_shwi (); 1309 return true; 1310 } 1311 1312 /* If both base objects aren't known return the maximum possible 1313 offset that would make them not overlap. */ 1314 if (!dstref->base || !srcref->base) 1315 return false; 1316 1317 /* If the base object is an array adjust the bounds of the offset 1318 to be non-negative and within the bounds of the array if possible. */ 1319 if (dstref->base 1320 && TREE_CODE (TREE_TYPE (dstref->base)) == ARRAY_TYPE) 1321 { 1322 if (acs.dstoff[0] < 0 && acs.dstoff[1] >= 0) 1323 acs.dstoff[0] = 0; 1324 1325 if (acs.dstoff[1] < acs.dstoff[0]) 1326 { 1327 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (dstref->base))) 1328 acs.dstoff[1] = wi::umin (acs.dstoff[1], wi::to_offset (size)); 1329 else 1330 acs.dstoff[1] = wi::umin (acs.dstoff[1], maxobjsize); 1331 } 1332 } 1333 1334 acs.srcoff[0] = srcref->offrange[0]; 1335 acs.srcoff[1] = srcref->offrange[1]; 1336 1337 if (srcref->base 1338 && TREE_CODE (TREE_TYPE (srcref->base)) == ARRAY_TYPE) 1339 { 1340 if (acs.srcoff[0] < 0 && acs.srcoff[1] >= 0) 1341 acs.srcoff[0] = 0; 1342 1343 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (srcref->base))) 1344 acs.srcoff[1] = wi::umin (acs.srcoff[1], wi::to_offset (size)); 1345 else if (acs.srcoff[1] < acs.srcoff[0]) 1346 acs.srcoff[1] = wi::umin (acs.srcoff[1], maxobjsize); 1347 } 1348 1349 /* When the upper bound of the offset is less than the lower bound 1350 the former is the result of a negative offset being represented 1351 as a large positive value or vice versa. The resulting range is 1352 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such 1353 a union is not representable using the current data structure 1354 replace it with the full range of offsets. */ 1355 if (acs.dstoff[1] < acs.dstoff[0]) 1356 { 1357 acs.dstoff[0] = -maxobjsize - 1; 1358 acs.dstoff[1] = maxobjsize; 1359 } 1360 1361 /* Validate the offset and size of each reference on its own first. 1362 This is independent of whether or not the base objects are the 1363 same. Normally, this would have already been detected and 1364 diagnosed by -Warray-bounds, unless it has been disabled. */ 1365 offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0]; 1366 if (maxobjsize < maxoff) 1367 { 1368 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi (); 1369 acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0]; 1370 return true; 1371 } 1372 1373 /* Repeat the same as above but for the source offsets. */ 1374 if (acs.srcoff[1] < acs.srcoff[0]) 1375 { 1376 acs.srcoff[0] = -maxobjsize - 1; 1377 acs.srcoff[1] = maxobjsize; 1378 } 1379 1380 maxoff = acs.srcoff[0] + srcref->sizrange[0]; 1381 if (maxobjsize < maxoff) 1382 { 1383 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi (); 1384 acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1] 1385 - maxobjsize).to_shwi (); 1386 acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0]; 1387 return true; 1388 } 1389 1390 if (dstref->base != srcref->base) 1391 return false; 1392 1393 acs.dstsiz[0] = dstref->sizrange[0]; 1394 acs.dstsiz[1] = dstref->sizrange[1]; 1395 1396 acs.srcsiz[0] = srcref->sizrange[0]; 1397 acs.srcsiz[1] = srcref->sizrange[1]; 1398 1399 /* Call the appropriate function to determine the overlap. */ 1400 if ((this->*detect_overlap) ()) 1401 { 1402 if (!sizrange[1]) 1403 { 1404 /* Unless the access size range has already been set, do so here. */ 1405 sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi (); 1406 sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi (); 1407 } 1408 return true; 1409 } 1410 1411 return false; 1412} 1413 1414/* Attempt to detect and diagnose an overlapping copy in a call expression 1415 EXPR involving an access ACS to a built-in memory or string function. 1416 Return true when one has been detected, false otherwise. */ 1417 1418static bool 1419maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs) 1420{ 1421 if (!acs.overlap ()) 1422 return false; 1423 1424 if (gimple_no_warning_p (call)) 1425 return true; 1426 1427 /* For convenience. */ 1428 const builtin_memref &dstref = *acs.dstref; 1429 const builtin_memref &srcref = *acs.srcref; 1430 1431 /* Determine the range of offsets and sizes of the overlap if it 1432 exists and issue diagnostics. */ 1433 HOST_WIDE_INT *ovloff = acs.ovloff; 1434 HOST_WIDE_INT *ovlsiz = acs.ovlsiz; 1435 HOST_WIDE_INT *sizrange = acs.sizrange; 1436 1437 tree func = gimple_call_fndecl (call); 1438 1439 /* To avoid a combinatorial explosion of diagnostics format the offsets 1440 or their ranges as strings and use them in the warning calls below. */ 1441 char offstr[3][64]; 1442 1443 if (dstref.offrange[0] == dstref.offrange[1] 1444 || dstref.offrange[1] > HOST_WIDE_INT_MAX) 1445 sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC, 1446 dstref.offrange[0].to_shwi ()); 1447 else 1448 sprintf (offstr[0], 1449 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]", 1450 dstref.offrange[0].to_shwi (), 1451 dstref.offrange[1].to_shwi ()); 1452 1453 if (srcref.offrange[0] == srcref.offrange[1] 1454 || srcref.offrange[1] > HOST_WIDE_INT_MAX) 1455 sprintf (offstr[1], 1456 HOST_WIDE_INT_PRINT_DEC, 1457 srcref.offrange[0].to_shwi ()); 1458 else 1459 sprintf (offstr[1], 1460 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]", 1461 srcref.offrange[0].to_shwi (), 1462 srcref.offrange[1].to_shwi ()); 1463 1464 if (ovloff[0] == ovloff[1] || !ovloff[1]) 1465 sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]); 1466 else 1467 sprintf (offstr[2], 1468 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]", 1469 ovloff[0], ovloff[1]); 1470 1471 const offset_int maxobjsize = dstref.maxobjsize; 1472 bool must_overlap = ovlsiz[0] > 0; 1473 1474 if (ovlsiz[1] == 0) 1475 ovlsiz[1] = ovlsiz[0]; 1476 1477 if (must_overlap) 1478 { 1479 /* Issue definitive "overlaps" diagnostic in this block. */ 1480 1481 if (sizrange[0] == sizrange[1]) 1482 { 1483 if (ovlsiz[0] == ovlsiz[1]) 1484 warning_at (loc, OPT_Wrestrict, 1485 sizrange[0] == 1 1486 ? (ovlsiz[0] == 1 1487 ? G_("%G%qD accessing %wu byte at offsets %s " 1488 "and %s overlaps %wu byte at offset %s") 1489 : G_("%G%qD accessing %wu byte at offsets %s " 1490 "and %s overlaps %wu bytes at offset " 1491 "%s")) 1492 : (ovlsiz[0] == 1 1493 ? G_("%G%qD accessing %wu bytes at offsets %s " 1494 "and %s overlaps %wu byte at offset %s") 1495 : G_("%G%qD accessing %wu bytes at offsets %s " 1496 "and %s overlaps %wu bytes at offset " 1497 "%s")), 1498 call, func, sizrange[0], 1499 offstr[0], offstr[1], ovlsiz[0], offstr[2]); 1500 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ()) 1501 warning_n (loc, OPT_Wrestrict, sizrange[0], 1502 "%G%qD accessing %wu byte at offsets %s " 1503 "and %s overlaps between %wu and %wu bytes " 1504 "at offset %s", 1505 "%G%qD accessing %wu bytes at offsets %s " 1506 "and %s overlaps between %wu and %wu bytes " 1507 "at offset %s", 1508 call, func, sizrange[0], offstr[0], offstr[1], 1509 ovlsiz[0], ovlsiz[1], offstr[2]); 1510 else 1511 warning_n (loc, OPT_Wrestrict, sizrange[0], 1512 "%G%qD accessing %wu byte at offsets %s and " 1513 "%s overlaps %wu or more bytes at offset %s", 1514 "%G%qD accessing %wu bytes at offsets %s and " 1515 "%s overlaps %wu or more bytes at offset %s", 1516 call, func, sizrange[0], 1517 offstr[0], offstr[1], ovlsiz[0], offstr[2]); 1518 return true; 1519 } 1520 1521 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ()) 1522 { 1523 if (ovlsiz[0] == ovlsiz[1]) 1524 warning_n (loc, OPT_Wrestrict, ovlsiz[0], 1525 "%G%qD accessing between %wu and %wu bytes " 1526 "at offsets %s and %s overlaps %wu byte at " 1527 "offset %s", 1528 "%G%qD accessing between %wu and %wu bytes " 1529 "at offsets %s and %s overlaps %wu bytes " 1530 "at offset %s", 1531 call, func, sizrange[0], sizrange[1], 1532 offstr[0], offstr[1], ovlsiz[0], offstr[2]); 1533 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ()) 1534 warning_at (loc, OPT_Wrestrict, 1535 "%G%qD accessing between %wu and %wu bytes at " 1536 "offsets %s and %s overlaps between %wu and %wu " 1537 "bytes at offset %s", 1538 call, func, sizrange[0], sizrange[1], 1539 offstr[0], offstr[1], ovlsiz[0], ovlsiz[1], 1540 offstr[2]); 1541 else 1542 warning_at (loc, OPT_Wrestrict, 1543 "%G%qD accessing between %wu and %wu bytes at " 1544 "offsets %s and %s overlaps %wu or more bytes " 1545 "at offset %s", 1546 call, func, sizrange[0], sizrange[1], 1547 offstr[0], offstr[1], ovlsiz[0], offstr[2]); 1548 return true; 1549 } 1550 1551 if (ovlsiz[0] != ovlsiz[1]) 1552 ovlsiz[1] = maxobjsize.to_shwi (); 1553 1554 if (ovlsiz[0] == ovlsiz[1]) 1555 warning_n (loc, OPT_Wrestrict, ovlsiz[0], 1556 "%G%qD accessing %wu or more bytes at offsets " 1557 "%s and %s overlaps %wu byte at offset %s", 1558 "%G%qD accessing %wu or more bytes at offsets " 1559 "%s and %s overlaps %wu bytes at offset %s", 1560 call, func, sizrange[0], offstr[0], offstr[1], 1561 ovlsiz[0], offstr[2]); 1562 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ()) 1563 warning_at (loc, OPT_Wrestrict, 1564 "%G%qD accessing %wu or more bytes at offsets %s " 1565 "and %s overlaps between %wu and %wu bytes " 1566 "at offset %s", 1567 call, func, sizrange[0], offstr[0], offstr[1], 1568 ovlsiz[0], ovlsiz[1], offstr[2]); 1569 else 1570 warning_at (loc, OPT_Wrestrict, 1571 "%G%qD accessing %wu or more bytes at offsets %s " 1572 "and %s overlaps %wu or more bytes at offset %s", 1573 call, func, sizrange[0], offstr[0], offstr[1], 1574 ovlsiz[0], offstr[2]); 1575 return true; 1576 } 1577 1578 /* Use more concise wording when one of the offsets is unbounded 1579 to avoid confusing the user with large and mostly meaningless 1580 numbers. */ 1581 bool open_range; 1582 if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE) 1583 open_range = ((dstref.offrange[0] == 0 1584 && dstref.offrange[1] == maxobjsize) 1585 || (srcref.offrange[0] == 0 1586 && srcref.offrange[1] == maxobjsize)); 1587 else 1588 open_range = ((dstref.offrange[0] == -maxobjsize - 1 1589 && dstref.offrange[1] == maxobjsize) 1590 || (srcref.offrange[0] == -maxobjsize - 1 1591 && srcref.offrange[1] == maxobjsize)); 1592 1593 if (sizrange[0] == sizrange[1] || sizrange[1] == 1) 1594 { 1595 if (ovlsiz[1] == 1) 1596 { 1597 if (open_range) 1598 warning_n (loc, OPT_Wrestrict, sizrange[1], 1599 "%G%qD accessing %wu byte may overlap " 1600 "%wu byte", 1601 "%G%qD accessing %wu bytes may overlap " 1602 "%wu byte", 1603 call, func, sizrange[1], ovlsiz[1]); 1604 else 1605 warning_n (loc, OPT_Wrestrict, sizrange[1], 1606 "%G%qD accessing %wu byte at offsets %s " 1607 "and %s may overlap %wu byte at offset %s", 1608 "%G%qD accessing %wu bytes at offsets %s " 1609 "and %s may overlap %wu byte at offset %s", 1610 call, func, sizrange[1], offstr[0], offstr[1], 1611 ovlsiz[1], offstr[2]); 1612 return true; 1613 } 1614 1615 if (open_range) 1616 warning_n (loc, OPT_Wrestrict, sizrange[1], 1617 "%G%qD accessing %wu byte may overlap " 1618 "up to %wu bytes", 1619 "%G%qD accessing %wu bytes may overlap " 1620 "up to %wu bytes", 1621 call, func, sizrange[1], ovlsiz[1]); 1622 else 1623 warning_n (loc, OPT_Wrestrict, sizrange[1], 1624 "%G%qD accessing %wu byte at offsets %s and " 1625 "%s may overlap up to %wu bytes at offset %s", 1626 "%G%qD accessing %wu bytes at offsets %s and " 1627 "%s may overlap up to %wu bytes at offset %s", 1628 call, func, sizrange[1], offstr[0], offstr[1], 1629 ovlsiz[1], offstr[2]); 1630 return true; 1631 } 1632 1633 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ()) 1634 { 1635 if (open_range) 1636 warning_n (loc, OPT_Wrestrict, ovlsiz[1], 1637 "%G%qD accessing between %wu and %wu bytes " 1638 "may overlap %wu byte", 1639 "%G%qD accessing between %wu and %wu bytes " 1640 "may overlap up to %wu bytes", 1641 call, func, sizrange[0], sizrange[1], ovlsiz[1]); 1642 else 1643 warning_n (loc, OPT_Wrestrict, ovlsiz[1], 1644 "%G%qD accessing between %wu and %wu bytes " 1645 "at offsets %s and %s may overlap %wu byte " 1646 "at offset %s", 1647 "%G%qD accessing between %wu and %wu bytes " 1648 "at offsets %s and %s may overlap up to %wu " 1649 "bytes at offset %s", 1650 call, func, sizrange[0], sizrange[1], 1651 offstr[0], offstr[1], ovlsiz[1], offstr[2]); 1652 return true; 1653 } 1654 1655 warning_n (loc, OPT_Wrestrict, ovlsiz[1], 1656 "%G%qD accessing %wu or more bytes at offsets %s " 1657 "and %s may overlap %wu byte at offset %s", 1658 "%G%qD accessing %wu or more bytes at offsets %s " 1659 "and %s may overlap up to %wu bytes at offset %s", 1660 call, func, sizrange[0], offstr[0], offstr[1], 1661 ovlsiz[1], offstr[2]); 1662 1663 return true; 1664} 1665 1666/* Validate REF size and offsets in an expression passed as an argument 1667 to a CALL to a built-in function FUNC to make sure they are within 1668 the bounds of the referenced object if its size is known, or 1669 PTRDIFF_MAX otherwise. DO_WARN is true when a diagnostic should 1670 be issued, false otherwise. 1671 Both initial values of the offsets and their final value computed 1672 by the function by incrementing the initial value by the size are 1673 validated. Return true if the offsets are not valid and a diagnostic 1674 has been issued, or would have been issued if DO_WARN had been true. */ 1675 1676static bool 1677maybe_diag_access_bounds (gimple *call, tree func, int strict, 1678 const builtin_memref &ref, offset_int wroff, 1679 bool do_warn) 1680{ 1681 location_t loc = gimple_or_expr_nonartificial_location (call, ref.ptr); 1682 const offset_int maxobjsize = ref.maxobjsize; 1683 1684 /* Check for excessive size first and regardless of warning options 1685 since the result is used to make codegen decisions. */ 1686 if (ref.sizrange[0] > maxobjsize) 1687 { 1688 /* Return true without issuing a warning. */ 1689 if (!do_warn) 1690 return true; 1691 1692 if (ref.ref && TREE_NO_WARNING (ref.ref)) 1693 return false; 1694 1695 if (warn_stringop_overflow) 1696 { 1697 if (ref.sizrange[0] == ref.sizrange[1]) 1698 return warning_at (loc, OPT_Wstringop_overflow_, 1699 "%G%qD specified bound %wu " 1700 "exceeds maximum object size %wu", 1701 call, func, ref.sizrange[0].to_uhwi (), 1702 maxobjsize.to_uhwi ()); 1703 1704 return warning_at (loc, OPT_Wstringop_overflow_, 1705 "%G%qD specified bound between %wu and %wu " 1706 "exceeds maximum object size %wu", 1707 call, func, ref.sizrange[0].to_uhwi (), 1708 ref.sizrange[1].to_uhwi (), 1709 maxobjsize.to_uhwi ()); 1710 } 1711 } 1712 1713 /* Check for out-bounds pointers regardless of warning options since 1714 the result is used to make codegen decisions. An excessive WROFF 1715 can only come up as a result of an invalid strncat bound and is 1716 diagnosed separately using a more meaningful warning. */ 1717 if (maxobjsize < wroff) 1718 wroff = 0; 1719 offset_int ooboff[] = { ref.offrange[0], ref.offrange[1], wroff }; 1720 tree oobref = ref.offset_out_of_bounds (strict, ooboff); 1721 if (!oobref) 1722 return false; 1723 1724 /* Return true without issuing a warning. */ 1725 if (!do_warn) 1726 return true; 1727 1728 if (!warn_array_bounds) 1729 return false; 1730 1731 if (TREE_NO_WARNING (ref.ptr) 1732 || (ref.ref && TREE_NO_WARNING (ref.ref))) 1733 return false; 1734 1735 char rangestr[2][64]; 1736 if (ooboff[0] == ooboff[1] 1737 || (ooboff[0] != ref.offrange[0] 1738 && ooboff[0].to_shwi () >= ooboff[1].to_shwi ())) 1739 sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ()); 1740 else 1741 sprintf (rangestr[0], "[%lli, %lli]", 1742 (long long) ooboff[0].to_shwi (), 1743 (long long) ooboff[1].to_shwi ()); 1744 1745 bool warned = false; 1746 1747 if (oobref == error_mark_node) 1748 { 1749 if (ref.sizrange[0] == ref.sizrange[1]) 1750 sprintf (rangestr[1], "%llu", 1751 (unsigned long long) ref.sizrange[0].to_shwi ()); 1752 else 1753 sprintf (rangestr[1], "[%lli, %lli]", 1754 (unsigned long long) ref.sizrange[0].to_uhwi (), 1755 (unsigned long long) ref.sizrange[1].to_uhwi ()); 1756 1757 tree type; 1758 1759 if (DECL_P (ref.base) 1760 && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE) 1761 { 1762 auto_diagnostic_group d; 1763 if (warning_at (loc, OPT_Warray_bounds, 1764 "%G%qD pointer overflow between offset %s " 1765 "and size %s accessing array %qD with type %qT", 1766 call, func, rangestr[0], rangestr[1], ref.base, type)) 1767 { 1768 inform (DECL_SOURCE_LOCATION (ref.base), 1769 "array %qD declared here", ref.base); 1770 warned = true; 1771 } 1772 else 1773 warned = warning_at (loc, OPT_Warray_bounds, 1774 "%G%qD pointer overflow between offset %s " 1775 "and size %s", 1776 call, func, rangestr[0], rangestr[1]); 1777 } 1778 else 1779 warned = warning_at (loc, OPT_Warray_bounds, 1780 "%G%qD pointer overflow between offset %s " 1781 "and size %s", 1782 call, func, rangestr[0], rangestr[1]); 1783 } 1784 else if (oobref == ref.base) 1785 { 1786 /* True when the offset formed by an access to the reference 1787 is out of bounds, rather than the initial offset wich is 1788 in bounds. This implies access past the end. */ 1789 bool form = ooboff[0] != ref.offrange[0]; 1790 1791 if (DECL_P (ref.base)) 1792 { 1793 auto_diagnostic_group d; 1794 if ((ref.basesize < maxobjsize 1795 && warning_at (loc, OPT_Warray_bounds, 1796 form 1797 ? G_("%G%qD forming offset %s is out of " 1798 "the bounds [0, %wu] of object %qD with " 1799 "type %qT") 1800 : G_("%G%qD offset %s is out of the bounds " 1801 "[0, %wu] of object %qD with type %qT"), 1802 call, func, rangestr[0], ref.basesize.to_uhwi (), 1803 ref.base, TREE_TYPE (ref.base))) 1804 || warning_at (loc, OPT_Warray_bounds, 1805 form 1806 ? G_("%G%qD forming offset %s is out of " 1807 "the bounds of object %qD with type %qT") 1808 : G_("%G%qD offset %s is out of the bounds " 1809 "of object %qD with type %qT"), 1810 call, func, rangestr[0], 1811 ref.base, TREE_TYPE (ref.base))) 1812 { 1813 inform (DECL_SOURCE_LOCATION (ref.base), 1814 "%qD declared here", ref.base); 1815 warned = true; 1816 } 1817 } 1818 else if (ref.basesize < maxobjsize) 1819 warned = warning_at (loc, OPT_Warray_bounds, 1820 form 1821 ? G_("%G%qD forming offset %s is out " 1822 "of the bounds [0, %wu]") 1823 : G_("%G%qD offset %s is out " 1824 "of the bounds [0, %wu]"), 1825 call, func, rangestr[0], ref.basesize.to_uhwi ()); 1826 else 1827 warned = warning_at (loc, OPT_Warray_bounds, 1828 form 1829 ? G_("%G%qD forming offset %s is out of bounds") 1830 : G_("%G%qD offset %s is out of bounds"), 1831 call, func, rangestr[0]); 1832 } 1833 else if (TREE_CODE (ref.ref) == MEM_REF) 1834 { 1835 tree refop = TREE_OPERAND (ref.ref, 0); 1836 tree type = TREE_TYPE (refop); 1837 if (POINTER_TYPE_P (type)) 1838 type = TREE_TYPE (type); 1839 type = TYPE_MAIN_VARIANT (type); 1840 1841 if (warning_at (loc, OPT_Warray_bounds, 1842 "%G%qD offset %s from the object at %qE is out " 1843 "of the bounds of %qT", 1844 call, func, rangestr[0], ref.base, type)) 1845 { 1846 if (TREE_CODE (ref.ref) == COMPONENT_REF) 1847 refop = TREE_OPERAND (ref.ref, 1); 1848 if (DECL_P (refop)) 1849 inform (DECL_SOURCE_LOCATION (refop), 1850 "subobject %qD declared here", refop); 1851 warned = true; 1852 } 1853 } 1854 else 1855 { 1856 tree refop = TREE_OPERAND (ref.ref, 0); 1857 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref)); 1858 1859 if (warning_at (loc, OPT_Warray_bounds, 1860 "%G%qD offset %s from the object at %qE is out " 1861 "of the bounds of referenced subobject %qD with " 1862 "type %qT at offset %wi", 1863 call, func, rangestr[0], ref.base, 1864 TREE_OPERAND (ref.ref, 1), type, 1865 ref.refoff.to_shwi ())) 1866 { 1867 if (TREE_CODE (ref.ref) == COMPONENT_REF) 1868 refop = TREE_OPERAND (ref.ref, 1); 1869 if (DECL_P (refop)) 1870 inform (DECL_SOURCE_LOCATION (refop), 1871 "subobject %qD declared here", refop); 1872 warned = true; 1873 } 1874 } 1875 1876 return warned; 1877} 1878 1879/* Check a CALL statement for restrict-violations and issue warnings 1880 if/when appropriate. */ 1881 1882void 1883wrestrict_dom_walker::check_call (gimple *call) 1884{ 1885 /* Avoid checking the call if it has already been diagnosed for 1886 some reason. */ 1887 if (gimple_no_warning_p (call)) 1888 return; 1889 1890 tree func = gimple_call_fndecl (call); 1891 if (!func || !fndecl_built_in_p (func, BUILT_IN_NORMAL)) 1892 return; 1893 1894 /* Argument number to extract from the call (depends on the built-in 1895 and its kind). */ 1896 unsigned dst_idx = -1; 1897 unsigned src_idx = -1; 1898 unsigned bnd_idx = -1; 1899 1900 /* Is this CALL to a string function (as opposed to one to a raw 1901 memory function). */ 1902 bool strfun = true; 1903 1904 switch (DECL_FUNCTION_CODE (func)) 1905 { 1906 case BUILT_IN_MEMCPY: 1907 case BUILT_IN_MEMCPY_CHK: 1908 case BUILT_IN_MEMPCPY: 1909 case BUILT_IN_MEMPCPY_CHK: 1910 case BUILT_IN_MEMMOVE: 1911 case BUILT_IN_MEMMOVE_CHK: 1912 strfun = false; 1913 /* Fall through. */ 1914 1915 case BUILT_IN_STPNCPY: 1916 case BUILT_IN_STPNCPY_CHK: 1917 case BUILT_IN_STRNCAT: 1918 case BUILT_IN_STRNCAT_CHK: 1919 case BUILT_IN_STRNCPY: 1920 case BUILT_IN_STRNCPY_CHK: 1921 dst_idx = 0; 1922 src_idx = 1; 1923 bnd_idx = 2; 1924 break; 1925 1926 case BUILT_IN_MEMSET: 1927 case BUILT_IN_MEMSET_CHK: 1928 dst_idx = 0; 1929 bnd_idx = 2; 1930 break; 1931 1932 case BUILT_IN_STPCPY: 1933 case BUILT_IN_STPCPY_CHK: 1934 case BUILT_IN_STRCPY: 1935 case BUILT_IN_STRCPY_CHK: 1936 case BUILT_IN_STRCAT: 1937 case BUILT_IN_STRCAT_CHK: 1938 dst_idx = 0; 1939 src_idx = 1; 1940 break; 1941 1942 default: 1943 /* Handle other string functions here whose access may need 1944 to be validated for in-bounds offsets and non-overlapping 1945 copies. */ 1946 return; 1947 } 1948 1949 unsigned nargs = gimple_call_num_args (call); 1950 1951 tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE; 1952 tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE; 1953 tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE; 1954 1955 /* For string functions with an unspecified or unknown bound, 1956 assume the size of the access is one. */ 1957 if (!dstwr && strfun) 1958 dstwr = size_one_node; 1959 1960 /* DST and SRC can be null for a call with an insufficient number 1961 of arguments to a built-in function declared without a protype. */ 1962 if (!dst || (src_idx < nargs && !src)) 1963 return; 1964 1965 /* DST, SRC, or DSTWR can also have the wrong type in a call to 1966 a function declared without a prototype. Avoid checking such 1967 invalid calls. */ 1968 if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE 1969 || (src && TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE) 1970 || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr)))) 1971 return; 1972 1973 if (!check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE)) 1974 return; 1975 1976 /* Avoid diagnosing the call again. */ 1977 gimple_set_no_warning (call, true); 1978} 1979 1980} /* anonymous namespace */ 1981 1982/* Attempt to detect and diagnose invalid offset bounds and (except for 1983 memmove) overlapping copy in a call expression EXPR from SRC to DST 1984 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and 1985 SRCSIZE may be NULL. DO_WARN is false to detect either problem 1986 without issue a warning. Return the OPT_Wxxx constant corresponding 1987 to the warning if one has been detected and zero otherwise. */ 1988 1989int 1990check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize, 1991 tree srcsize, bool bounds_only /* = false */, 1992 bool do_warn /* = true */) 1993{ 1994 tree func = gimple_call_fndecl (call); 1995 1996 builtin_memref dstref (dst, dstsize); 1997 builtin_memref srcref (src, srcsize); 1998 1999 /* Create a descriptor of the access. This may adjust both DSTREF 2000 and SRCREF based on one another and the kind of the access. */ 2001 builtin_access acs (call, dstref, srcref); 2002 2003 /* Set STRICT to the value of the -Warray-bounds=N argument for 2004 string functions or when N > 1. */ 2005 int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0); 2006 2007 /* The starting offset of the destination write access. Nonzero only 2008 for the strcat family of functions. */ 2009 offset_int wroff = acs.write_off (dstsize); 2010 2011 /* Validate offsets to each reference before the access first to make 2012 sure they are within the bounds of the destination object if its 2013 size is known, or PTRDIFF_MAX otherwise. */ 2014 if (maybe_diag_access_bounds (call, func, strict, dstref, wroff, do_warn) 2015 || maybe_diag_access_bounds (call, func, strict, srcref, 0, do_warn)) 2016 { 2017 if (do_warn) 2018 gimple_set_no_warning (call, true); 2019 return OPT_Warray_bounds; 2020 } 2021 2022 if (!warn_restrict || bounds_only || !src) 2023 return 0; 2024 2025 if (!bounds_only) 2026 { 2027 switch (DECL_FUNCTION_CODE (func)) 2028 { 2029 case BUILT_IN_MEMMOVE: 2030 case BUILT_IN_MEMMOVE_CHK: 2031 case BUILT_IN_MEMSET: 2032 case BUILT_IN_MEMSET_CHK: 2033 return 0; 2034 default: 2035 break; 2036 } 2037 } 2038 2039 location_t loc = gimple_or_expr_nonartificial_location (call, dst); 2040 if (operand_equal_p (dst, src, 0)) 2041 { 2042 /* Issue -Wrestrict unless the pointers are null (those do 2043 not point to objects and so do not indicate an overlap; 2044 such calls could be the result of sanitization and jump 2045 threading). */ 2046 if (!integer_zerop (dst) && !gimple_no_warning_p (call)) 2047 { 2048 warning_at (loc, OPT_Wrestrict, 2049 "%G%qD source argument is the same as destination", 2050 call, func); 2051 gimple_set_no_warning (call, true); 2052 return OPT_Wrestrict; 2053 } 2054 2055 return 0; 2056 } 2057 2058 /* Return false when overlap has been detected. */ 2059 if (maybe_diag_overlap (loc, call, acs)) 2060 { 2061 gimple_set_no_warning (call, true); 2062 return OPT_Wrestrict; 2063 } 2064 2065 return 0; 2066} 2067 2068gimple_opt_pass * 2069make_pass_warn_restrict (gcc::context *ctxt) 2070{ 2071 return new pass_wrestrict (ctxt); 2072} 2073 2074DEBUG_FUNCTION void 2075dump_builtin_memref (FILE *fp, const builtin_memref &ref) 2076{ 2077 fprintf (fp, "\n ptr = "); 2078 print_generic_expr (fp, ref.ptr, TDF_LINENO); 2079 fprintf (fp, "\n ref = "); 2080 if (ref.ref) 2081 print_generic_expr (fp, ref.ref, TDF_LINENO); 2082 else 2083 fputs ("null", fp); 2084 fprintf (fp, "\n base = "); 2085 print_generic_expr (fp, ref.base, TDF_LINENO); 2086 fprintf (fp, 2087 "\n basesize = %lli" 2088 "\n refsize = %lli" 2089 "\n refoff = %lli" 2090 "\n offrange = [%lli, %lli]" 2091 "\n sizrange = [%lli, %lli]" 2092 "\n strbounded_p = %s\n", 2093 (long long)ref.basesize.to_shwi (), 2094 (long long)ref.refsize.to_shwi (), 2095 (long long)ref.refoff.to_shwi (), 2096 (long long)ref.offrange[0].to_shwi (), 2097 (long long)ref.offrange[1].to_shwi (), 2098 (long long)ref.sizrange[0].to_shwi (), 2099 (long long)ref.sizrange[1].to_shwi (), 2100 ref.strbounded_p ? "true" : "false"); 2101} 2102 2103void 2104builtin_access::dump (FILE *fp) const 2105{ 2106 fprintf (fp, " dstref:"); 2107 dump_builtin_memref (fp, *dstref); 2108 fprintf (fp, "\n srcref:"); 2109 dump_builtin_memref (fp, *srcref); 2110 2111 fprintf (fp, 2112 " sizrange = [%lli, %lli]\n" 2113 " ovloff = [%lli, %lli]\n" 2114 " ovlsiz = [%lli, %lli]\n" 2115 " dstoff = [%lli, %lli]\n" 2116 " dstsiz = [%lli, %lli]\n" 2117 " srcoff = [%lli, %lli]\n" 2118 " srcsiz = [%lli, %lli]\n", 2119 (long long)sizrange[0], (long long)sizrange[1], 2120 (long long)ovloff[0], (long long)ovloff[1], 2121 (long long)ovlsiz[0], (long long)ovlsiz[1], 2122 (long long)dstoff[0].to_shwi (), (long long)dstoff[1].to_shwi (), 2123 (long long)dstsiz[0].to_shwi (), (long long)dstsiz[1].to_shwi (), 2124 (long long)srcoff[0].to_shwi (), (long long)srcoff[1].to_shwi (), 2125 (long long)srcsiz[0].to_shwi (), (long long)srcsiz[1].to_shwi ()); 2126} 2127 2128DEBUG_FUNCTION void 2129dump_builtin_access (FILE *fp, gimple *stmt, const builtin_access &acs) 2130{ 2131 if (stmt) 2132 { 2133 fprintf (fp, "\nDumping builtin_access for "); 2134 print_gimple_expr (fp, stmt, TDF_LINENO); 2135 fputs (":\n", fp); 2136 } 2137 2138 acs.dump (fp); 2139} 2140 2141DEBUG_FUNCTION void 2142debug (gimple *stmt, const builtin_access &acs) 2143{ 2144 dump_builtin_access (stdout, stmt, acs); 2145} 2146