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