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