1 /* Pass to detect and issue warnings for invalid accesses, including
2    invalid or mismatched allocation/deallocation calls.
3 
4    Copyright (C) 2020-2022 Free Software Foundation, Inc.
5    Contributed by Martin Sebor <msebor@redhat.com>.
6 
7    This file is part of GCC.
8 
9    GCC is free software; you can redistribute it and/or modify it under
10    the terms of the GNU General Public License as published by the Free
11    Software Foundation; either version 3, or (at your option) any later
12    version.
13 
14    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15    WARRANTY; without even the implied warranty of MERCHANTABILITY or
16    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17    for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with GCC; see the file COPYING3.  If not see
21    <http://www.gnu.org/licenses/>.  */
22 
23 #define INCLUDE_STRING
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "backend.h"
28 #include "tree.h"
29 #include "gimple.h"
30 #include "tree-pass.h"
31 #include "builtins.h"
32 #include "diagnostic.h"
33 #include "ssa.h"
34 #include "gimple-pretty-print.h"
35 #include "gimple-ssa-warn-access.h"
36 #include "gimple-ssa-warn-restrict.h"
37 #include "diagnostic-core.h"
38 #include "fold-const.h"
39 #include "gimple-fold.h"
40 #include "gimple-iterator.h"
41 #include "langhooks.h"
42 #include "memmodel.h"
43 #include "target.h"
44 #include "tree-dfa.h"
45 #include "tree-ssa.h"
46 #include "tree-cfg.h"
47 #include "tree-object-size.h"
48 #include "tree-ssa-strlen.h"
49 #include "calls.h"
50 #include "cfganal.h"
51 #include "intl.h"
52 #include "gimple-range.h"
53 #include "stringpool.h"
54 #include "attribs.h"
55 #include "demangle.h"
56 #include "attr-fnspec.h"
57 #include "pointer-query.h"
58 
59 /* Return true if tree node X has an associated location.  */
60 
61 static inline location_t
has_location(const_tree x)62 has_location (const_tree x)
63 {
64   if (DECL_P (x))
65     return DECL_SOURCE_LOCATION (x) != UNKNOWN_LOCATION;
66 
67   if (EXPR_P (x))
68     return EXPR_HAS_LOCATION (x);
69 
70   return false;
71 }
72 
73 /* Return the associated location of STMT.  */
74 
75 static inline location_t
get_location(const gimple * stmt)76 get_location (const gimple *stmt)
77 {
78   return gimple_location (stmt);
79 }
80 
81 /* Return the associated location of tree node X.  */
82 
83 static inline location_t
get_location(tree x)84 get_location (tree x)
85 {
86   if (DECL_P (x))
87     return DECL_SOURCE_LOCATION (x);
88 
89   if (EXPR_P (x))
90     return EXPR_LOCATION (x);
91 
92   return UNKNOWN_LOCATION;
93 }
94 
95 /* Overload of the nascent tree function for GIMPLE STMT.  */
96 
97 static inline tree
get_callee_fndecl(const gimple * stmt)98 get_callee_fndecl (const gimple *stmt)
99 {
100   return gimple_call_fndecl (stmt);
101 }
102 
103 static inline unsigned
call_nargs(const gimple * stmt)104 call_nargs (const gimple *stmt)
105 {
106   return gimple_call_num_args (stmt);
107 }
108 
109 static inline unsigned
call_nargs(const_tree expr)110 call_nargs (const_tree expr)
111 {
112   return call_expr_nargs (expr);
113 }
114 
115 
116 static inline tree
call_arg(const gimple * stmt,unsigned argno)117 call_arg (const gimple *stmt, unsigned argno)
118 {
119   return gimple_call_arg (stmt, argno);
120 }
121 
122 static inline tree
call_arg(tree expr,unsigned argno)123 call_arg (tree expr, unsigned argno)
124 {
125   return CALL_EXPR_ARG (expr, argno);
126 }
127 
128 /* For a call EXPR at LOC to a function FNAME that expects a string
129    in the argument ARG, issue a diagnostic due to it being a called
130    with an argument that is a character array with no terminating
131    NUL.  SIZE is the EXACT size of the array, and BNDRNG the number
132    of characters in which the NUL is expected.  Either EXPR or FNAME
133    may be null but noth both.  SIZE may be null when BNDRNG is null.  */
134 
135 template <class GimpleOrTree>
136 static void
warn_string_no_nul(location_t loc,GimpleOrTree expr,const char * fname,tree arg,tree decl,tree size,bool exact,const wide_int bndrng[2])137 warn_string_no_nul (location_t loc, GimpleOrTree expr, const char *fname,
138                         tree arg, tree decl, tree size, bool exact,
139                         const wide_int bndrng[2] /* = NULL */)
140 {
141   const opt_code opt = OPT_Wstringop_overread;
142   if ((expr && warning_suppressed_p (expr, opt))
143       || warning_suppressed_p (arg, opt))
144     return;
145 
146   loc = expansion_point_location_if_in_system_header (loc);
147   bool warned;
148 
149   /* Format the bound range as a string to keep the number of messages
150      from exploding.  */
151   char bndstr[80];
152   *bndstr = 0;
153   if (bndrng)
154     {
155       if (bndrng[0] == bndrng[1])
156           sprintf (bndstr, "%llu", (unsigned long long) bndrng[0].to_uhwi ());
157       else
158           sprintf (bndstr, "[%llu, %llu]",
159                      (unsigned long long) bndrng[0].to_uhwi (),
160                      (unsigned long long) bndrng[1].to_uhwi ());
161     }
162 
163   const tree maxobjsize = max_object_size ();
164   const wide_int maxsiz = wi::to_wide (maxobjsize);
165   if (expr)
166     {
167       tree func = get_callee_fndecl (expr);
168       if (bndrng)
169           {
170             if (wi::ltu_p (maxsiz, bndrng[0]))
171               warned = warning_at (loc, opt,
172                                          "%qD specified bound %s exceeds "
173                                          "maximum object size %E",
174                                          func, bndstr, maxobjsize);
175             else
176               {
177                 bool maybe = wi::to_wide (size) == bndrng[0];
178                 warned = warning_at (loc, opt,
179                                            exact
180                                            ? G_("%qD specified bound %s exceeds "
181                                                   "the size %E of unterminated array")
182                                            : (maybe
183                                               ? G_("%qD specified bound %s may "
184                                                      "exceed the size of at most %E "
185                                                      "of unterminated array")
186                                               : G_("%qD specified bound %s exceeds "
187                                                      "the size of at most %E "
188                                                      "of unterminated array")),
189                                            func, bndstr, size);
190               }
191           }
192       else
193           warned = warning_at (loc, opt,
194                                    "%qD argument missing terminating nul",
195                                    func);
196     }
197   else
198     {
199       if (bndrng)
200           {
201             if (wi::ltu_p (maxsiz, bndrng[0]))
202               warned = warning_at (loc, opt,
203                                          "%qs specified bound %s exceeds "
204                                          "maximum object size %E",
205                                          fname, bndstr, maxobjsize);
206             else
207               {
208                 bool maybe = wi::to_wide (size) == bndrng[0];
209                 warned = warning_at (loc, opt,
210                                            exact
211                                            ? G_("%qs specified bound %s exceeds "
212                                                   "the size %E of unterminated array")
213                                            : (maybe
214                                               ? G_("%qs specified bound %s may "
215                                                      "exceed the size of at most %E "
216                                                      "of unterminated array")
217                                               : G_("%qs specified bound %s exceeds "
218                                                      "the size of at most %E "
219                                                      "of unterminated array")),
220                                            fname, bndstr, size);
221               }
222           }
223       else
224           warned = warning_at (loc, opt,
225                                    "%qs argument missing terminating nul",
226                                    fname);
227     }
228 
229   if (warned)
230     {
231       inform (get_location (decl),
232                 "referenced argument declared here");
233       suppress_warning (arg, opt);
234       if (expr)
235           suppress_warning (expr, opt);
236     }
237 }
238 
239 void
warn_string_no_nul(location_t loc,gimple * stmt,const char * fname,tree arg,tree decl,tree size,bool exact,const wide_int bndrng[2])240 warn_string_no_nul (location_t loc, gimple *stmt, const char *fname,
241                         tree arg, tree decl, tree size /* = NULL_TREE */,
242                         bool exact /* = false */,
243                         const wide_int bndrng[2] /* = NULL */)
244 {
245   return warn_string_no_nul<gimple *> (loc, stmt, fname,
246                                                arg, decl, size, exact, bndrng);
247 }
248 
249 void
warn_string_no_nul(location_t loc,tree expr,const char * fname,tree arg,tree decl,tree size,bool exact,const wide_int bndrng[2])250 warn_string_no_nul (location_t loc, tree expr, const char *fname,
251                         tree arg, tree decl, tree size /* = NULL_TREE */,
252                         bool exact /* = false */,
253                         const wide_int bndrng[2] /* = NULL */)
254 {
255   return warn_string_no_nul<tree> (loc, expr, fname,
256                                            arg, decl, size, exact, bndrng);
257 }
258 
259 /* If EXP refers to an unterminated constant character array return
260    the declaration of the object of which the array is a member or
261    element and if SIZE is not null, set *SIZE to the size of
262    the unterminated array and set *EXACT if the size is exact or
263    clear it otherwise.  Otherwise return null.  */
264 
265 tree
unterminated_array(tree exp,tree * size,bool * exact)266 unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */)
267 {
268   /* C_STRLEN will return NULL and set DECL in the info
269      structure if EXP references a unterminated array.  */
270   c_strlen_data lendata = { };
271   tree len = c_strlen (exp, 1, &lendata);
272   if (len || !lendata.minlen || !lendata.decl)
273     return NULL_TREE;
274 
275   if (!size)
276     return lendata.decl;
277 
278   len = lendata.minlen;
279   if (lendata.off)
280     {
281       /* Constant offsets are already accounted for in LENDATA.MINLEN,
282            but not in a SSA_NAME + CST expression.  */
283       if (TREE_CODE (lendata.off) == INTEGER_CST)
284           *exact = true;
285       else if (TREE_CODE (lendata.off) == PLUS_EXPR
286                  && TREE_CODE (TREE_OPERAND (lendata.off, 1)) == INTEGER_CST)
287           {
288             /* Subtract the offset from the size of the array.  */
289             *exact = false;
290             tree temp = TREE_OPERAND (lendata.off, 1);
291             temp = fold_convert (ssizetype, temp);
292             len = fold_build2 (MINUS_EXPR, ssizetype, len, temp);
293           }
294       else
295           *exact = false;
296     }
297   else
298     *exact = true;
299 
300   *size = len;
301   return lendata.decl;
302 }
303 
304 /* For a call EXPR (which may be null) that expects a string argument
305    SRC as an argument, returns false if SRC is a character array with
306    no terminating NUL.  When nonnull, BOUND is the number of characters
307    in which to expect the terminating NUL.  When EXPR is nonnull also
308    issues a warning.  */
309 
310 template <class GimpleOrTree>
311 static bool
check_nul_terminated_array(GimpleOrTree expr,tree src,tree bound)312 check_nul_terminated_array (GimpleOrTree expr, tree src, tree bound)
313 {
314   /* The constant size of the array SRC points to.  The actual size
315      may be less of EXACT is true, but not more.  */
316   tree size;
317   /* True if SRC involves a non-constant offset into the array.  */
318   bool exact;
319   /* The unterminated constant array SRC points to.  */
320   tree nonstr = unterminated_array (src, &size, &exact);
321   if (!nonstr)
322     return true;
323 
324   /* NONSTR refers to the non-nul terminated constant array and SIZE
325      is the constant size of the array in bytes.  EXACT is true when
326      SIZE is exact.  */
327 
328   wide_int bndrng[2];
329   if (bound)
330     {
331       value_range r;
332 
333       get_global_range_query ()->range_of_expr (r, bound);
334 
335       if (r.kind () != VR_RANGE)
336           return true;
337 
338       bndrng[0] = r.lower_bound ();
339       bndrng[1] = r.upper_bound ();
340 
341       if (exact)
342           {
343             if (wi::leu_p (bndrng[0], wi::to_wide (size)))
344               return true;
345           }
346       else if (wi::lt_p (bndrng[0], wi::to_wide (size), UNSIGNED))
347           return true;
348     }
349 
350   if (expr)
351     warn_string_no_nul (get_location (expr), expr, NULL, src, nonstr,
352                               size, exact, bound ? bndrng : NULL);
353 
354   return false;
355 }
356 
357 bool
check_nul_terminated_array(gimple * stmt,tree src,tree bound)358 check_nul_terminated_array (gimple *stmt, tree src, tree bound /* = NULL_TREE */)
359 {
360   return check_nul_terminated_array<gimple *>(stmt, src, bound);
361 }
362 
363 bool
check_nul_terminated_array(tree expr,tree src,tree bound)364 check_nul_terminated_array (tree expr, tree src, tree bound /* = NULL_TREE */)
365 {
366   return check_nul_terminated_array<tree>(expr, src, bound);
367 }
368 
369 /* Warn about passing a non-string array/pointer to a built-in function
370    that expects a nul-terminated string argument.  Returns true if
371    a warning has been issued.*/
372 
373 template <class GimpleOrTree>
374 static bool
maybe_warn_nonstring_arg(tree fndecl,GimpleOrTree exp)375 maybe_warn_nonstring_arg (tree fndecl, GimpleOrTree exp)
376 {
377   if (!fndecl || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
378     return false;
379 
380   if (!warn_stringop_overread
381       || warning_suppressed_p (exp, OPT_Wstringop_overread))
382     return false;
383 
384   /* Avoid clearly invalid calls (more checking done below).  */
385   unsigned nargs = call_nargs (exp);
386   if (!nargs)
387     return false;
388 
389   /* The bound argument to a bounded string function like strncpy.  */
390   tree bound = NULL_TREE;
391 
392   /* The longest known or possible string argument to one of the comparison
393      functions.  If the length is less than the bound it is used instead.
394      Since the length is only used for warning and not for code generation
395      disable strict mode in the calls to get_range_strlen below.  */
396   tree maxlen = NULL_TREE;
397 
398   /* It's safe to call "bounded" string functions with a non-string
399      argument since the functions provide an explicit bound for this
400      purpose.  The exception is strncat where the bound may refer to
401      either the destination or the source.  */
402   int fncode = DECL_FUNCTION_CODE (fndecl);
403   switch (fncode)
404     {
405     case BUILT_IN_STRCMP:
406     case BUILT_IN_STRNCMP:
407     case BUILT_IN_STRNCASECMP:
408       {
409           /* For these, if one argument refers to one or more of a set
410              of string constants or arrays of known size, determine
411              the range of their known or possible lengths and use it
412              conservatively as the bound for the unbounded function,
413              and to adjust the range of the bound of the bounded ones.  */
414           for (unsigned argno = 0;
415                argno < MIN (nargs, 2)
416                  && !(maxlen && TREE_CODE (maxlen) == INTEGER_CST); argno++)
417             {
418               tree arg = call_arg (exp, argno);
419               if (!get_attr_nonstring_decl (arg))
420                 {
421                     c_strlen_data lendata = { };
422                     /* Set MAXBOUND to an arbitrary non-null non-integer
423                        node as a request to have it set to the length of
424                        the longest string in a PHI.  */
425                     lendata.maxbound = arg;
426                     get_range_strlen (arg, &lendata, /* eltsize = */ 1);
427                     maxlen = lendata.maxbound;
428                 }
429             }
430       }
431       /* Fall through.  */
432 
433     case BUILT_IN_STRNCAT:
434     case BUILT_IN_STPNCPY:
435     case BUILT_IN_STRNCPY:
436       if (nargs > 2)
437           bound = call_arg (exp, 2);
438       break;
439 
440     case BUILT_IN_STRNDUP:
441       if (nargs < 2)
442           return false;
443       bound = call_arg (exp, 1);
444       break;
445 
446     case BUILT_IN_STRNLEN:
447       {
448           tree arg = call_arg (exp, 0);
449           if (!get_attr_nonstring_decl (arg))
450             {
451               c_strlen_data lendata = { };
452               /* Set MAXBOUND to an arbitrary non-null non-integer
453                  node as a request to have it set to the length of
454                  the longest string in a PHI.  */
455               lendata.maxbound = arg;
456               get_range_strlen (arg, &lendata, /* eltsize = */ 1);
457               maxlen = lendata.maxbound;
458             }
459           if (nargs > 1)
460             bound = call_arg (exp, 1);
461           break;
462       }
463 
464     default:
465       break;
466     }
467 
468   /* Determine the range of the bound argument (if specified).  */
469   tree bndrng[2] = { NULL_TREE, NULL_TREE };
470   if (bound)
471     {
472       STRIP_NOPS (bound);
473       get_size_range (bound, bndrng);
474     }
475 
476   location_t loc = get_location (exp);
477 
478   if (bndrng[0])
479     {
480       /* Diagnose excessive bound prior to the adjustment below and
481            regardless of attribute nonstring.  */
482       tree maxobjsize = max_object_size ();
483       if (tree_int_cst_lt (maxobjsize, bndrng[0]))
484           {
485             bool warned = false;
486             if (tree_int_cst_equal (bndrng[0], bndrng[1]))
487               warned = warning_at (loc, OPT_Wstringop_overread,
488                                          "%qD specified bound %E "
489                                          "exceeds maximum object size %E",
490                                          fndecl, bndrng[0], maxobjsize);
491             else
492               warned = warning_at (loc, OPT_Wstringop_overread,
493                                          "%qD specified bound [%E, %E] "
494                                          "exceeds maximum object size %E",
495                                          fndecl, bndrng[0], bndrng[1],
496                                          maxobjsize);
497             if (warned)
498               suppress_warning (exp, OPT_Wstringop_overread);
499 
500             return warned;
501           }
502     }
503 
504   if (maxlen && !integer_all_onesp (maxlen))
505     {
506       /* Add one for the nul.  */
507       maxlen = const_binop (PLUS_EXPR, TREE_TYPE (maxlen), maxlen,
508                                   size_one_node);
509 
510       if (!bndrng[0])
511           {
512             /* Conservatively use the upper bound of the lengths for
513                both the lower and the upper bound of the operation.  */
514             bndrng[0] = maxlen;
515             bndrng[1] = maxlen;
516             bound = void_type_node;
517           }
518       else if (maxlen)
519           {
520             /* Replace the bound on the operation with the upper bound
521                of the length of the string if the latter is smaller.  */
522             if (tree_int_cst_lt (maxlen, bndrng[0]))
523               bndrng[0] = maxlen;
524             else if (tree_int_cst_lt (maxlen, bndrng[1]))
525               bndrng[1] = maxlen;
526           }
527     }
528 
529   bool any_arg_warned = false;
530   /* Iterate over the built-in function's formal arguments and check
531      each const char* against the actual argument.  If the actual
532      argument is declared attribute non-string issue a warning unless
533      the argument's maximum length is bounded.  */
534   function_args_iterator it;
535   function_args_iter_init (&it, TREE_TYPE (fndecl));
536 
537   for (unsigned argno = 0; ; ++argno, function_args_iter_next (&it))
538     {
539       /* Avoid iterating past the declared argument in a call
540            to function declared without a prototype.  */
541       if (argno >= nargs)
542           break;
543 
544       tree argtype = function_args_iter_cond (&it);
545       if (!argtype)
546           break;
547 
548       if (TREE_CODE (argtype) != POINTER_TYPE)
549           continue;
550 
551       argtype = TREE_TYPE (argtype);
552 
553       if (TREE_CODE (argtype) != INTEGER_TYPE
554             || !TYPE_READONLY (argtype))
555           continue;
556 
557       argtype = TYPE_MAIN_VARIANT (argtype);
558       if (argtype != char_type_node)
559           continue;
560 
561       tree callarg = call_arg (exp, argno);
562       if (TREE_CODE (callarg) == ADDR_EXPR)
563           callarg = TREE_OPERAND (callarg, 0);
564 
565       /* See if the destination is declared with attribute "nonstring".  */
566       tree decl = get_attr_nonstring_decl (callarg);
567       if (!decl)
568           continue;
569 
570       /* The maximum number of array elements accessed.  */
571       offset_int wibnd = 0;
572 
573       if (argno && fncode == BUILT_IN_STRNCAT)
574           {
575             /* See if the bound in strncat is derived from the length
576                of the strlen of the destination (as it's expected to be).
577                If so, reset BOUND and FNCODE to trigger a warning.  */
578             tree dstarg = call_arg (exp, 0);
579             if (is_strlen_related_p (dstarg, bound))
580               {
581                 /* The bound applies to the destination, not to the source,
582                      so reset these to trigger a warning without mentioning
583                      the bound.  */
584                 bound = NULL;
585                 fncode = 0;
586               }
587             else if (bndrng[1])
588               /* Use the upper bound of the range for strncat.  */
589               wibnd = wi::to_offset (bndrng[1]);
590           }
591       else if (bndrng[0])
592           /* Use the lower bound of the range for functions other than
593              strncat.  */
594           wibnd = wi::to_offset (bndrng[0]);
595 
596       /* Determine the size of the argument array if it is one.  */
597       offset_int asize = wibnd;
598       bool known_size = false;
599       tree type = TREE_TYPE (decl);
600 
601       /* Determine the array size.  For arrays of unknown bound and
602            pointers reset BOUND to trigger the appropriate warning.  */
603       if (TREE_CODE (type) == ARRAY_TYPE)
604           {
605             if (tree arrbnd = TYPE_DOMAIN (type))
606               {
607                 if ((arrbnd = TYPE_MAX_VALUE (arrbnd)))
608                     {
609                       asize = wi::to_offset (arrbnd) + 1;
610                       known_size = true;
611                     }
612               }
613             else if (bound == void_type_node)
614               bound = NULL_TREE;
615           }
616       else if (bound == void_type_node)
617           bound = NULL_TREE;
618 
619       /* In a call to strncat with a bound in a range whose lower but
620            not upper bound is less than the array size, reset ASIZE to
621            be the same as the bound and the other variable to trigger
622            the appropriate warning below.  */
623       if (fncode == BUILT_IN_STRNCAT
624             && bndrng[0] != bndrng[1]
625             && wi::ltu_p (wi::to_offset (bndrng[0]), asize)
626             && (!known_size
627                 || wi::ltu_p (asize, wibnd)))
628           {
629             asize = wibnd;
630             bound = NULL_TREE;
631             fncode = 0;
632           }
633 
634       bool warned = false;
635 
636       auto_diagnostic_group d;
637       if (wi::ltu_p (asize, wibnd))
638           {
639             if (bndrng[0] == bndrng[1])
640               warned = warning_at (loc, OPT_Wstringop_overread,
641                                          "%qD argument %i declared attribute "
642                                          "%<nonstring%> is smaller than the specified "
643                                          "bound %wu",
644                                          fndecl, argno + 1, wibnd.to_uhwi ());
645             else if (wi::ltu_p (asize, wi::to_offset (bndrng[0])))
646               warned = warning_at (loc, OPT_Wstringop_overread,
647                                          "%qD argument %i declared attribute "
648                                          "%<nonstring%> is smaller than "
649                                          "the specified bound [%E, %E]",
650                                          fndecl, argno + 1, bndrng[0], bndrng[1]);
651             else
652               warned = warning_at (loc, OPT_Wstringop_overread,
653                                          "%qD argument %i declared attribute "
654                                          "%<nonstring%> may be smaller than "
655                                          "the specified bound [%E, %E]",
656                                          fndecl, argno + 1, bndrng[0], bndrng[1]);
657           }
658       else if (fncode == BUILT_IN_STRNCAT)
659           ; /* Avoid warning for calls to strncat() when the bound
660                is equal to the size of the non-string argument.  */
661       else if (!bound)
662           warned = warning_at (loc, OPT_Wstringop_overread,
663                                    "%qD argument %i declared attribute %<nonstring%>",
664                                    fndecl, argno + 1);
665 
666       if (warned)
667           {
668             inform (DECL_SOURCE_LOCATION (decl),
669                       "argument %qD declared here", decl);
670             any_arg_warned = true;
671           }
672     }
673 
674   if (any_arg_warned)
675     suppress_warning (exp, OPT_Wstringop_overread);
676 
677   return any_arg_warned;
678 }
679 
680 bool
maybe_warn_nonstring_arg(tree fndecl,gimple * stmt)681 maybe_warn_nonstring_arg (tree fndecl, gimple *stmt)
682 {
683   return maybe_warn_nonstring_arg<gimple *>(fndecl, stmt);
684 }
685 
686 
687 bool
maybe_warn_nonstring_arg(tree fndecl,tree expr)688 maybe_warn_nonstring_arg (tree fndecl, tree expr)
689 {
690   return maybe_warn_nonstring_arg<tree>(fndecl, expr);
691 }
692 
693 /* Issue a warning OPT for a bounded call EXP with a bound in RANGE
694    accessing an object with SIZE.  */
695 
696 template <class GimpleOrTree>
697 static bool
maybe_warn_for_bound(opt_code opt,location_t loc,GimpleOrTree exp,tree func,tree bndrng[2],tree size,const access_data * pad)698 maybe_warn_for_bound (opt_code opt, location_t loc, GimpleOrTree exp, tree func,
699                           tree bndrng[2], tree size, const access_data *pad)
700 {
701   if (!bndrng[0] || warning_suppressed_p (exp, opt))
702     return false;
703 
704   tree maxobjsize = max_object_size ();
705 
706   bool warned = false;
707 
708   if (opt == OPT_Wstringop_overread)
709     {
710       bool maybe = pad && pad->src.phi ();
711       if (maybe)
712           {
713             /* Issue a "maybe" warning only if the PHI refers to objects
714                at least one of which has more space remaining than the bound.
715                Otherwise, if the bound is greater, use the definitive form.  */
716             offset_int remmax = pad->src.size_remaining ();
717             if (remmax < wi::to_offset (bndrng[0]))
718               maybe = false;
719           }
720 
721       if (tree_int_cst_lt (maxobjsize, bndrng[0]))
722           {
723             if (bndrng[0] == bndrng[1])
724               warned = (func
725                           ? warning_at (loc, opt,
726                                             (maybe
727                                              ? G_("%qD specified bound %E may "
728                                                     "exceed maximum object size %E")
729                                              : G_("%qD specified bound %E "
730                                                     "exceeds maximum object size %E")),
731                                             func, bndrng[0], maxobjsize)
732                           : warning_at (loc, opt,
733                                             (maybe
734                                              ? G_("specified bound %E may "
735                                                     "exceed maximum object size %E")
736                                              : G_("specified bound %E "
737                                                     "exceeds maximum object size %E")),
738                                             bndrng[0], maxobjsize));
739             else
740               warned = (func
741                           ? warning_at (loc, opt,
742                                             (maybe
743                                              ? G_("%qD specified bound [%E, %E] may "
744                                                     "exceed maximum object size %E")
745                                              : G_("%qD specified bound [%E, %E] "
746                                                     "exceeds maximum object size %E")),
747                                             func,
748                                             bndrng[0], bndrng[1], maxobjsize)
749                           : warning_at (loc, opt,
750                                             (maybe
751                                              ? G_("specified bound [%E, %E] may "
752                                                     "exceed maximum object size %E")
753                                              : G_("specified bound [%E, %E] "
754                                                     "exceeds maximum object size %E")),
755                                             bndrng[0], bndrng[1], maxobjsize));
756           }
757       else if (!size || tree_int_cst_le (bndrng[0], size))
758           return false;
759       else if (tree_int_cst_equal (bndrng[0], bndrng[1]))
760           warned = (func
761                       ? warning_at (loc, opt,
762                                         (maybe
763                                          ? G_("%qD specified bound %E may exceed "
764                                               "source size %E")
765                                          : G_("%qD specified bound %E exceeds "
766                                               "source size %E")),
767                                         func, bndrng[0], size)
768                       : warning_at (loc, opt,
769                                         (maybe
770                                          ? G_("specified bound %E may exceed "
771                                               "source size %E")
772                                          : G_("specified bound %E exceeds "
773                                               "source size %E")),
774                                         bndrng[0], size));
775       else
776           warned = (func
777                       ? warning_at (loc, opt,
778                                         (maybe
779                                          ? G_("%qD specified bound [%E, %E] may "
780                                               "exceed source size %E")
781                                          : G_("%qD specified bound [%E, %E] exceeds "
782                                               "source size %E")),
783                                         func, bndrng[0], bndrng[1], size)
784                       : warning_at (loc, opt,
785                                         (maybe
786                                          ? G_("specified bound [%E, %E] may exceed "
787                                               "source size %E")
788                                          : G_("specified bound [%E, %E] exceeds "
789                                               "source size %E")),
790                                         bndrng[0], bndrng[1], size));
791       if (warned)
792           {
793             if (pad && pad->src.ref
794                 && has_location (pad->src.ref))
795               inform (get_location (pad->src.ref),
796                         "source object allocated here");
797             suppress_warning (exp, opt);
798           }
799 
800       return warned;
801     }
802 
803   bool maybe = pad && pad->dst.phi ();
804   if (maybe)
805     {
806       /* Issue a "maybe" warning only if the PHI refers to objects
807            at least one of which has more space remaining than the bound.
808            Otherwise, if the bound is greater, use the definitive form.  */
809       offset_int remmax = pad->dst.size_remaining ();
810       if (remmax < wi::to_offset (bndrng[0]))
811           maybe = false;
812     }
813   if (tree_int_cst_lt (maxobjsize, bndrng[0]))
814     {
815       if (bndrng[0] == bndrng[1])
816           warned = (func
817                       ? warning_at (loc, opt,
818                                         (maybe
819                                          ? G_("%qD specified size %E may "
820                                               "exceed maximum object size %E")
821                                          : G_("%qD specified size %E "
822                                               "exceeds maximum object size %E")),
823                                         func, bndrng[0], maxobjsize)
824                       : warning_at (loc, opt,
825                                         (maybe
826                                          ? G_("specified size %E may exceed "
827                                               "maximum object size %E")
828                                          : G_("specified size %E exceeds "
829                                               "maximum object size %E")),
830                                         bndrng[0], maxobjsize));
831       else
832           warned = (func
833                       ? warning_at (loc, opt,
834                                         (maybe
835                                          ? G_("%qD specified size between %E and %E "
836                                               "may exceed maximum object size %E")
837                                          : G_("%qD specified size between %E and %E "
838                                               "exceeds maximum object size %E")),
839                                         func, bndrng[0], bndrng[1], maxobjsize)
840                       : warning_at (loc, opt,
841                                         (maybe
842                                          ? G_("specified size between %E and %E "
843                                               "may exceed maximum object size %E")
844                                          : G_("specified size between %E and %E "
845                                               "exceeds maximum object size %E")),
846                                         bndrng[0], bndrng[1], maxobjsize));
847     }
848   else if (!size || tree_int_cst_le (bndrng[0], size))
849     return false;
850   else if (tree_int_cst_equal (bndrng[0], bndrng[1]))
851     warned = (func
852                 ? warning_at (loc, opt,
853                                   (maybe
854                                    ? G_("%qD specified bound %E may exceed "
855                                           "destination size %E")
856                                    : G_("%qD specified bound %E exceeds "
857                                           "destination size %E")),
858                                   func, bndrng[0], size)
859                 : warning_at (loc, opt,
860                                   (maybe
861                                    ? G_("specified bound %E may exceed "
862                                           "destination size %E")
863                                    : G_("specified bound %E exceeds "
864                                           "destination size %E")),
865                                   bndrng[0], size));
866   else
867     warned = (func
868                 ? warning_at (loc, opt,
869                                   (maybe
870                                    ? G_("%qD specified bound [%E, %E] may exceed "
871                                           "destination size %E")
872                                    : G_("%qD specified bound [%E, %E] exceeds "
873                                           "destination size %E")),
874                                   func, bndrng[0], bndrng[1], size)
875                 : warning_at (loc, opt,
876                                   (maybe
877                                    ? G_("specified bound [%E, %E] exceeds "
878                                           "destination size %E")
879                                    : G_("specified bound [%E, %E] exceeds "
880                                           "destination size %E")),
881                                   bndrng[0], bndrng[1], size));
882 
883   if (warned)
884     {
885       if (pad && pad->dst.ref
886             && has_location (pad->dst.ref))
887           inform (get_location (pad->dst.ref),
888                     "destination object allocated here");
889       suppress_warning (exp, opt);
890     }
891 
892   return warned;
893 }
894 
895 bool
maybe_warn_for_bound(opt_code opt,location_t loc,gimple * stmt,tree func,tree bndrng[2],tree size,const access_data * pad)896 maybe_warn_for_bound (opt_code opt, location_t loc, gimple *stmt, tree func,
897                           tree bndrng[2], tree size,
898                           const access_data *pad /* = NULL */)
899 {
900   return maybe_warn_for_bound<gimple *> (opt, loc, stmt, func, bndrng, size,
901                                                    pad);
902 }
903 
904 bool
maybe_warn_for_bound(opt_code opt,location_t loc,tree expr,tree func,tree bndrng[2],tree size,const access_data * pad)905 maybe_warn_for_bound (opt_code opt, location_t loc, tree expr, tree func,
906                           tree bndrng[2], tree size,
907                           const access_data *pad /* = NULL */)
908 {
909   return maybe_warn_for_bound<tree> (opt, loc, expr, func, bndrng, size, pad);
910 }
911 
912 /* For an expression EXP issue an access warning controlled by option OPT
913    with access to a region SIZE bytes in size in the RANGE of sizes.
914    WRITE is true for a write access, READ for a read access, neither for
915    call that may or may not perform an access but for which the range
916    is expected to valid.
917    Returns true when a warning has been issued.  */
918 
919 template <class GimpleOrTree>
920 static bool
warn_for_access(location_t loc,tree func,GimpleOrTree exp,int opt,tree range[2],tree size,bool write,bool read,bool maybe)921 warn_for_access (location_t loc, tree func, GimpleOrTree exp, int opt,
922                      tree range[2], tree size, bool write, bool read, bool maybe)
923 {
924   bool warned = false;
925 
926   if (write && read)
927     {
928       if (tree_int_cst_equal (range[0], range[1]))
929           warned = (func
930                       ? warning_n (loc, opt, tree_to_uhwi (range[0]),
931                                      (maybe
932                                         ? G_("%qD may access %E byte in a region "
933                                              "of size %E")
934                                         : G_("%qD accessing %E byte in a region "
935                                              "of size %E")),
936                                         (maybe
937                                          ? G_ ("%qD may access %E bytes in a region "
938                                                "of size %E")
939                                          : G_ ("%qD accessing %E bytes in a region "
940                                                "of size %E")),
941                                      func, range[0], size)
942                       : warning_n (loc, opt, tree_to_uhwi (range[0]),
943                                      (maybe
944                                         ? G_("may access %E byte in a region "
945                                              "of size %E")
946                                         : G_("accessing %E byte in a region "
947                                              "of size %E")),
948                                      (maybe
949                                         ? G_("may access %E bytes in a region "
950                                              "of size %E")
951                                         : G_("accessing %E bytes in a region "
952                                              "of size %E")),
953                                      range[0], size));
954       else if (tree_int_cst_sign_bit (range[1]))
955           {
956             /* Avoid printing the upper bound if it's invalid.  */
957             warned = (func
958                         ? warning_at (loc, opt,
959                                           (maybe
960                                            ? G_("%qD may access %E or more bytes "
961                                                   "in a region of size %E")
962                                            : G_("%qD accessing %E or more bytes "
963                                                   "in a region of size %E")),
964                                           func, range[0], size)
965                         : warning_at (loc, opt,
966                                           (maybe
967                                            ? G_("may access %E or more bytes "
968                                                   "in a region of size %E")
969                                            : G_("accessing %E or more bytes "
970                                                   "in a region of size %E")),
971                                           range[0], size));
972           }
973       else
974           warned = (func
975                       ? warning_at (loc, opt,
976                                         (maybe
977                                          ? G_("%qD may access between %E and %E "
978                                               "bytes in a region of size %E")
979                                          : G_("%qD accessing between %E and %E "
980                                               "bytes in a region of size %E")),
981                                         func, range[0], range[1], size)
982                       : warning_at (loc, opt,
983                                         (maybe
984                                          ? G_("may access between %E and %E bytes "
985                                               "in a region of size %E")
986                                          : G_("accessing between %E and %E bytes "
987                                               "in a region of size %E")),
988                                         range[0], range[1], size));
989       return warned;
990     }
991 
992   if (write)
993     {
994       if (tree_int_cst_equal (range[0], range[1]))
995           warned = (func
996                       ? warning_n (loc, opt, tree_to_uhwi (range[0]),
997                                      (maybe
998                                         ? G_("%qD may write %E byte into a region "
999                                              "of size %E")
1000                                         : G_("%qD writing %E byte into a region "
1001                                              "of size %E overflows the destination")),
1002                                      (maybe
1003                                         ? G_("%qD may write %E bytes into a region "
1004                                              "of size %E")
1005                                         : G_("%qD writing %E bytes into a region "
1006                                              "of size %E overflows the destination")),
1007                                      func, range[0], size)
1008                       : warning_n (loc, opt, tree_to_uhwi (range[0]),
1009                                      (maybe
1010                                         ? G_("may write %E byte into a region "
1011                                              "of size %E")
1012                                         : G_("writing %E byte into a region "
1013                                              "of size %E overflows the destination")),
1014                                      (maybe
1015                                         ? G_("may write %E bytes into a region "
1016                                              "of size %E")
1017                                         : G_("writing %E bytes into a region "
1018                                              "of size %E overflows the destination")),
1019                                      range[0], size));
1020       else if (tree_int_cst_sign_bit (range[1]))
1021           {
1022             /* Avoid printing the upper bound if it's invalid.  */
1023             warned = (func
1024                         ? warning_at (loc, opt,
1025                                           (maybe
1026                                            ? G_("%qD may write %E or more bytes "
1027                                                   "into a region of size %E")
1028                                            : G_("%qD writing %E or more bytes "
1029                                                   "into a region of size %E overflows "
1030                                                   "the destination")),
1031                                           func, range[0], size)
1032                         : warning_at (loc, opt,
1033                                           (maybe
1034                                            ? G_("may write %E or more bytes into "
1035                                                   "a region of size %E")
1036                                            : G_("writing %E or more bytes into "
1037                                                   "a region of size %E overflows "
1038                                                   "the destination")),
1039                                           range[0], size));
1040           }
1041       else
1042           warned = (func
1043                       ? warning_at (loc, opt,
1044                                         (maybe
1045                                          ? G_("%qD may write between %E and %E bytes "
1046                                               "into a region of size %E")
1047                                          : G_("%qD writing between %E and %E bytes "
1048                                               "into a region of size %E overflows "
1049                                               "the destination")),
1050                                         func, range[0], range[1], size)
1051                       : warning_at (loc, opt,
1052                                         (maybe
1053                                          ? G_("may write between %E and %E bytes "
1054                                               "into a region of size %E")
1055                                          : G_("writing between %E and %E bytes "
1056                                               "into a region of size %E overflows "
1057                                               "the destination")),
1058                                         range[0], range[1], size));
1059       return warned;
1060     }
1061 
1062   if (read)
1063     {
1064       if (tree_int_cst_equal (range[0], range[1]))
1065           warned = (func
1066                       ? warning_n (loc, OPT_Wstringop_overread,
1067                                      tree_to_uhwi (range[0]),
1068                                      (maybe
1069                                         ? G_("%qD may read %E byte from a region "
1070                                              "of size %E")
1071                                         : G_("%qD reading %E byte from a region "
1072                                              "of size %E")),
1073                                      (maybe
1074                                         ? G_("%qD may read %E bytes from a region "
1075                                              "of size %E")
1076                                         : G_("%qD reading %E bytes from a region "
1077                                              "of size %E")),
1078                                      func, range[0], size)
1079                       : warning_n (loc, OPT_Wstringop_overread,
1080                                      tree_to_uhwi (range[0]),
1081                                      (maybe
1082                                         ? G_("may read %E byte from a region "
1083                                              "of size %E")
1084                                         : G_("reading %E byte from a region "
1085                                              "of size %E")),
1086                                      (maybe
1087                                         ? G_("may read %E bytes from a region "
1088                                              "of size %E")
1089                                         : G_("reading %E bytes from a region "
1090                                              "of size %E")),
1091                                      range[0], size));
1092       else if (tree_int_cst_sign_bit (range[1]))
1093           {
1094             /* Avoid printing the upper bound if it's invalid.  */
1095             warned = (func
1096                         ? warning_at (loc, OPT_Wstringop_overread,
1097                                           (maybe
1098                                            ? G_("%qD may read %E or more bytes "
1099                                                   "from a region of size %E")
1100                                            : G_("%qD reading %E or more bytes "
1101                                                   "from a region of size %E")),
1102                                           func, range[0], size)
1103                         : warning_at (loc, OPT_Wstringop_overread,
1104                                           (maybe
1105                                            ? G_("may read %E or more bytes "
1106                                                   "from a region of size %E")
1107                                            : G_("reading %E or more bytes "
1108                                                   "from a region of size %E")),
1109                                           range[0], size));
1110           }
1111       else
1112           warned = (func
1113                       ? warning_at (loc, OPT_Wstringop_overread,
1114                                         (maybe
1115                                          ? G_("%qD may read between %E and %E bytes "
1116                                               "from a region of size %E")
1117                                          : G_("%qD reading between %E and %E bytes "
1118                                               "from a region of size %E")),
1119                                         func, range[0], range[1], size)
1120                       : warning_at (loc, opt,
1121                                         (maybe
1122                                          ? G_("may read between %E and %E bytes "
1123                                               "from a region of size %E")
1124                                          : G_("reading between %E and %E bytes "
1125                                               "from a region of size %E")),
1126                                         range[0], range[1], size));
1127 
1128       if (warned)
1129           suppress_warning (exp, OPT_Wstringop_overread);
1130 
1131       return warned;
1132     }
1133 
1134   if (tree_int_cst_equal (range[0], range[1])
1135       || tree_int_cst_sign_bit (range[1]))
1136     warned = (func
1137                 ? warning_n (loc, OPT_Wstringop_overread,
1138                                  tree_to_uhwi (range[0]),
1139                                  "%qD expecting %E byte in a region of size %E",
1140                                  "%qD expecting %E bytes in a region of size %E",
1141                                  func, range[0], size)
1142                 : warning_n (loc, OPT_Wstringop_overread,
1143                                  tree_to_uhwi (range[0]),
1144                                  "expecting %E byte in a region of size %E",
1145                                  "expecting %E bytes in a region of size %E",
1146                                  range[0], size));
1147   else if (tree_int_cst_sign_bit (range[1]))
1148     {
1149       /* Avoid printing the upper bound if it's invalid.  */
1150       warned = (func
1151                     ? warning_at (loc, OPT_Wstringop_overread,
1152                                     "%qD expecting %E or more bytes in a region "
1153                                     "of size %E",
1154                                     func, range[0], size)
1155                     : warning_at (loc, OPT_Wstringop_overread,
1156                                     "expecting %E or more bytes in a region "
1157                                     "of size %E",
1158                                     range[0], size));
1159     }
1160   else
1161     warned = (func
1162                 ? warning_at (loc, OPT_Wstringop_overread,
1163                                   "%qD expecting between %E and %E bytes in "
1164                                   "a region of size %E",
1165                                   func, range[0], range[1], size)
1166                 : warning_at (loc, OPT_Wstringop_overread,
1167                                   "expecting between %E and %E bytes in "
1168                                   "a region of size %E",
1169                                   range[0], range[1], size));
1170 
1171   if (warned)
1172     suppress_warning (exp, OPT_Wstringop_overread);
1173 
1174   return warned;
1175 }
1176 
1177 static bool
warn_for_access(location_t loc,tree func,gimple * stmt,int opt,tree range[2],tree size,bool write,bool read,bool maybe)1178 warn_for_access (location_t loc, tree func, gimple *stmt, int opt,
1179                      tree range[2], tree size, bool write, bool read, bool maybe)
1180 {
1181   return warn_for_access<gimple *>(loc, func, stmt, opt, range, size,
1182                                            write, read, maybe);
1183 }
1184 
1185 static bool
warn_for_access(location_t loc,tree func,tree expr,int opt,tree range[2],tree size,bool write,bool read,bool maybe)1186 warn_for_access (location_t loc, tree func, tree expr, int opt,
1187                      tree range[2], tree size, bool write, bool read, bool maybe)
1188 {
1189   return warn_for_access<tree>(loc, func, expr, opt, range, size,
1190                                      write, read, maybe);
1191 }
1192 
1193 /* Helper to set RANGE to the range of BOUND if it's nonnull, bounded
1194    by BNDRNG if nonnull and valid.  */
1195 
1196 static void
get_size_range(range_query * query,tree bound,gimple * stmt,tree range[2],const offset_int bndrng[2])1197 get_size_range (range_query *query, tree bound, gimple *stmt, tree range[2],
1198                     const offset_int bndrng[2])
1199 {
1200   if (bound)
1201     get_size_range (query, bound, stmt, range);
1202 
1203   if (!bndrng || (bndrng[0] == 0 && bndrng[1] == HOST_WIDE_INT_M1U))
1204     return;
1205 
1206   if (range[0] && TREE_CODE (range[0]) == INTEGER_CST)
1207     {
1208       offset_int r[] =
1209           { wi::to_offset (range[0]), wi::to_offset (range[1]) };
1210       if (r[0] < bndrng[0])
1211           range[0] = wide_int_to_tree (sizetype, bndrng[0]);
1212       if (bndrng[1] < r[1])
1213           range[1] = wide_int_to_tree (sizetype, bndrng[1]);
1214     }
1215   else
1216     {
1217       range[0] = wide_int_to_tree (sizetype, bndrng[0]);
1218       range[1] = wide_int_to_tree (sizetype, bndrng[1]);
1219     }
1220 }
1221 
1222 /* Try to verify that the sizes and lengths of the arguments to a string
1223    manipulation function given by EXP are within valid bounds and that
1224    the operation does not lead to buffer overflow or read past the end.
1225    Arguments other than EXP may be null.  When non-null, the arguments
1226    have the following meaning:
1227    DST is the destination of a copy call or NULL otherwise.
1228    SRC is the source of a copy call or NULL otherwise.
1229    DSTWRITE is the number of bytes written into the destination obtained
1230    from the user-supplied size argument to the function (such as in
1231    memcpy(DST, SRCs, DSTWRITE) or strncpy(DST, DRC, DSTWRITE).
1232    MAXREAD is the user-supplied bound on the length of the source sequence
1233    (such as in strncat(d, s, N).  It specifies the upper limit on the number
1234    of bytes to write.  If NULL, it's taken to be the same as DSTWRITE.
1235    SRCSTR is the source string (such as in strcpy(DST, SRC)) when the
1236    expression EXP is a string function call (as opposed to a memory call
1237    like memcpy).  As an exception, SRCSTR can also be an integer denoting
1238    the precomputed size of the source string or object (for functions like
1239    memcpy).
1240    DSTSIZE is the size of the destination object.
1241 
1242    When DSTWRITE is null LEN is checked to verify that it doesn't exceed
1243    SIZE_MAX.
1244 
1245    WRITE is true for write accesses, READ is true for reads.  Both are
1246    false for simple size checks in calls to functions that neither read
1247    from nor write to the region.
1248 
1249    When nonnull, PAD points to a more detailed description of the access.
1250 
1251    If the call is successfully verified as safe return true, otherwise
1252    return false.  */
1253 
1254 template <class GimpleOrTree>
1255 static bool
check_access(GimpleOrTree exp,tree dstwrite,tree maxread,tree srcstr,tree dstsize,access_mode mode,const access_data * pad,range_query * rvals)1256 check_access (GimpleOrTree exp, tree dstwrite,
1257                 tree maxread, tree srcstr, tree dstsize,
1258                 access_mode mode, const access_data *pad,
1259                 range_query *rvals)
1260 {
1261   /* The size of the largest object is half the address space, or
1262      PTRDIFF_MAX.  (This is way too permissive.)  */
1263   tree maxobjsize = max_object_size ();
1264 
1265   /* Either an approximate/minimum the length of the source string for
1266      string functions or the size of the source object for raw memory
1267      functions.  */
1268   tree slen = NULL_TREE;
1269 
1270   /* The range of the access in bytes; first set to the write access
1271      for functions that write and then read for those that also (or
1272      just) read.  */
1273   tree range[2] = { NULL_TREE, NULL_TREE };
1274 
1275   /* Set to true when the exact number of bytes written by a string
1276      function like strcpy is not known and the only thing that is
1277      known is that it must be at least one (for the terminating nul).  */
1278   bool at_least_one = false;
1279   if (srcstr)
1280     {
1281       /* SRCSTR is normally a pointer to string but as a special case
1282            it can be an integer denoting the length of a string.  */
1283       if (POINTER_TYPE_P (TREE_TYPE (srcstr)))
1284           {
1285             if (!check_nul_terminated_array (exp, srcstr, maxread))
1286               /* Return if the array is not nul-terminated and a warning
1287                  has been issued.  */
1288               return false;
1289 
1290             /* Try to determine the range of lengths the source string
1291                refers to.  If it can be determined and is less than
1292                the upper bound given by MAXREAD add one to it for
1293                the terminating nul.  Otherwise, set it to one for
1294                the same reason, or to MAXREAD as appropriate.  */
1295             c_strlen_data lendata = { };
1296             get_range_strlen (srcstr, &lendata, /* eltsize = */ 1);
1297             range[0] = lendata.minlen;
1298             range[1] = lendata.maxbound ? lendata.maxbound : lendata.maxlen;
1299             if (range[0]
1300                 && TREE_CODE (range[0]) == INTEGER_CST
1301                 && TREE_CODE (range[1]) == INTEGER_CST
1302                 && (!maxread || TREE_CODE (maxread) == INTEGER_CST))
1303               {
1304                 if (maxread && tree_int_cst_le (maxread, range[0]))
1305                     range[0] = range[1] = maxread;
1306                 else
1307                     range[0] = fold_build2 (PLUS_EXPR, size_type_node,
1308                                                   range[0], size_one_node);
1309 
1310                 if (maxread && tree_int_cst_le (maxread, range[1]))
1311                     range[1] = maxread;
1312                 else if (!integer_all_onesp (range[1]))
1313                     range[1] = fold_build2 (PLUS_EXPR, size_type_node,
1314                                                   range[1], size_one_node);
1315 
1316                 slen = range[0];
1317               }
1318             else
1319               {
1320                 at_least_one = true;
1321                 slen = size_one_node;
1322               }
1323           }
1324       else
1325           slen = srcstr;
1326     }
1327 
1328   if (!dstwrite && !maxread)
1329     {
1330       /* When the only available piece of data is the object size
1331            there is nothing to do.  */
1332       if (!slen)
1333           return true;
1334 
1335       /* Otherwise, when the length of the source sequence is known
1336            (as with strlen), set DSTWRITE to it.  */
1337       if (!range[0])
1338           dstwrite = slen;
1339     }
1340 
1341   if (!dstsize)
1342     dstsize = maxobjsize;
1343 
1344   /* Set RANGE to that of DSTWRITE if non-null, bounded by PAD->DST_BNDRNG
1345      if valid.  */
1346   gimple *stmt = pad ? pad->stmt : nullptr;
1347   get_size_range (rvals, dstwrite, stmt, range, pad ? pad->dst_bndrng : NULL);
1348 
1349   tree func = get_callee_fndecl (exp);
1350   /* Read vs write access by built-ins can be determined from the const
1351      qualifiers on the pointer argument.  In the absence of attribute
1352      access, non-const qualified pointer arguments to user-defined
1353      functions are assumed to both read and write the objects.  */
1354   const bool builtin = func ? fndecl_built_in_p (func) : false;
1355 
1356   /* First check the number of bytes to be written against the maximum
1357      object size.  */
1358   if (range[0]
1359       && TREE_CODE (range[0]) == INTEGER_CST
1360       && tree_int_cst_lt (maxobjsize, range[0]))
1361     {
1362       location_t loc = get_location (exp);
1363       maybe_warn_for_bound (OPT_Wstringop_overflow_, loc, exp, func, range,
1364                                   NULL_TREE, pad);
1365       return false;
1366     }
1367 
1368   /* The number of bytes to write is "exact" if DSTWRITE is non-null,
1369      constant, and in range of unsigned HOST_WIDE_INT.  */
1370   bool exactwrite = dstwrite && tree_fits_uhwi_p (dstwrite);
1371 
1372   /* Next check the number of bytes to be written against the destination
1373      object size.  */
1374   if (range[0] || !exactwrite || integer_all_onesp (dstwrite))
1375     {
1376       if (range[0]
1377             && TREE_CODE (range[0]) == INTEGER_CST
1378             && ((tree_fits_uhwi_p (dstsize)
1379                  && tree_int_cst_lt (dstsize, range[0]))
1380                 || (dstwrite
1381                       && tree_fits_uhwi_p (dstwrite)
1382                       && tree_int_cst_lt (dstwrite, range[0]))))
1383           {
1384             const opt_code opt = OPT_Wstringop_overflow_;
1385             if (warning_suppressed_p (exp, opt)
1386                 || (pad && pad->dst.ref
1387                       && warning_suppressed_p (pad->dst.ref, opt)))
1388               return false;
1389 
1390             location_t loc = get_location (exp);
1391             bool warned = false;
1392             if (dstwrite == slen && at_least_one)
1393               {
1394                 /* This is a call to strcpy with a destination of 0 size
1395                      and a source of unknown length.  The call will write
1396                      at least one byte past the end of the destination.  */
1397                 warned = (func
1398                               ? warning_at (loc, opt,
1399                                               "%qD writing %E or more bytes into "
1400                                               "a region of size %E overflows "
1401                                               "the destination",
1402                                               func, range[0], dstsize)
1403                               : warning_at (loc, opt,
1404                                               "writing %E or more bytes into "
1405                                               "a region of size %E overflows "
1406                                               "the destination",
1407                                               range[0], dstsize));
1408               }
1409             else
1410               {
1411                 const bool read
1412                     = mode == access_read_only || mode == access_read_write;
1413                 const bool write
1414                     = mode == access_write_only || mode == access_read_write;
1415                 const bool maybe = pad && pad->dst.parmarray;
1416                 warned = warn_for_access (loc, func, exp,
1417                                                   OPT_Wstringop_overflow_,
1418                                                   range, dstsize,
1419                                                   write, read && !builtin, maybe);
1420               }
1421 
1422             if (warned)
1423               {
1424                 suppress_warning (exp, OPT_Wstringop_overflow_);
1425                 if (pad)
1426                     pad->dst.inform_access (pad->mode);
1427               }
1428 
1429             /* Return error when an overflow has been detected.  */
1430             return false;
1431           }
1432     }
1433 
1434   /* Check the maximum length of the source sequence against the size
1435      of the destination object if known, or against the maximum size
1436      of an object.  */
1437   if (maxread)
1438     {
1439       /* Set RANGE to that of MAXREAD, bounded by PAD->SRC_BNDRNG if
1440            PAD is nonnull and BNDRNG is valid.  */
1441       get_size_range (rvals, maxread, stmt, range, pad ? pad->src_bndrng : NULL);
1442 
1443       location_t loc = get_location (exp);
1444       tree size = dstsize;
1445       if (pad && pad->mode == access_read_only)
1446           size = wide_int_to_tree (sizetype, pad->src.size_remaining ());
1447 
1448       if (range[0] && maxread && tree_fits_uhwi_p (size))
1449           {
1450             if (tree_int_cst_lt (maxobjsize, range[0]))
1451               {
1452                 maybe_warn_for_bound (OPT_Wstringop_overread, loc, exp, func,
1453                                             range, size, pad);
1454                 return false;
1455               }
1456 
1457             if (size != maxobjsize && tree_int_cst_lt (size, range[0]))
1458               {
1459                 opt_code opt = (dstwrite || mode != access_read_only
1460                                     ? OPT_Wstringop_overflow_
1461                                     : OPT_Wstringop_overread);
1462                 maybe_warn_for_bound (opt, loc, exp, func, range, size, pad);
1463                 return false;
1464               }
1465           }
1466 
1467       maybe_warn_nonstring_arg (func, exp);
1468     }
1469 
1470   /* Check for reading past the end of SRC.  */
1471   bool overread = (slen
1472                        && slen == srcstr
1473                        && dstwrite
1474                        && range[0]
1475                        && TREE_CODE (slen) == INTEGER_CST
1476                        && tree_int_cst_lt (slen, range[0]));
1477   /* If none is determined try to get a better answer based on the details
1478      in PAD.  */
1479   if (!overread
1480       && pad
1481       && pad->src.sizrng[1] >= 0
1482       && pad->src.offrng[0] >= 0
1483       && (pad->src.offrng[1] < 0
1484             || pad->src.offrng[0] <= pad->src.offrng[1]))
1485     {
1486       /* Set RANGE to that of MAXREAD, bounded by PAD->SRC_BNDRNG if
1487            PAD is nonnull and BNDRNG is valid.  */
1488       get_size_range (rvals, maxread, stmt, range, pad ? pad->src_bndrng : NULL);
1489       /* Set OVERREAD for reads starting just past the end of an object.  */
1490       overread = pad->src.sizrng[1] - pad->src.offrng[0] < pad->src_bndrng[0];
1491       range[0] = wide_int_to_tree (sizetype, pad->src_bndrng[0]);
1492       slen = size_zero_node;
1493     }
1494 
1495   if (overread)
1496     {
1497       const opt_code opt = OPT_Wstringop_overread;
1498       if (warning_suppressed_p (exp, opt)
1499             || (srcstr && warning_suppressed_p (srcstr, opt))
1500             || (pad && pad->src.ref
1501                 && warning_suppressed_p (pad->src.ref, opt)))
1502           return false;
1503 
1504       location_t loc = get_location (exp);
1505       const bool read
1506           = mode == access_read_only || mode == access_read_write;
1507       const bool maybe = pad && pad->dst.parmarray;
1508       if (warn_for_access (loc, func, exp, opt, range, slen, false, read,
1509                                  maybe))
1510           {
1511             suppress_warning (exp, opt);
1512             if (pad)
1513               pad->src.inform_access (access_read_only);
1514           }
1515       return false;
1516     }
1517 
1518   return true;
1519 }
1520 
1521 static bool
check_access(gimple * stmt,tree dstwrite,tree maxread,tree srcstr,tree dstsize,access_mode mode,const access_data * pad,range_query * rvals)1522 check_access (gimple *stmt, tree dstwrite,
1523                 tree maxread, tree srcstr, tree dstsize,
1524                 access_mode mode, const access_data *pad,
1525                 range_query *rvals)
1526 {
1527   return check_access<gimple *> (stmt, dstwrite, maxread, srcstr, dstsize,
1528                                          mode, pad, rvals);
1529 }
1530 
1531 bool
check_access(tree expr,tree dstwrite,tree maxread,tree srcstr,tree dstsize,access_mode mode,const access_data * pad)1532 check_access (tree expr, tree dstwrite,
1533                 tree maxread, tree srcstr, tree dstsize,
1534                 access_mode mode, const access_data *pad /* = NULL */)
1535 {
1536   return check_access<tree> (expr, dstwrite, maxread, srcstr, dstsize,
1537                                    mode, pad, nullptr);
1538 }
1539 
1540 /* Return true if STMT is a call to an allocation function.  Unless
1541    ALL_ALLOC is set, consider only functions that return dynamically
1542    allocated objects.  Otherwise return true even for all forms of
1543    alloca (including VLA).  */
1544 
1545 static bool
fndecl_alloc_p(tree fndecl,bool all_alloc)1546 fndecl_alloc_p (tree fndecl, bool all_alloc)
1547 {
1548   if (!fndecl)
1549     return false;
1550 
1551   /* A call to operator new isn't recognized as one to a built-in.  */
1552   if (DECL_IS_OPERATOR_NEW_P (fndecl))
1553     return true;
1554 
1555   if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
1556     {
1557       switch (DECL_FUNCTION_CODE (fndecl))
1558           {
1559           case BUILT_IN_ALLOCA:
1560           case BUILT_IN_ALLOCA_WITH_ALIGN:
1561             return all_alloc;
1562           case BUILT_IN_ALIGNED_ALLOC:
1563           case BUILT_IN_CALLOC:
1564           case BUILT_IN_GOMP_ALLOC:
1565           case BUILT_IN_MALLOC:
1566           case BUILT_IN_REALLOC:
1567           case BUILT_IN_STRDUP:
1568           case BUILT_IN_STRNDUP:
1569             return true;
1570           default:
1571             break;
1572           }
1573     }
1574 
1575   /* A function is considered an allocation function if it's declared
1576      with attribute malloc with an argument naming its associated
1577      deallocation function.  */
1578   tree attrs = DECL_ATTRIBUTES (fndecl);
1579   if (!attrs)
1580     return false;
1581 
1582   for (tree allocs = attrs;
1583        (allocs = lookup_attribute ("malloc", allocs));
1584        allocs = TREE_CHAIN (allocs))
1585     {
1586       tree args = TREE_VALUE (allocs);
1587       if (!args)
1588           continue;
1589 
1590       if (TREE_VALUE (args))
1591           return true;
1592     }
1593 
1594   return false;
1595 }
1596 
1597 /* Return true if STMT is a call to an allocation function.  A wrapper
1598    around fndecl_alloc_p.  */
1599 
1600 static bool
gimple_call_alloc_p(gimple * stmt,bool all_alloc=false)1601 gimple_call_alloc_p (gimple *stmt, bool all_alloc = false)
1602 {
1603   return fndecl_alloc_p (gimple_call_fndecl (stmt), all_alloc);
1604 }
1605 
1606 /* Return true if DELC doesn't refer to an operator delete that's
1607    suitable to call with a pointer returned from the operator new
1608    described by NEWC.  */
1609 
1610 static bool
new_delete_mismatch_p(const demangle_component & newc,const demangle_component & delc)1611 new_delete_mismatch_p (const demangle_component &newc,
1612                            const demangle_component &delc)
1613 {
1614   if (newc.type != delc.type)
1615     return true;
1616 
1617   switch (newc.type)
1618     {
1619     case DEMANGLE_COMPONENT_NAME:
1620       {
1621           int len = newc.u.s_name.len;
1622           const char *news = newc.u.s_name.s;
1623           const char *dels = delc.u.s_name.s;
1624           if (len != delc.u.s_name.len || memcmp (news, dels, len))
1625             return true;
1626 
1627           if (news[len] == 'n')
1628             {
1629               if (news[len + 1] == 'a')
1630                 return dels[len] != 'd' || dels[len + 1] != 'a';
1631               if (news[len + 1] == 'w')
1632                 return dels[len] != 'd' || dels[len + 1] != 'l';
1633             }
1634           return false;
1635       }
1636 
1637     case DEMANGLE_COMPONENT_OPERATOR:
1638       /* Operator mismatches are handled above.  */
1639       return false;
1640 
1641     case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
1642       if (newc.u.s_extended_operator.args != delc.u.s_extended_operator.args)
1643           return true;
1644       return new_delete_mismatch_p (*newc.u.s_extended_operator.name,
1645                                             *delc.u.s_extended_operator.name);
1646 
1647     case DEMANGLE_COMPONENT_FIXED_TYPE:
1648       if (newc.u.s_fixed.accum != delc.u.s_fixed.accum
1649             || newc.u.s_fixed.sat != delc.u.s_fixed.sat)
1650           return true;
1651       return new_delete_mismatch_p (*newc.u.s_fixed.length,
1652                                             *delc.u.s_fixed.length);
1653 
1654     case DEMANGLE_COMPONENT_CTOR:
1655       if (newc.u.s_ctor.kind != delc.u.s_ctor.kind)
1656           return true;
1657       return new_delete_mismatch_p (*newc.u.s_ctor.name,
1658                                             *delc.u.s_ctor.name);
1659 
1660     case DEMANGLE_COMPONENT_DTOR:
1661       if (newc.u.s_dtor.kind != delc.u.s_dtor.kind)
1662           return true;
1663       return new_delete_mismatch_p (*newc.u.s_dtor.name,
1664                                             *delc.u.s_dtor.name);
1665 
1666     case DEMANGLE_COMPONENT_BUILTIN_TYPE:
1667       {
1668           /* The demangler API provides no better way to compare built-in
1669              types except to by comparing their demangled names. */
1670           size_t nsz, dsz;
1671           demangle_component *pnc = const_cast<demangle_component *>(&newc);
1672           demangle_component *pdc = const_cast<demangle_component *>(&delc);
1673           char *nts = cplus_demangle_print (0, pnc, 16, &nsz);
1674           char *dts = cplus_demangle_print (0, pdc, 16, &dsz);
1675           if (!nts != !dts)
1676             return true;
1677           bool mismatch = strcmp (nts, dts);
1678           free (nts);
1679           free (dts);
1680           return mismatch;
1681       }
1682 
1683     case DEMANGLE_COMPONENT_SUB_STD:
1684       if (newc.u.s_string.len != delc.u.s_string.len)
1685           return true;
1686       return memcmp (newc.u.s_string.string, delc.u.s_string.string,
1687                          newc.u.s_string.len);
1688 
1689     case DEMANGLE_COMPONENT_FUNCTION_PARAM:
1690     case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
1691     case DEMANGLE_COMPONENT_UNNAMED_TYPE:
1692       return newc.u.s_number.number != delc.u.s_number.number;
1693 
1694     case DEMANGLE_COMPONENT_CHARACTER:
1695       return newc.u.s_character.character != delc.u.s_character.character;
1696 
1697     case DEMANGLE_COMPONENT_DEFAULT_ARG:
1698     case DEMANGLE_COMPONENT_LAMBDA:
1699       if (newc.u.s_unary_num.num != delc.u.s_unary_num.num)
1700           return true;
1701       return new_delete_mismatch_p (*newc.u.s_unary_num.sub,
1702                                             *delc.u.s_unary_num.sub);
1703     default:
1704       break;
1705     }
1706 
1707   if (!newc.u.s_binary.left != !delc.u.s_binary.left)
1708     return true;
1709 
1710   if (!newc.u.s_binary.left)
1711     return false;
1712 
1713   if (new_delete_mismatch_p (*newc.u.s_binary.left, *delc.u.s_binary.left)
1714       || !newc.u.s_binary.right != !delc.u.s_binary.right)
1715     return true;
1716 
1717   if (newc.u.s_binary.right)
1718     return new_delete_mismatch_p (*newc.u.s_binary.right,
1719                                           *delc.u.s_binary.right);
1720   return false;
1721 }
1722 
1723 /* Return true if DELETE_DECL is an operator delete that's not suitable
1724    to call with a pointer returned from NEW_DECL.  */
1725 
1726 static bool
new_delete_mismatch_p(tree new_decl,tree delete_decl)1727 new_delete_mismatch_p (tree new_decl, tree delete_decl)
1728 {
1729   tree new_name = DECL_ASSEMBLER_NAME (new_decl);
1730   tree delete_name = DECL_ASSEMBLER_NAME (delete_decl);
1731 
1732   /* valid_new_delete_pair_p() returns a conservative result (currently
1733      it only handles global operators).  A true result is reliable but
1734      a false result doesn't necessarily mean the operators don't match
1735      unless CERTAIN is set.  */
1736   bool certain;
1737   if (valid_new_delete_pair_p (new_name, delete_name, &certain))
1738     return false;
1739   /* CERTAIN is set when the negative result is certain.  */
1740   if (certain)
1741     return true;
1742 
1743   /* For anything not handled by valid_new_delete_pair_p() such as member
1744      operators compare the individual demangled components of the mangled
1745      name.  */
1746   const char *new_str = IDENTIFIER_POINTER (new_name);
1747   const char *del_str = IDENTIFIER_POINTER (delete_name);
1748 
1749   void *np = NULL, *dp = NULL;
1750   demangle_component *ndc = cplus_demangle_v3_components (new_str, 0, &np);
1751   demangle_component *ddc = cplus_demangle_v3_components (del_str, 0, &dp);
1752   bool mismatch = new_delete_mismatch_p (*ndc, *ddc);
1753   free (np);
1754   free (dp);
1755   return mismatch;
1756 }
1757 
1758 /* ALLOC_DECL and DEALLOC_DECL are pair of allocation and deallocation
1759    functions.  Return true if the latter is suitable to deallocate objects
1760    allocated by calls to the former.  */
1761 
1762 static bool
matching_alloc_calls_p(tree alloc_decl,tree dealloc_decl)1763 matching_alloc_calls_p (tree alloc_decl, tree dealloc_decl)
1764 {
1765   /* Set to alloc_kind_t::builtin if ALLOC_DECL is associated with
1766      a built-in deallocator.  */
1767   enum class alloc_kind_t { none, builtin, user }
1768   alloc_dealloc_kind = alloc_kind_t::none;
1769 
1770   if (DECL_IS_OPERATOR_NEW_P (alloc_decl))
1771     {
1772       if (DECL_IS_OPERATOR_DELETE_P (dealloc_decl))
1773           /* Return true iff both functions are of the same array or
1774              singleton form and false otherwise.  */
1775           return !new_delete_mismatch_p (alloc_decl, dealloc_decl);
1776 
1777       /* Return false for deallocation functions that are known not
1778            to match.  */
1779       if (fndecl_built_in_p (dealloc_decl, BUILT_IN_FREE)
1780             || fndecl_built_in_p (dealloc_decl, BUILT_IN_REALLOC))
1781           return false;
1782       /* Otherwise proceed below to check the deallocation function's
1783            "*dealloc" attributes to look for one that mentions this operator
1784            new.  */
1785     }
1786   else if (fndecl_built_in_p (alloc_decl, BUILT_IN_NORMAL))
1787     {
1788       switch (DECL_FUNCTION_CODE (alloc_decl))
1789           {
1790           case BUILT_IN_ALLOCA:
1791           case BUILT_IN_ALLOCA_WITH_ALIGN:
1792             return false;
1793 
1794           case BUILT_IN_ALIGNED_ALLOC:
1795           case BUILT_IN_CALLOC:
1796           case BUILT_IN_GOMP_ALLOC:
1797           case BUILT_IN_MALLOC:
1798           case BUILT_IN_REALLOC:
1799           case BUILT_IN_STRDUP:
1800           case BUILT_IN_STRNDUP:
1801             if (DECL_IS_OPERATOR_DELETE_P (dealloc_decl))
1802               return false;
1803 
1804             if (fndecl_built_in_p (dealloc_decl, BUILT_IN_FREE)
1805                 || fndecl_built_in_p (dealloc_decl, BUILT_IN_REALLOC))
1806               return true;
1807 
1808             alloc_dealloc_kind = alloc_kind_t::builtin;
1809             break;
1810 
1811           default:
1812             break;
1813           }
1814     }
1815 
1816   /* Set if DEALLOC_DECL both allocates and deallocates.  */
1817   alloc_kind_t realloc_kind = alloc_kind_t::none;
1818 
1819   if (fndecl_built_in_p (dealloc_decl, BUILT_IN_NORMAL))
1820     {
1821       built_in_function dealloc_code = DECL_FUNCTION_CODE (dealloc_decl);
1822       if (dealloc_code == BUILT_IN_REALLOC)
1823           realloc_kind = alloc_kind_t::builtin;
1824 
1825       for (tree amats = DECL_ATTRIBUTES (alloc_decl);
1826              (amats = lookup_attribute ("malloc", amats));
1827              amats = TREE_CHAIN (amats))
1828           {
1829             tree args = TREE_VALUE (amats);
1830             if (!args)
1831               continue;
1832 
1833             tree fndecl = TREE_VALUE (args);
1834             if (!fndecl || !DECL_P (fndecl))
1835               continue;
1836 
1837             if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
1838                 && dealloc_code == DECL_FUNCTION_CODE (fndecl))
1839               return true;
1840           }
1841     }
1842 
1843   const bool alloc_builtin = fndecl_built_in_p (alloc_decl, BUILT_IN_NORMAL);
1844   alloc_kind_t realloc_dealloc_kind = alloc_kind_t::none;
1845 
1846   /* If DEALLOC_DECL has an internal "*dealloc" attribute scan the list
1847      of its associated allocation functions for ALLOC_DECL.
1848      If the corresponding ALLOC_DECL is found they're a matching pair,
1849      otherwise they're not.
1850      With DDATS set to the Deallocator's *Dealloc ATtributes...  */
1851   for (tree ddats = DECL_ATTRIBUTES (dealloc_decl);
1852        (ddats = lookup_attribute ("*dealloc", ddats));
1853        ddats = TREE_CHAIN (ddats))
1854     {
1855       tree args = TREE_VALUE (ddats);
1856       if (!args)
1857           continue;
1858 
1859       tree alloc = TREE_VALUE (args);
1860       if (!alloc)
1861           continue;
1862 
1863       if (alloc == DECL_NAME (dealloc_decl))
1864           realloc_kind = alloc_kind_t::user;
1865 
1866       if (DECL_P (alloc))
1867           {
1868             gcc_checking_assert (fndecl_built_in_p (alloc, BUILT_IN_NORMAL));
1869 
1870             switch (DECL_FUNCTION_CODE (alloc))
1871               {
1872               case BUILT_IN_ALIGNED_ALLOC:
1873               case BUILT_IN_CALLOC:
1874               case BUILT_IN_GOMP_ALLOC:
1875               case BUILT_IN_MALLOC:
1876               case BUILT_IN_REALLOC:
1877               case BUILT_IN_STRDUP:
1878               case BUILT_IN_STRNDUP:
1879                 realloc_dealloc_kind = alloc_kind_t::builtin;
1880                 break;
1881               default:
1882                 break;
1883               }
1884 
1885             if (!alloc_builtin)
1886               continue;
1887 
1888             if (DECL_FUNCTION_CODE (alloc) != DECL_FUNCTION_CODE (alloc_decl))
1889               continue;
1890 
1891             return true;
1892           }
1893 
1894       if (alloc == DECL_NAME (alloc_decl))
1895           return true;
1896     }
1897 
1898   if (realloc_kind == alloc_kind_t::none)
1899     return false;
1900 
1901   hash_set<tree> common_deallocs;
1902   /* Special handling for deallocators.  Iterate over both the allocator's
1903      and the reallocator's associated deallocator functions looking for
1904      the first one in common.  If one is found, the de/reallocator is
1905      a match for the allocator even though the latter isn't directly
1906      associated with the former.  This simplifies declarations in system
1907      headers.
1908      With AMATS set to the Allocator's Malloc ATtributes,
1909      and  RMATS set to Reallocator's Malloc ATtributes...  */
1910   for (tree amats = DECL_ATTRIBUTES (alloc_decl),
1911            rmats = DECL_ATTRIBUTES (dealloc_decl);
1912        (amats = lookup_attribute ("malloc", amats))
1913            || (rmats = lookup_attribute ("malloc", rmats));
1914        amats = amats ? TREE_CHAIN (amats) : NULL_TREE,
1915            rmats = rmats ? TREE_CHAIN (rmats) : NULL_TREE)
1916     {
1917       if (tree args = amats ? TREE_VALUE (amats) : NULL_TREE)
1918           if (tree adealloc = TREE_VALUE (args))
1919             {
1920               if (DECL_P (adealloc)
1921                     && fndecl_built_in_p (adealloc, BUILT_IN_NORMAL))
1922                 {
1923                     built_in_function fncode = DECL_FUNCTION_CODE (adealloc);
1924                     if (fncode == BUILT_IN_FREE || fncode == BUILT_IN_REALLOC)
1925                       {
1926                         if (realloc_kind == alloc_kind_t::builtin)
1927                           return true;
1928                         alloc_dealloc_kind = alloc_kind_t::builtin;
1929                       }
1930                     continue;
1931                 }
1932 
1933               common_deallocs.add (adealloc);
1934             }
1935 
1936       if (tree args = rmats ? TREE_VALUE (rmats) : NULL_TREE)
1937           if (tree ddealloc = TREE_VALUE (args))
1938             {
1939               if (DECL_P (ddealloc)
1940                     && fndecl_built_in_p (ddealloc, BUILT_IN_NORMAL))
1941                 {
1942                     built_in_function fncode = DECL_FUNCTION_CODE (ddealloc);
1943                     if (fncode == BUILT_IN_FREE || fncode == BUILT_IN_REALLOC)
1944                       {
1945                         if (alloc_dealloc_kind == alloc_kind_t::builtin)
1946                           return true;
1947                         realloc_dealloc_kind = alloc_kind_t::builtin;
1948                       }
1949                     continue;
1950                 }
1951 
1952               if (common_deallocs.add (ddealloc))
1953                 return true;
1954             }
1955     }
1956 
1957   /* Succeed only if ALLOC_DECL and the reallocator DEALLOC_DECL share
1958      a built-in deallocator.  */
1959   return  (alloc_dealloc_kind == alloc_kind_t::builtin
1960              && realloc_dealloc_kind == alloc_kind_t::builtin);
1961 }
1962 
1963 /* Return true if DEALLOC_DECL is a function suitable to deallocate
1964    objects allocated by the ALLOC call.  */
1965 
1966 static bool
matching_alloc_calls_p(gimple * alloc,tree dealloc_decl)1967 matching_alloc_calls_p (gimple *alloc, tree dealloc_decl)
1968 {
1969   tree alloc_decl = gimple_call_fndecl (alloc);
1970   if (!alloc_decl)
1971     return true;
1972 
1973   return matching_alloc_calls_p (alloc_decl, dealloc_decl);
1974 }
1975 
1976 /* Diagnose a call EXP to deallocate a pointer referenced by AREF if it
1977    includes a nonzero offset.  Such a pointer cannot refer to the beginning
1978    of an allocated object.  A negative offset may refer to it only if
1979    the target pointer is unknown.  */
1980 
1981 static bool
warn_dealloc_offset(location_t loc,gimple * call,const access_ref & aref)1982 warn_dealloc_offset (location_t loc, gimple *call, const access_ref &aref)
1983 {
1984   if (aref.deref || aref.offrng[0] <= 0 || aref.offrng[1] <= 0)
1985     return false;
1986 
1987   tree dealloc_decl = gimple_call_fndecl (call);
1988   if (!dealloc_decl)
1989     return false;
1990 
1991   if (DECL_IS_OPERATOR_DELETE_P (dealloc_decl)
1992       && !DECL_IS_REPLACEABLE_OPERATOR (dealloc_decl))
1993     {
1994       /* A call to a user-defined operator delete with a pointer plus offset
1995            may be valid if it's returned from an unknown function (i.e., one
1996            that's not operator new).  */
1997       if (TREE_CODE (aref.ref) == SSA_NAME)
1998           {
1999             gimple *def_stmt = SSA_NAME_DEF_STMT (aref.ref);
2000             if (is_gimple_call (def_stmt))
2001               {
2002                 tree alloc_decl = gimple_call_fndecl (def_stmt);
2003                 if (!alloc_decl || !DECL_IS_OPERATOR_NEW_P (alloc_decl))
2004                     return false;
2005               }
2006           }
2007     }
2008 
2009   char offstr[80];
2010   offstr[0] = '\0';
2011   if (wi::fits_shwi_p (aref.offrng[0]))
2012     {
2013       if (aref.offrng[0] == aref.offrng[1]
2014             || !wi::fits_shwi_p (aref.offrng[1]))
2015           sprintf (offstr, " %lli",
2016                      (long long)aref.offrng[0].to_shwi ());
2017       else
2018           sprintf (offstr, " [%lli, %lli]",
2019                      (long long)aref.offrng[0].to_shwi (),
2020                      (long long)aref.offrng[1].to_shwi ());
2021     }
2022 
2023   if (!warning_at (loc, OPT_Wfree_nonheap_object,
2024                        "%qD called on pointer %qE with nonzero offset%s",
2025                        dealloc_decl, aref.ref, offstr))
2026     return false;
2027 
2028   if (DECL_P (aref.ref))
2029     inform (get_location (aref.ref), "declared here");
2030   else if (TREE_CODE (aref.ref) == SSA_NAME)
2031     {
2032       gimple *def_stmt = SSA_NAME_DEF_STMT (aref.ref);
2033       if (is_gimple_call (def_stmt))
2034           {
2035             location_t def_loc = get_location (def_stmt);
2036             tree alloc_decl = gimple_call_fndecl (def_stmt);
2037             if (alloc_decl)
2038               inform (def_loc,
2039                         "returned from %qD", alloc_decl);
2040             else if (tree alloc_fntype = gimple_call_fntype (def_stmt))
2041               inform (def_loc,
2042                         "returned from %qT", alloc_fntype);
2043             else
2044               inform (def_loc,  "obtained here");
2045           }
2046     }
2047 
2048   return true;
2049 }
2050 
2051 namespace {
2052 
2053 const pass_data pass_data_waccess = {
2054   GIMPLE_PASS,
2055   "waccess",
2056   OPTGROUP_NONE,
2057   TV_WARN_ACCESS, /* timer variable */
2058   PROP_cfg, /* properties_required  */
2059   0,          /* properties_provided  */
2060   0,          /* properties_destroyed  */
2061   0,          /* properties_start */
2062   0,          /* properties_finish */
2063 };
2064 
2065 /* Pass to detect invalid accesses.  */
2066 class pass_waccess : public gimple_opt_pass
2067 {
2068  public:
2069   pass_waccess (gcc::context *);
2070 
2071   ~pass_waccess ();
2072 
2073   opt_pass *clone ();
2074 
2075   virtual bool gate (function *);
2076 
2077   void set_pass_param (unsigned, bool);
2078 
2079   virtual unsigned int execute (function *);
2080 
2081 private:
2082   /* Not copyable or assignable.  */
2083   pass_waccess (pass_waccess &) = delete;
2084   void operator= (pass_waccess &) = delete;
2085 
2086   /* Check a call to an atomic built-in function.  */
2087   bool check_atomic_builtin (gcall *);
2088 
2089   /* Check a call to a built-in function.  */
2090   bool check_builtin (gcall *);
2091 
2092   /* Check a call to an ordinary function for invalid accesses.  */
2093   bool check_call_access (gcall *);
2094 
2095   /* Check a non-call statement.  */
2096   void check_stmt (gimple *);
2097 
2098   /* Check statements in a basic block.  */
2099   void check_block (basic_block);
2100 
2101   /* Check a call to a function.  */
2102   void check_call (gcall *);
2103 
2104   /* Check a call to the named built-in function.  */
2105   void check_alloca (gcall *);
2106   void check_alloc_size_call (gcall *);
2107   void check_strcat (gcall *);
2108   void check_strncat (gcall *);
2109   void check_stxcpy (gcall *);
2110   void check_stxncpy (gcall *);
2111   void check_strncmp (gcall *);
2112   void check_memop_access (gimple *, tree, tree, tree);
2113   void check_read_access (gimple *, tree, tree = NULL_TREE, int = 1);
2114 
2115   void maybe_check_dealloc_call (gcall *);
2116   void maybe_check_access_sizes (rdwr_map *, tree, tree, gimple *);
2117   bool maybe_warn_memmodel (gimple *, tree, tree, const unsigned char *);
2118   void check_atomic_memmodel (gimple *, tree, tree, const unsigned char *);
2119 
2120   /* Check for uses of indeterminate pointers.  */
2121   void check_pointer_uses (gimple *, tree, tree = NULL_TREE, bool = false);
2122 
2123   /* Return the argument that a call returns.  */
2124   tree gimple_call_return_arg (gcall *);
2125 
2126   /* Check a call for uses of a dangling pointer arguments.  */
2127   void check_call_dangling (gcall *);
2128 
2129   /* Check uses of a dangling pointer or those derived from it.  */
2130   void check_dangling_uses (tree, tree, bool = false, bool = false);
2131   void check_dangling_uses ();
2132   void check_dangling_stores ();
2133   void check_dangling_stores (basic_block, hash_set<tree> &, auto_bitmap &);
2134 
2135   void warn_invalid_pointer (tree, gimple *, gimple *, tree, bool, bool = false);
2136 
2137   /* Return true if use follows an invalidating statement.  */
2138   bool use_after_inval_p (gimple *, gimple *, bool = false);
2139 
2140   /* A pointer_query object to store information about pointers and
2141      their targets in.  */
2142   pointer_query m_ptr_qry;
2143   /* Mapping from DECLs and their clobber statements in the function.  */
2144   hash_map<tree, gimple *> m_clobbers;
2145   /* A bit is set for each basic block whose statements have been assigned
2146      valid UIDs.  */
2147   bitmap m_bb_uids_set;
2148   /* The current function.  */
2149   function *m_func;
2150   /* True to run checks for uses of dangling pointers.  */
2151   bool m_check_dangling_p;
2152   /* True to run checks early on in the optimization pipeline.  */
2153   bool m_early_checks_p;
2154 };
2155 
2156 /* Construct the pass.  */
2157 
pass_waccess(gcc::context * ctxt)2158 pass_waccess::pass_waccess (gcc::context *ctxt)
2159   : gimple_opt_pass (pass_data_waccess, ctxt),
2160     m_ptr_qry (NULL),
2161     m_clobbers (),
2162     m_bb_uids_set (),
2163     m_func (),
2164     m_check_dangling_p (),
2165     m_early_checks_p ()
2166 {
2167 }
2168 
2169 /* Return a copy of the pass with RUN_NUMBER one greater than THIS.  */
2170 
2171 opt_pass*
clone()2172 pass_waccess::clone ()
2173 {
2174   return new pass_waccess (m_ctxt);
2175 }
2176 
2177 /* Release pointer_query cache.  */
2178 
~pass_waccess()2179 pass_waccess::~pass_waccess ()
2180 {
2181   m_ptr_qry.flush_cache ();
2182 }
2183 
2184 void
set_pass_param(unsigned int n,bool early)2185 pass_waccess::set_pass_param (unsigned int n, bool early)
2186 {
2187   gcc_assert (n == 0);
2188 
2189   m_early_checks_p = early;
2190 }
2191 
2192 /* Return true when any checks performed by the pass are enabled.  */
2193 
2194 bool
gate(function *)2195 pass_waccess::gate (function *)
2196 {
2197   return (warn_free_nonheap_object
2198             || warn_mismatched_alloc
2199             || warn_mismatched_new_delete);
2200 }
2201 
2202 /* Initialize ALLOC_OBJECT_SIZE_LIMIT based on the -Walloc-size-larger-than=
2203    setting if the option is specified, or to the maximum object size if it
2204    is not.  Return the initialized value.  */
2205 
2206 static tree
alloc_max_size(void)2207 alloc_max_size (void)
2208 {
2209   HOST_WIDE_INT limit = warn_alloc_size_limit;
2210   if (limit == HOST_WIDE_INT_MAX)
2211     limit = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
2212 
2213   return build_int_cst (size_type_node, limit);
2214 }
2215 
2216 /* Diagnose a call EXP to function FN decorated with attribute alloc_size
2217    whose argument numbers given by IDX with values given by ARGS exceed
2218    the maximum object size or cause an unsigned overflow (wrapping) when
2219    multiplied.  FN is null when EXP is a call via a function pointer.
2220    When ARGS[0] is null the function does nothing.  ARGS[1] may be null
2221    for functions like malloc, and non-null for those like calloc that
2222    are decorated with a two-argument attribute alloc_size.  */
2223 
2224 void
maybe_warn_alloc_args_overflow(gimple * stmt,const tree args[2],const int idx[2])2225 maybe_warn_alloc_args_overflow (gimple *stmt, const tree args[2],
2226                                         const int idx[2])
2227 {
2228   /* The range each of the (up to) two arguments is known to be in.  */
2229   tree argrange[2][2] = { { NULL_TREE, NULL_TREE }, { NULL_TREE, NULL_TREE } };
2230 
2231   /* Maximum object size set by -Walloc-size-larger-than= or SIZE_MAX / 2.  */
2232   tree maxobjsize = alloc_max_size ();
2233 
2234   location_t loc = get_location (stmt);
2235 
2236   tree fn = gimple_call_fndecl (stmt);
2237   tree fntype = fn ? TREE_TYPE (fn) : gimple_call_fntype (stmt);
2238   bool warned = false;
2239 
2240   /* Validate each argument individually.  */
2241   for (unsigned i = 0; i != 2 && args[i]; ++i)
2242     {
2243       if (TREE_CODE (args[i]) == INTEGER_CST)
2244           {
2245             argrange[i][0] = args[i];
2246             argrange[i][1] = args[i];
2247 
2248             if (tree_int_cst_lt (args[i], integer_zero_node))
2249               {
2250                 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2251                                            "argument %i value %qE is negative",
2252                                            idx[i] + 1, args[i]);
2253               }
2254             else if (integer_zerop (args[i]))
2255               {
2256                 /* Avoid issuing -Walloc-zero for allocation functions other
2257                      than __builtin_alloca that are declared with attribute
2258                      returns_nonnull because there's no portability risk.  This
2259                      avoids warning for such calls to libiberty's xmalloc and
2260                      friends.
2261                      Also avoid issuing the warning for calls to function named
2262                      "alloca".  */
2263                 if (fn && fndecl_built_in_p (fn, BUILT_IN_ALLOCA)
2264                       ? IDENTIFIER_LENGTH (DECL_NAME (fn)) != 6
2265                       : !lookup_attribute ("returns_nonnull",
2266                                                TYPE_ATTRIBUTES (fntype)))
2267                     warned = warning_at (loc, OPT_Walloc_zero,
2268                                              "argument %i value is zero",
2269                                              idx[i] + 1);
2270               }
2271             else if (tree_int_cst_lt (maxobjsize, args[i]))
2272               {
2273                 /* G++ emits calls to ::operator new[](SIZE_MAX) in C++98
2274                      mode and with -fno-exceptions as a way to indicate array
2275                      size overflow.  There's no good way to detect C++98 here
2276                      so avoid diagnosing these calls for all C++ modes.  */
2277                 if (i == 0
2278                       && fn
2279                       && !args[1]
2280                       && lang_GNU_CXX ()
2281                       && DECL_IS_OPERATOR_NEW_P (fn)
2282                       && integer_all_onesp (args[i]))
2283                     continue;
2284 
2285                 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2286                                            "argument %i value %qE exceeds "
2287                                            "maximum object size %E",
2288                                            idx[i] + 1, args[i], maxobjsize);
2289               }
2290           }
2291       else if (TREE_CODE (args[i]) == SSA_NAME
2292                  && get_size_range (args[i], argrange[i]))
2293           {
2294             /* Verify that the argument's range is not negative (including
2295                upper bound of zero).  */
2296             if (tree_int_cst_lt (argrange[i][0], integer_zero_node)
2297                 && tree_int_cst_le (argrange[i][1], integer_zero_node))
2298               {
2299                 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2300                                            "argument %i range [%E, %E] is negative",
2301                                            idx[i] + 1,
2302                                            argrange[i][0], argrange[i][1]);
2303               }
2304             else if (tree_int_cst_lt (maxobjsize, argrange[i][0]))
2305               {
2306                 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2307                                            "argument %i range [%E, %E] exceeds "
2308                                            "maximum object size %E",
2309                                            idx[i] + 1,
2310                                            argrange[i][0], argrange[i][1],
2311                                            maxobjsize);
2312               }
2313           }
2314     }
2315 
2316   if (!argrange[0][0])
2317     return;
2318 
2319   /* For a two-argument alloc_size, validate the product of the two
2320      arguments if both of their values or ranges are known.  */
2321   if (!warned && tree_fits_uhwi_p (argrange[0][0])
2322       && argrange[1][0] && tree_fits_uhwi_p (argrange[1][0])
2323       && !integer_onep (argrange[0][0])
2324       && !integer_onep (argrange[1][0]))
2325     {
2326       /* Check for overflow in the product of a function decorated with
2327            attribute alloc_size (X, Y).  */
2328       unsigned szprec = TYPE_PRECISION (size_type_node);
2329       wide_int x = wi::to_wide (argrange[0][0], szprec);
2330       wide_int y = wi::to_wide (argrange[1][0], szprec);
2331 
2332       wi::overflow_type vflow;
2333       wide_int prod = wi::umul (x, y, &vflow);
2334 
2335       if (vflow)
2336           warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2337                                    "product %<%E * %E%> of arguments %i and %i "
2338                                    "exceeds %<SIZE_MAX%>",
2339                                    argrange[0][0], argrange[1][0],
2340                                    idx[0] + 1, idx[1] + 1);
2341       else if (wi::ltu_p (wi::to_wide (maxobjsize, szprec), prod))
2342           warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2343                                    "product %<%E * %E%> of arguments %i and %i "
2344                                    "exceeds maximum object size %E",
2345                                    argrange[0][0], argrange[1][0],
2346                                    idx[0] + 1, idx[1] + 1,
2347                                    maxobjsize);
2348 
2349       if (warned)
2350           {
2351             /* Print the full range of each of the two arguments to make
2352                it clear when it is, in fact, in a range and not constant.  */
2353             if (argrange[0][0] != argrange [0][1])
2354               inform (loc, "argument %i in the range [%E, %E]",
2355                         idx[0] + 1, argrange[0][0], argrange[0][1]);
2356             if (argrange[1][0] != argrange [1][1])
2357               inform (loc, "argument %i in the range [%E, %E]",
2358                         idx[1] + 1, argrange[1][0], argrange[1][1]);
2359           }
2360     }
2361 
2362   if (warned && fn)
2363     {
2364       location_t fnloc = DECL_SOURCE_LOCATION (fn);
2365 
2366       if (DECL_IS_UNDECLARED_BUILTIN (fn))
2367           inform (loc,
2368                     "in a call to built-in allocation function %qD", fn);
2369       else
2370           inform (fnloc,
2371                     "in a call to allocation function %qD declared here", fn);
2372     }
2373 }
2374 
2375 /* Check a call to an alloca function for an excessive size.  */
2376 
2377 void
check_alloca(gcall * stmt)2378 pass_waccess::check_alloca (gcall *stmt)
2379 {
2380   if (m_early_checks_p)
2381     return;
2382 
2383   if ((warn_vla_limit >= HOST_WIDE_INT_MAX
2384        && warn_alloc_size_limit < warn_vla_limit)
2385       || (warn_alloca_limit >= HOST_WIDE_INT_MAX
2386             && warn_alloc_size_limit < warn_alloca_limit))
2387     {
2388       /* -Walloca-larger-than and -Wvla-larger-than settings of less
2389            than  HWI_MAX override the more general -Walloc-size-larger-than
2390            so unless either of the former options is smaller than the last
2391            one (which would imply that the call was already checked), check
2392            the alloca arguments for overflow.  */
2393       const tree alloc_args[] = { call_arg (stmt, 0), NULL_TREE };
2394       const int idx[] = { 0, -1 };
2395       maybe_warn_alloc_args_overflow (stmt, alloc_args, idx);
2396     }
2397 }
2398 
2399 /* Check a call to an allocation function for an excessive size.  */
2400 
2401 void
check_alloc_size_call(gcall * stmt)2402 pass_waccess::check_alloc_size_call (gcall *stmt)
2403 {
2404   if (m_early_checks_p)
2405     return;
2406 
2407   if (gimple_call_num_args (stmt) < 1)
2408     /* Avoid invalid calls to functions without a prototype.  */
2409     return;
2410 
2411   tree fndecl = gimple_call_fndecl (stmt);
2412   if (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
2413     {
2414       /* Alloca is handled separately.  */
2415       switch (DECL_FUNCTION_CODE (fndecl))
2416           {
2417           case BUILT_IN_ALLOCA:
2418           case BUILT_IN_ALLOCA_WITH_ALIGN:
2419           case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
2420             return;
2421           default:
2422             break;
2423           }
2424     }
2425 
2426   tree fntype = gimple_call_fntype (stmt);
2427   tree fntypeattrs = TYPE_ATTRIBUTES (fntype);
2428 
2429   tree alloc_size = lookup_attribute ("alloc_size", fntypeattrs);
2430   if (!alloc_size)
2431     return;
2432 
2433   /* Extract attribute alloc_size from the type of the called expression
2434      (which could be a function or a function pointer) and if set, store
2435      the indices of the corresponding arguments in ALLOC_IDX, and then
2436      the actual argument(s) at those indices in ALLOC_ARGS.  */
2437   int idx[2] = { -1, -1 };
2438   tree alloc_args[] = { NULL_TREE, NULL_TREE };
2439   unsigned nargs = gimple_call_num_args (stmt);
2440 
2441   tree args = TREE_VALUE (alloc_size);
2442   idx[0] = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1;
2443   /* Avoid invalid calls to functions without a prototype.  */
2444   if ((unsigned) idx[0] >= nargs)
2445     return;
2446   alloc_args[0] = call_arg (stmt, idx[0]);
2447   if (TREE_CHAIN (args))
2448     {
2449       idx[1] = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1;
2450       if ((unsigned) idx[1] >= nargs)
2451           return;
2452       alloc_args[1] = call_arg (stmt, idx[1]);
2453     }
2454 
2455   maybe_warn_alloc_args_overflow (stmt, alloc_args, idx);
2456 }
2457 
2458 /* Check a call STMT to strcat() for overflow and warn if it does.  */
2459 
2460 void
check_strcat(gcall * stmt)2461 pass_waccess::check_strcat (gcall *stmt)
2462 {
2463   if (m_early_checks_p)
2464     return;
2465 
2466   if (!warn_stringop_overflow && !warn_stringop_overread)
2467     return;
2468 
2469   tree dest = call_arg (stmt, 0);
2470   tree src = call_arg (stmt, 1);
2471 
2472   /* There is no way here to determine the length of the string in
2473      the destination to which the SRC string is being appended so
2474      just diagnose cases when the source string is longer than
2475      the destination object.  */
2476   access_data data (m_ptr_qry.rvals, stmt, access_read_write, NULL_TREE,
2477                         true, NULL_TREE, true);
2478   const int ost = warn_stringop_overflow ? warn_stringop_overflow - 1 : 1;
2479   compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
2480   tree destsize = compute_objsize (dest, stmt, ost, &data.dst, &m_ptr_qry);
2481 
2482   check_access (stmt, /*dstwrite=*/NULL_TREE, /*maxread=*/NULL_TREE,
2483                     src, destsize, data.mode, &data, m_ptr_qry.rvals);
2484 }
2485 
2486 /* Check a call STMT to strcat() for overflow and warn if it does.  */
2487 
2488 void
check_strncat(gcall * stmt)2489 pass_waccess::check_strncat (gcall *stmt)
2490 {
2491   if (m_early_checks_p)
2492     return;
2493 
2494   if (!warn_stringop_overflow && !warn_stringop_overread)
2495     return;
2496 
2497   tree dest = call_arg (stmt, 0);
2498   tree src = call_arg (stmt, 1);
2499   /* The upper bound on the number of bytes to write.  */
2500   tree maxread = call_arg (stmt, 2);
2501 
2502   /* Detect unterminated source (only).  */
2503   if (!check_nul_terminated_array (stmt, src, maxread))
2504     return;
2505 
2506   /* The length of the source sequence.  */
2507   tree slen = c_strlen (src, 1);
2508 
2509   /* Try to determine the range of lengths that the source expression
2510      refers to.  Since the lengths are only used for warning and not
2511      for code generation disable strict mode below.  */
2512   tree maxlen = slen;
2513   if (!maxlen)
2514     {
2515       c_strlen_data lendata = { };
2516       get_range_strlen (src, &lendata, /* eltsize = */ 1);
2517       maxlen = lendata.maxbound;
2518     }
2519 
2520   access_data data (m_ptr_qry.rvals, stmt, access_read_write);
2521   /* Try to verify that the destination is big enough for the shortest
2522      string.  First try to determine the size of the destination object
2523      into which the source is being copied.  */
2524   const int ost = warn_stringop_overflow - 1;
2525   tree destsize = compute_objsize (dest, stmt, ost, &data.dst, &m_ptr_qry);
2526 
2527   /* Add one for the terminating nul.  */
2528   tree srclen = (maxlen
2529                      ? fold_build2 (PLUS_EXPR, size_type_node, maxlen,
2530                                         size_one_node)
2531                      : NULL_TREE);
2532 
2533   /* The strncat function copies at most MAXREAD bytes and always appends
2534      the terminating nul so the specified upper bound should never be equal
2535      to (or greater than) the size of the destination.  */
2536   if (tree_fits_uhwi_p (maxread) && tree_fits_uhwi_p (destsize)
2537       && tree_int_cst_equal (destsize, maxread))
2538     {
2539       location_t loc = get_location (stmt);
2540       warning_at (loc, OPT_Wstringop_overflow_,
2541                       "%qD specified bound %E equals destination size",
2542                       get_callee_fndecl (stmt), maxread);
2543 
2544       return;
2545     }
2546 
2547   if (!srclen
2548       || (maxread && tree_fits_uhwi_p (maxread)
2549             && tree_fits_uhwi_p (srclen)
2550             && tree_int_cst_lt (maxread, srclen)))
2551     srclen = maxread;
2552 
2553   check_access (stmt, /*dstwrite=*/NULL_TREE, maxread, srclen,
2554                     destsize, data.mode, &data, m_ptr_qry.rvals);
2555 }
2556 
2557 /* Check a call STMT to stpcpy() or strcpy() for overflow and warn
2558    if it does.  */
2559 
2560 void
check_stxcpy(gcall * stmt)2561 pass_waccess::check_stxcpy (gcall *stmt)
2562 {
2563   if (m_early_checks_p)
2564     return;
2565 
2566   tree dst = call_arg (stmt, 0);
2567   tree src = call_arg (stmt, 1);
2568 
2569   tree size;
2570   bool exact;
2571   if (tree nonstr = unterminated_array (src, &size, &exact))
2572     {
2573       /* NONSTR refers to the non-nul terminated constant array.  */
2574       warn_string_no_nul (get_location (stmt), stmt, NULL, src, nonstr,
2575                                 size, exact);
2576       return;
2577     }
2578 
2579   if (warn_stringop_overflow)
2580     {
2581       access_data data (m_ptr_qry.rvals, stmt, access_read_write, NULL_TREE,
2582                               true, NULL_TREE, true);
2583       const int ost = warn_stringop_overflow ? warn_stringop_overflow - 1 : 1;
2584       compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
2585       tree dstsize = compute_objsize (dst, stmt, ost, &data.dst, &m_ptr_qry);
2586       check_access (stmt, /*dstwrite=*/ NULL_TREE,
2587                         /*maxread=*/ NULL_TREE, /*srcstr=*/ src,
2588                         dstsize, data.mode, &data, m_ptr_qry.rvals);
2589     }
2590 
2591   /* Check to see if the argument was declared attribute nonstring
2592      and if so, issue a warning since at this point it's not known
2593      to be nul-terminated.  */
2594   tree fndecl = get_callee_fndecl (stmt);
2595   maybe_warn_nonstring_arg (fndecl, stmt);
2596 }
2597 
2598 /* Check a call STMT to stpncpy() or strncpy() for overflow and warn
2599    if it does.  */
2600 
2601 void
check_stxncpy(gcall * stmt)2602 pass_waccess::check_stxncpy (gcall *stmt)
2603 {
2604   if (m_early_checks_p || !warn_stringop_overflow)
2605     return;
2606 
2607   tree dst = call_arg (stmt, 0);
2608   tree src = call_arg (stmt, 1);
2609   /* The number of bytes to write (not the maximum).  */
2610   tree len = call_arg (stmt, 2);
2611 
2612   access_data data (m_ptr_qry.rvals, stmt, access_read_write, len, true, len,
2613                         true);
2614   const int ost = warn_stringop_overflow ? warn_stringop_overflow - 1 : 1;
2615   compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
2616   tree dstsize = compute_objsize (dst, stmt, ost, &data.dst, &m_ptr_qry);
2617 
2618   check_access (stmt, /*dstwrite=*/len, /*maxread=*/len, src, dstsize,
2619                     data.mode, &data, m_ptr_qry.rvals);
2620 }
2621 
2622 /* Check a call STMT to stpncpy() or strncpy() for overflow and warn
2623    if it does.  */
2624 
2625 void
check_strncmp(gcall * stmt)2626 pass_waccess::check_strncmp (gcall *stmt)
2627 {
2628   if (m_early_checks_p || !warn_stringop_overread)
2629     return;
2630 
2631   tree arg1 = call_arg (stmt, 0);
2632   tree arg2 = call_arg (stmt, 1);
2633   tree bound = call_arg (stmt, 2);
2634 
2635   /* First check each argument separately, considering the bound.  */
2636   if (!check_nul_terminated_array (stmt, arg1, bound)
2637       || !check_nul_terminated_array (stmt, arg2, bound))
2638     return;
2639 
2640   /* A strncmp read from each argument is constrained not just by
2641      the bound but also by the length of the shorter string.  Specifying
2642      a bound that's larger than the size of either array makes no sense
2643      and is likely a bug.  When the length of neither of the two strings
2644      is known but the sizes of both of the arrays they are stored in is,
2645      issue a warning if the bound is larger than the size of
2646      the larger of the two arrays.  */
2647 
2648   c_strlen_data lendata1{ }, lendata2{ };
2649   tree len1 = c_strlen (arg1, 1, &lendata1);
2650   tree len2 = c_strlen (arg2, 1, &lendata2);
2651 
2652   if (len1 && TREE_CODE (len1) != INTEGER_CST)
2653     len1 = NULL_TREE;
2654   if (len2 && TREE_CODE (len2) != INTEGER_CST)
2655     len2 = NULL_TREE;
2656 
2657   if (len1 && len2)
2658     /* If the length of both arguments was computed they must both be
2659        nul-terminated and no further checking is necessary regardless
2660        of the bound.  */
2661     return;
2662 
2663   /* Check to see if the argument was declared with attribute nonstring
2664      and if so, issue a warning since at this point it's not known to be
2665      nul-terminated.  */
2666   if (maybe_warn_nonstring_arg (get_callee_fndecl (stmt), stmt))
2667     return;
2668 
2669   access_data adata1 (m_ptr_qry.rvals, stmt, access_read_only, NULL_TREE, false,
2670                           bound, true);
2671   access_data adata2 (m_ptr_qry.rvals, stmt, access_read_only, NULL_TREE, false,
2672                           bound, true);
2673 
2674   /* Determine the range of the bound first and bail if it fails; it's
2675      cheaper than computing the size of the objects.  */
2676   tree bndrng[2] = { NULL_TREE, NULL_TREE };
2677   get_size_range (m_ptr_qry.rvals, bound, stmt, bndrng, adata1.src_bndrng);
2678   if (!bndrng[0] || integer_zerop (bndrng[0]))
2679     return;
2680 
2681   if (len1 && tree_int_cst_lt (len1, bndrng[0]))
2682     bndrng[0] = len1;
2683   if (len2 && tree_int_cst_lt (len2, bndrng[0]))
2684     bndrng[0] = len2;
2685 
2686   /* compute_objsize almost never fails (and ultimately should never
2687      fail).  Don't bother to handle the rare case when it does.  */
2688   if (!compute_objsize (arg1, stmt, 1, &adata1.src, &m_ptr_qry)
2689       || !compute_objsize (arg2, stmt, 1, &adata2.src, &m_ptr_qry))
2690     return;
2691 
2692   /* Compute the size of the remaining space in each array after
2693      subtracting any offset into it.  */
2694   offset_int rem1 = adata1.src.size_remaining ();
2695   offset_int rem2 = adata2.src.size_remaining ();
2696 
2697   /* Cap REM1 and REM2 at the other if the other's argument is known
2698      to be an unterminated array, either because there's no space
2699      left in it after adding its offset or because it's constant and
2700      has no nul.  */
2701   if (rem1 == 0 || (rem1 < rem2 && lendata1.decl))
2702     rem2 = rem1;
2703   else if (rem2 == 0 || (rem2 < rem1 && lendata2.decl))
2704     rem1 = rem2;
2705 
2706   /* Point PAD at the array to reference in the note if a warning
2707      is issued.  */
2708   access_data *pad = len1 ? &adata2 : &adata1;
2709   offset_int maxrem = wi::max (rem1, rem2, UNSIGNED);
2710   if (lendata1.decl || lendata2.decl
2711       || maxrem < wi::to_offset (bndrng[0]))
2712     {
2713       /* Warn when either argument isn't nul-terminated or the maximum
2714            remaining space in the two arrays is less than the bound.  */
2715       tree func = get_callee_fndecl (stmt);
2716       location_t loc = gimple_location (stmt);
2717       maybe_warn_for_bound (OPT_Wstringop_overread, loc, stmt, func,
2718                                   bndrng, wide_int_to_tree (sizetype, maxrem),
2719                                   pad);
2720     }
2721 }
2722 
2723 /* Determine and check the sizes of the source and the destination
2724    of calls to __builtin_{bzero,memcpy,mempcpy,memset} calls.  STMT is
2725    the call statement, DEST is the destination argument, SRC is the source
2726    argument or null, and SIZE is the number of bytes being accessed.  Use
2727    Object Size type-0 regardless of the OPT_Wstringop_overflow_ setting.
2728    Return true on success (no overflow or invalid sizes), false otherwise.  */
2729 
2730 void
check_memop_access(gimple * stmt,tree dest,tree src,tree size)2731 pass_waccess::check_memop_access (gimple *stmt, tree dest, tree src, tree size)
2732 {
2733   if (m_early_checks_p)
2734     return;
2735 
2736   /* For functions like memset and memcpy that operate on raw memory
2737      try to determine the size of the largest source and destination
2738      object using type-0 Object Size regardless of the object size
2739      type specified by the option.  */
2740   access_data data (m_ptr_qry.rvals, stmt, access_read_write);
2741   tree srcsize
2742     = src ? compute_objsize (src, stmt, 0, &data.src, &m_ptr_qry) : NULL_TREE;
2743   tree dstsize = compute_objsize (dest, stmt, 0, &data.dst, &m_ptr_qry);
2744 
2745   check_access (stmt, size, /*maxread=*/NULL_TREE, srcsize, dstsize,
2746                     data.mode, &data, m_ptr_qry.rvals);
2747 }
2748 
2749 /* A convenience wrapper for check_access to check access by a read-only
2750    function like puts or strcmp.  */
2751 
2752 void
check_read_access(gimple * stmt,tree src,tree bound,int ost)2753 pass_waccess::check_read_access (gimple *stmt, tree src,
2754                                          tree bound /* = NULL_TREE */,
2755                                          int ost /* = 1 */)
2756 {
2757   if (m_early_checks_p || !warn_stringop_overread)
2758     return;
2759 
2760   if (bound && !useless_type_conversion_p (size_type_node, TREE_TYPE (bound)))
2761     bound = fold_convert (size_type_node, bound);
2762 
2763   tree fndecl = get_callee_fndecl (stmt);
2764   maybe_warn_nonstring_arg (fndecl, stmt);
2765 
2766   access_data data (m_ptr_qry.rvals, stmt, access_read_only, NULL_TREE,
2767                        false, bound, true);
2768   compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
2769   check_access (stmt, /*dstwrite=*/ NULL_TREE, /*maxread=*/ bound,
2770                     /*srcstr=*/ src, /*dstsize=*/ NULL_TREE, data.mode,
2771                     &data, m_ptr_qry.rvals);
2772 }
2773 
2774 /* Return true if memory model ORD is constant in the context of STMT and
2775    set *CSTVAL to the constant value.  Otherwise return false.  Warn for
2776    invalid ORD.  */
2777 
2778 bool
memmodel_to_uhwi(tree ord,gimple * stmt,unsigned HOST_WIDE_INT * cstval)2779 memmodel_to_uhwi (tree ord, gimple *stmt, unsigned HOST_WIDE_INT *cstval)
2780 {
2781   unsigned HOST_WIDE_INT val;
2782 
2783   if (TREE_CODE (ord) == INTEGER_CST)
2784     {
2785       if (!tree_fits_uhwi_p (ord))
2786           return false;
2787       val = tree_to_uhwi (ord);
2788     }
2789   else
2790     {
2791       /* Use the range query to determine constant values in the absence
2792            of constant propagation (such as at -O0).  */
2793       value_range rng;
2794       if (!get_range_query (cfun)->range_of_expr (rng, ord, stmt)
2795             || !rng.constant_p ()
2796             || !rng.singleton_p (&ord))
2797           return false;
2798 
2799       wide_int lob = rng.lower_bound ();
2800       if (!wi::fits_uhwi_p (lob))
2801           return false;
2802 
2803       val = lob.to_shwi ();
2804     }
2805 
2806   if (targetm.memmodel_check)
2807     /* This might warn for an invalid VAL but return a conservatively
2808        valid result.  */
2809     val = targetm.memmodel_check (val);
2810   else if (val & ~MEMMODEL_MASK)
2811     {
2812       tree fndecl = gimple_call_fndecl (stmt);
2813       location_t loc = gimple_location (stmt);
2814       loc = expansion_point_location_if_in_system_header (loc);
2815 
2816       warning_at (loc, OPT_Winvalid_memory_model,
2817                       "unknown architecture specifier in memory model "
2818                       "%wi for %qD", val, fndecl);
2819       return false;
2820     }
2821 
2822   *cstval = val;
2823 
2824   return true;
2825 }
2826 
2827 /* Valid memory model for each set of atomic built-in functions.  */
2828 
2829 struct memmodel_pair
2830 {
2831   memmodel modval;
2832   const char* modname;
2833 
2834 #define MEMMODEL_PAIR(val, str)                             \
2835   { MEMMODEL_ ## val, "memory_order_" str }
2836 };
2837 
2838 /* Valid memory models in the order of increasing strength.  */
2839 
2840 static const memmodel_pair memory_models[] =
2841   { MEMMODEL_PAIR (RELAXED, "relaxed"),
2842     MEMMODEL_PAIR (SEQ_CST, "seq_cst"),
2843     MEMMODEL_PAIR (ACQUIRE, "acquire"),
2844     MEMMODEL_PAIR (CONSUME, "consume"),
2845     MEMMODEL_PAIR (RELEASE, "release"),
2846     MEMMODEL_PAIR (ACQ_REL, "acq_rel")
2847   };
2848 
2849 /* Return the name of the memory model VAL.  */
2850 
2851 static const char*
memmodel_name(unsigned HOST_WIDE_INT val)2852 memmodel_name (unsigned HOST_WIDE_INT val)
2853 {
2854   val = memmodel_base (val);
2855 
2856   for (unsigned i = 0; i != sizeof memory_models / sizeof *memory_models; ++i)
2857     {
2858       if (val == memory_models[i].modval)
2859           return memory_models[i].modname;
2860     }
2861   return NULL;
2862 }
2863 
2864 /* Indices of valid MEMORY_MODELS above for corresponding atomic operations.  */
2865 static const unsigned char load_models[] = { 0, 1, 2, 3, UCHAR_MAX };
2866 static const unsigned char store_models[] = { 0, 1, 4, UCHAR_MAX };
2867 static const unsigned char xchg_models[] = { 0, 1, 3, 4, 5, UCHAR_MAX };
2868 static const unsigned char flag_clr_models[] = { 0, 1, 4, UCHAR_MAX };
2869 static const unsigned char all_models[] = { 0, 1, 2, 3, 4, 5, UCHAR_MAX };
2870 
2871 /* Check the success memory model argument ORD_SUCS to the call STMT to
2872    an atomic function and warn if it's invalid.  If nonnull, also check
2873    the failure memory model ORD_FAIL and warn if it's invalid.  Return
2874    true if a warning has been issued.  */
2875 
2876 bool
maybe_warn_memmodel(gimple * stmt,tree ord_sucs,tree ord_fail,const unsigned char * valid)2877 pass_waccess::maybe_warn_memmodel (gimple *stmt, tree ord_sucs,
2878                                            tree ord_fail, const unsigned char *valid)
2879 {
2880   unsigned HOST_WIDE_INT sucs, fail = 0;
2881   if (!memmodel_to_uhwi (ord_sucs, stmt, &sucs)
2882       || (ord_fail && !memmodel_to_uhwi (ord_fail, stmt, &fail)))
2883     return false;
2884 
2885   bool is_valid = false;
2886   if (valid)
2887     for (unsigned i = 0; valid[i] != UCHAR_MAX; ++i)
2888       {
2889           memmodel model = memory_models[valid[i]].modval;
2890           if (memmodel_base (sucs) == model)
2891             {
2892               is_valid = true;
2893               break;
2894             }
2895       }
2896   else
2897     is_valid = true;
2898 
2899   tree fndecl = gimple_call_fndecl (stmt);
2900   location_t loc = gimple_location (stmt);
2901   loc = expansion_point_location_if_in_system_header (loc);
2902 
2903   if (!is_valid)
2904     {
2905       bool warned = false;
2906       if (const char *modname = memmodel_name (sucs))
2907           warned = warning_at (loc, OPT_Winvalid_memory_model,
2908                                    "invalid memory model %qs for %qD",
2909                                    modname, fndecl);
2910       else
2911           warned = warning_at (loc, OPT_Winvalid_memory_model,
2912                                    "invalid memory model %wi for %qD",
2913                                    sucs, fndecl);
2914 
2915       if (!warned)
2916           return false;
2917 
2918       /* Print a note with the valid memory models.  */
2919       pretty_printer pp;
2920       pp_show_color (&pp) = pp_show_color (global_dc->printer);
2921       for (unsigned i = 0; valid[i] != UCHAR_MAX; ++i)
2922           {
2923             const char *modname = memory_models[valid[i]].modname;
2924             pp_printf (&pp, "%s%qs", i ? ", " : "", modname);
2925           }
2926 
2927       inform (loc, "valid models are %s", pp_formatted_text (&pp));
2928       return true;
2929     }
2930 
2931   if (!ord_fail)
2932     return false;
2933 
2934   if (fail == MEMMODEL_RELEASE || fail == MEMMODEL_ACQ_REL)
2935     if (const char *failname = memmodel_name (fail))
2936       {
2937           /* If both memory model arguments are valid but their combination
2938              is not, use their names in the warning.  */
2939           if (!warning_at (loc, OPT_Winvalid_memory_model,
2940                                "invalid failure memory model %qs for %qD",
2941                                failname, fndecl))
2942             return false;
2943 
2944           inform (loc,
2945                     "valid failure models are %qs, %qs, %qs, %qs",
2946                     "memory_order_relaxed", "memory_order_seq_cst",
2947                     "memory_order_acquire", "memory_order_consume");
2948           return true;
2949       }
2950 
2951   if (memmodel_base (fail) <= memmodel_base (sucs))
2952     return false;
2953 
2954   if (const char *sucsname = memmodel_name (sucs))
2955     if (const char *failname = memmodel_name (fail))
2956       {
2957           /* If both memory model arguments are valid but their combination
2958              is not, use their names in the warning.  */
2959           if (!warning_at (loc, OPT_Winvalid_memory_model,
2960                                "failure memory model %qs cannot be stronger "
2961                                "than success memory model %qs for %qD",
2962                                failname, sucsname, fndecl))
2963             return false;
2964 
2965           /* Print a note with the valid failure memory models which are
2966              those with a value less than or equal to the success mode.  */
2967           char buf[120];
2968           *buf = '\0';
2969           for (unsigned i = 0;
2970                memory_models[i].modval <= memmodel_base (sucs); ++i)
2971             {
2972               if (*buf)
2973                 strcat (buf, ", ");
2974 
2975               const char *modname = memory_models[valid[i]].modname;
2976               sprintf (buf + strlen (buf), "'%s'", modname);
2977             }
2978 
2979           inform (loc, "valid models are %s", buf);
2980           return true;
2981       }
2982 
2983   /* If either memory model argument value is invalid use the numerical
2984      value of both in the message.  */
2985   return warning_at (loc, OPT_Winvalid_memory_model,
2986                          "failure memory model %wi cannot be stronger "
2987                          "than success memory model %wi for %qD",
2988                          fail, sucs, fndecl);
2989 }
2990 
2991 /* Wrapper for the above.  */
2992 
2993 void
check_atomic_memmodel(gimple * stmt,tree ord_sucs,tree ord_fail,const unsigned char * valid)2994 pass_waccess::check_atomic_memmodel (gimple *stmt, tree ord_sucs,
2995                                              tree ord_fail, const unsigned char *valid)
2996 {
2997   if (warning_suppressed_p (stmt, OPT_Winvalid_memory_model))
2998     return;
2999 
3000   if (!maybe_warn_memmodel (stmt, ord_sucs, ord_fail, valid))
3001     return;
3002 
3003   suppress_warning (stmt, OPT_Winvalid_memory_model);
3004 }
3005 
3006 /* Check a call STMT to an atomic or sync built-in.  */
3007 
3008 bool
check_atomic_builtin(gcall * stmt)3009 pass_waccess::check_atomic_builtin (gcall *stmt)
3010 {
3011   tree callee = gimple_call_fndecl (stmt);
3012   if (!callee)
3013     return false;
3014 
3015   /* The size in bytes of the access by the function, and the number
3016      of the second argument to check (if any).  */
3017   unsigned bytes = 0, arg2 = UINT_MAX;
3018   unsigned sucs_arg = UINT_MAX, fail_arg = UINT_MAX;
3019   /* Points to the array of indices of valid memory models.  */
3020   const unsigned char *pvalid_models = NULL;
3021 
3022   switch (DECL_FUNCTION_CODE (callee))
3023     {
3024 #define BUILTIN_ACCESS_SIZE_FNSPEC(N)                       \
3025       BUILT_IN_SYNC_FETCH_AND_ADD_ ## N:                    \
3026     case BUILT_IN_SYNC_FETCH_AND_SUB_ ## N:                 \
3027     case BUILT_IN_SYNC_FETCH_AND_OR_ ## N:                  \
3028     case BUILT_IN_SYNC_FETCH_AND_AND_ ## N:                 \
3029     case BUILT_IN_SYNC_FETCH_AND_XOR_ ## N:                 \
3030     case BUILT_IN_SYNC_FETCH_AND_NAND_ ## N:                \
3031     case BUILT_IN_SYNC_ADD_AND_FETCH_ ## N:                 \
3032     case BUILT_IN_SYNC_SUB_AND_FETCH_ ## N:                 \
3033     case BUILT_IN_SYNC_OR_AND_FETCH_ ## N:                  \
3034     case BUILT_IN_SYNC_AND_AND_FETCH_ ## N:                 \
3035     case BUILT_IN_SYNC_XOR_AND_FETCH_ ## N:                 \
3036     case BUILT_IN_SYNC_NAND_AND_FETCH_ ## N:                \
3037     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_ ## N:             \
3038     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_ ## N:         \
3039     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_ ## N:          \
3040     case BUILT_IN_SYNC_LOCK_RELEASE_ ## N:                  \
3041       bytes = N;                                            \
3042       break;                                                          \
3043     case BUILT_IN_ATOMIC_LOAD_ ## N:                        \
3044       pvalid_models = load_models;                          \
3045       sucs_arg = 1;                                         \
3046       /* FALLTHROUGH */                                               \
3047     case BUILT_IN_ATOMIC_STORE_ ## N:                       \
3048       if (!pvalid_models)                                   \
3049           pvalid_models = store_models;                     \
3050       /* FALLTHROUGH */                                               \
3051     case BUILT_IN_ATOMIC_ADD_FETCH_ ## N:                   \
3052     case BUILT_IN_ATOMIC_SUB_FETCH_ ## N:                   \
3053     case BUILT_IN_ATOMIC_AND_FETCH_ ## N:                   \
3054     case BUILT_IN_ATOMIC_NAND_FETCH_ ## N:                  \
3055     case BUILT_IN_ATOMIC_XOR_FETCH_ ## N:                   \
3056     case BUILT_IN_ATOMIC_OR_FETCH_ ## N:                    \
3057     case BUILT_IN_ATOMIC_FETCH_ADD_ ## N:                   \
3058     case BUILT_IN_ATOMIC_FETCH_SUB_ ## N:                   \
3059     case BUILT_IN_ATOMIC_FETCH_AND_ ## N:                   \
3060     case BUILT_IN_ATOMIC_FETCH_NAND_ ## N:                  \
3061     case BUILT_IN_ATOMIC_FETCH_OR_ ## N:                    \
3062     case BUILT_IN_ATOMIC_FETCH_XOR_ ## N:                   \
3063           bytes = N;                                                  \
3064           if (sucs_arg == UINT_MAX)                         \
3065             sucs_arg = 2;                                             \
3066           if (!pvalid_models)                               \
3067             pvalid_models = all_models;                     \
3068           break;                                                      \
3069     case BUILT_IN_ATOMIC_EXCHANGE_ ## N:                    \
3070           bytes = N;                                                  \
3071           sucs_arg = 3;                                               \
3072           pvalid_models = xchg_models;                      \
3073           break;                                                      \
3074     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_ ## N:  \
3075           bytes = N;                                                  \
3076           sucs_arg = 4;                                               \
3077           fail_arg = 5;                                               \
3078           pvalid_models = all_models;                       \
3079           arg2 = 1
3080 
3081     case BUILTIN_ACCESS_SIZE_FNSPEC (1);
3082       break;
3083     case BUILTIN_ACCESS_SIZE_FNSPEC (2);
3084       break;
3085     case BUILTIN_ACCESS_SIZE_FNSPEC (4);
3086       break;
3087     case BUILTIN_ACCESS_SIZE_FNSPEC (8);
3088       break;
3089     case BUILTIN_ACCESS_SIZE_FNSPEC (16);
3090       break;
3091 
3092     case BUILT_IN_ATOMIC_CLEAR:
3093       sucs_arg = 1;
3094       pvalid_models = flag_clr_models;
3095       break;
3096 
3097     default:
3098       return false;
3099     }
3100 
3101   unsigned nargs = gimple_call_num_args (stmt);
3102   if (sucs_arg < nargs)
3103     {
3104       tree ord_sucs = gimple_call_arg (stmt, sucs_arg);
3105       tree ord_fail = NULL_TREE;
3106       if (fail_arg < nargs)
3107           ord_fail = gimple_call_arg (stmt, fail_arg);
3108       check_atomic_memmodel (stmt, ord_sucs, ord_fail, pvalid_models);
3109     }
3110 
3111   if (!bytes)
3112     return true;
3113 
3114   tree size = build_int_cstu (sizetype, bytes);
3115   tree dst = gimple_call_arg (stmt, 0);
3116   check_memop_access (stmt, dst, NULL_TREE, size);
3117 
3118   if (arg2 != UINT_MAX)
3119     {
3120       tree dst = gimple_call_arg (stmt, arg2);
3121       check_memop_access (stmt, dst, NULL_TREE, size);
3122     }
3123 
3124   return true;
3125 }
3126 
3127 /* Check call STMT to a built-in function for invalid accesses.  Return
3128    true if a call has been handled.  */
3129 
3130 bool
check_builtin(gcall * stmt)3131 pass_waccess::check_builtin (gcall *stmt)
3132 {
3133   tree callee = gimple_call_fndecl (stmt);
3134   if (!callee)
3135     return false;
3136 
3137   switch (DECL_FUNCTION_CODE (callee))
3138     {
3139     case BUILT_IN_ALLOCA:
3140     case BUILT_IN_ALLOCA_WITH_ALIGN:
3141     case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
3142       check_alloca (stmt);
3143       return true;
3144 
3145     case BUILT_IN_EXECL:
3146     case BUILT_IN_EXECLE:
3147     case BUILT_IN_EXECLP:
3148     case BUILT_IN_EXECV:
3149     case BUILT_IN_EXECVE:
3150     case BUILT_IN_EXECVP:
3151       check_read_access (stmt, call_arg (stmt, 0));
3152       return true;
3153 
3154     case BUILT_IN_FREE:
3155     case BUILT_IN_REALLOC:
3156       if (!m_early_checks_p)
3157           {
3158             tree arg = call_arg (stmt, 0);
3159             if (TREE_CODE (arg) == SSA_NAME)
3160               check_pointer_uses (stmt, arg);
3161           }
3162       return true;
3163 
3164     case BUILT_IN_GETTEXT:
3165     case BUILT_IN_PUTS:
3166     case BUILT_IN_PUTS_UNLOCKED:
3167     case BUILT_IN_STRDUP:
3168       check_read_access (stmt, call_arg (stmt, 0));
3169       return true;
3170 
3171     case BUILT_IN_INDEX:
3172     case BUILT_IN_RINDEX:
3173     case BUILT_IN_STRCHR:
3174     case BUILT_IN_STRRCHR:
3175     case BUILT_IN_STRLEN:
3176       check_read_access (stmt, call_arg (stmt, 0));
3177       return true;
3178 
3179     case BUILT_IN_FPUTS:
3180     case BUILT_IN_FPUTS_UNLOCKED:
3181       check_read_access (stmt, call_arg (stmt, 0));
3182       return true;
3183 
3184     case BUILT_IN_STRNDUP:
3185     case BUILT_IN_STRNLEN:
3186       {
3187           tree str = call_arg (stmt, 0);
3188           tree len = call_arg (stmt, 1);
3189           check_read_access (stmt, str, len);
3190           return true;
3191       }
3192 
3193     case BUILT_IN_STRCAT:
3194       check_strcat (stmt);
3195       return true;
3196 
3197     case BUILT_IN_STRNCAT:
3198       check_strncat (stmt);
3199       return true;
3200 
3201     case BUILT_IN_STPCPY:
3202     case BUILT_IN_STRCPY:
3203       check_stxcpy (stmt);
3204       return true;
3205 
3206     case BUILT_IN_STPNCPY:
3207     case BUILT_IN_STRNCPY:
3208       check_stxncpy (stmt);
3209       return true;
3210 
3211     case BUILT_IN_STRCASECMP:
3212     case BUILT_IN_STRCMP:
3213     case BUILT_IN_STRPBRK:
3214     case BUILT_IN_STRSPN:
3215     case BUILT_IN_STRCSPN:
3216     case BUILT_IN_STRSTR:
3217       check_read_access (stmt, call_arg (stmt, 0));
3218       check_read_access (stmt, call_arg (stmt, 1));
3219       return true;
3220 
3221     case BUILT_IN_STRNCASECMP:
3222     case BUILT_IN_STRNCMP:
3223       check_strncmp (stmt);
3224       return true;
3225 
3226     case BUILT_IN_MEMCMP:
3227       {
3228           tree a1 = call_arg (stmt, 0);
3229           tree a2 = call_arg (stmt, 1);
3230           tree len = call_arg (stmt, 2);
3231           check_read_access (stmt, a1, len, 0);
3232           check_read_access (stmt, a2, len, 0);
3233           return true;
3234       }
3235 
3236     case BUILT_IN_MEMCPY:
3237     case BUILT_IN_MEMPCPY:
3238     case BUILT_IN_MEMMOVE:
3239       {
3240           tree dst = call_arg (stmt, 0);
3241           tree src = call_arg (stmt, 1);
3242           tree len = call_arg (stmt, 2);
3243           check_memop_access (stmt, dst, src, len);
3244           return true;
3245       }
3246 
3247     case BUILT_IN_MEMCHR:
3248       {
3249           tree src = call_arg (stmt, 0);
3250           tree len = call_arg (stmt, 2);
3251           check_read_access (stmt, src, len, 0);
3252           return true;
3253       }
3254 
3255     case BUILT_IN_MEMSET:
3256       {
3257           tree dst = call_arg (stmt, 0);
3258           tree len = call_arg (stmt, 2);
3259           check_memop_access (stmt, dst, NULL_TREE, len);
3260           return true;
3261       }
3262 
3263     default:
3264       if (check_atomic_builtin (stmt))
3265           return true;
3266       break;
3267     }
3268 
3269   return false;
3270 }
3271 
3272 /* Returns the type of the argument ARGNO to function with type FNTYPE
3273    or null when the type cannot be determined or no such argument exists.  */
3274 
3275 static tree
fntype_argno_type(tree fntype,unsigned argno)3276 fntype_argno_type (tree fntype, unsigned argno)
3277 {
3278   if (!prototype_p (fntype))
3279     return NULL_TREE;
3280 
3281   tree argtype;
3282   function_args_iterator it;
3283   FOREACH_FUNCTION_ARGS (fntype, argtype, it)
3284     if (argno-- == 0)
3285       return argtype;
3286 
3287   return NULL_TREE;
3288 }
3289 
3290 /* Helper to append the "human readable" attribute access specification
3291    described by ACCESS to the array ATTRSTR with size STRSIZE.  Used in
3292    diagnostics.  */
3293 
3294 static inline void
append_attrname(const std::pair<int,attr_access> & access,char * attrstr,size_t strsize)3295 append_attrname (const std::pair<int, attr_access> &access,
3296                      char *attrstr, size_t strsize)
3297 {
3298   if (access.second.internal_p)
3299     return;
3300 
3301   tree str = access.second.to_external_string ();
3302   gcc_assert (strsize >= (size_t) TREE_STRING_LENGTH (str));
3303   strcpy (attrstr, TREE_STRING_POINTER (str));
3304 }
3305 
3306 /* Iterate over attribute access read-only, read-write, and write-only
3307    arguments and diagnose past-the-end accesses and related problems
3308    in the function call EXP.  */
3309 
3310 void
maybe_check_access_sizes(rdwr_map * rwm,tree fndecl,tree fntype,gimple * stmt)3311 pass_waccess::maybe_check_access_sizes (rdwr_map *rwm, tree fndecl, tree fntype,
3312                                                   gimple *stmt)
3313 {
3314   if (warning_suppressed_p (stmt, OPT_Wnonnull)
3315       || warning_suppressed_p (stmt, OPT_Wstringop_overflow_))
3316     return;
3317 
3318   auto_diagnostic_group adg;
3319 
3320   /* Set if a warning has been issued for any argument (used to decide
3321      whether to emit an informational note at the end).  */
3322   opt_code opt_warned = no_warning;
3323 
3324   /* A string describing the attributes that the warnings issued by this
3325      function apply to.  Used to print one informational note per function
3326      call, rather than one per warning.  That reduces clutter.  */
3327   char attrstr[80];
3328   attrstr[0] = 0;
3329 
3330   for (rdwr_map::iterator it = rwm->begin (); it != rwm->end (); ++it)
3331     {
3332       std::pair<int, attr_access> access = *it;
3333 
3334       /* Get the function call arguments corresponding to the attribute's
3335            positional arguments.  When both arguments have been specified
3336            there will be two entries in *RWM, one for each.  They are
3337            cross-referenced by their respective argument numbers in
3338            ACCESS.PTRARG and ACCESS.SIZARG.  */
3339       const int ptridx = access.second.ptrarg;
3340       const int sizidx = access.second.sizarg;
3341 
3342       gcc_assert (ptridx != -1);
3343       gcc_assert (access.first == ptridx || access.first == sizidx);
3344 
3345       /* The pointer is set to null for the entry corresponding to
3346            the size argument.  Skip it.  It's handled when the entry
3347            corresponding to the pointer argument comes up.  */
3348       if (!access.second.ptr)
3349           continue;
3350 
3351       tree ptrtype = fntype_argno_type (fntype, ptridx);
3352       if (!ptrtype)
3353           /* A function with a prototype was redeclared without one and
3354              the prototype has been lost.  See pr102759.  Avoid dealing
3355              with this pathological case.  */
3356           return;
3357 
3358       tree argtype = TREE_TYPE (ptrtype);
3359 
3360       /* The size of the access by the call in elements.  */
3361       tree access_nelts;
3362       if (sizidx == -1)
3363           {
3364             /* If only the pointer attribute operand was specified and
3365                not size, set SIZE to the greater of MINSIZE or size of
3366                one element of the pointed to type to detect smaller
3367                objects (null pointers are diagnosed in this case only
3368                if the pointer is also declared with attribute nonnull.  */
3369             if (access.second.minsize
3370                 && access.second.minsize != HOST_WIDE_INT_M1U)
3371               access_nelts = build_int_cstu (sizetype, access.second.minsize);
3372             else if (VOID_TYPE_P (argtype) && access.second.mode == access_none)
3373               /* Treat access mode none on a void* argument as expecting
3374                  as little as zero bytes.  */
3375               access_nelts = size_zero_node;
3376             else
3377               access_nelts = size_one_node;
3378           }
3379       else
3380           access_nelts = rwm->get (sizidx)->size;
3381 
3382       /* Format the value or range to avoid an explosion of messages.  */
3383       char sizstr[80];
3384       tree sizrng[2] = { size_zero_node, build_all_ones_cst (sizetype) };
3385       if (get_size_range (m_ptr_qry.rvals, access_nelts, stmt, sizrng, 1))
3386           {
3387             char *s0 = print_generic_expr_to_str (sizrng[0]);
3388             if (tree_int_cst_equal (sizrng[0], sizrng[1]))
3389               {
3390                 gcc_checking_assert (strlen (s0) < sizeof sizstr);
3391                 strcpy (sizstr, s0);
3392               }
3393             else
3394               {
3395                 char *s1 = print_generic_expr_to_str (sizrng[1]);
3396                 gcc_checking_assert (strlen (s0) + strlen (s1)
3397                                            < sizeof sizstr - 4);
3398                 sprintf (sizstr, "[%.37s, %.37s]", s0, s1);
3399                 free (s1);
3400               }
3401             free (s0);
3402           }
3403       else
3404           *sizstr = '\0';
3405 
3406       /* Set if a warning has been issued for the current argument.  */
3407       opt_code arg_warned = no_warning;
3408       location_t loc = get_location (stmt);
3409       tree ptr = access.second.ptr;
3410       if (*sizstr
3411             && tree_int_cst_sgn (sizrng[0]) < 0
3412             && tree_int_cst_sgn (sizrng[1]) < 0)
3413           {
3414             /* Warn about negative sizes.  */
3415             if (access.second.internal_p)
3416               {
3417                 const std::string argtypestr
3418                     = access.second.array_as_string (ptrtype);
3419 
3420                 if (warning_at (loc, OPT_Wstringop_overflow_,
3421                                     "bound argument %i value %s is "
3422                                     "negative for a variable length array "
3423                                     "argument %i of type %s",
3424                                     sizidx + 1, sizstr,
3425                                     ptridx + 1, argtypestr.c_str ()))
3426                     arg_warned = OPT_Wstringop_overflow_;
3427               }
3428             else if (warning_at (loc, OPT_Wstringop_overflow_,
3429                                      "argument %i value %s is negative",
3430                                      sizidx + 1, sizstr))
3431               arg_warned = OPT_Wstringop_overflow_;
3432 
3433             if (arg_warned != no_warning)
3434               {
3435                 append_attrname (access, attrstr, sizeof attrstr);
3436                 /* Remember a warning has been issued and avoid warning
3437                      again below for the same attribute.  */
3438                 opt_warned = arg_warned;
3439                 continue;
3440               }
3441           }
3442 
3443       /* The size of the access by the call in bytes.  */
3444       tree access_size = NULL_TREE;
3445       if (tree_int_cst_sgn (sizrng[0]) >= 0)
3446           {
3447             if (COMPLETE_TYPE_P (argtype))
3448               {
3449                 /* Multiply ACCESS_SIZE by the size of the type the pointer
3450                      argument points to.  If it's incomplete the size is used
3451                      as is.  */
3452                 if (tree argsize = TYPE_SIZE_UNIT (argtype))
3453                     if (TREE_CODE (argsize) == INTEGER_CST)
3454                       {
3455                         const int prec = TYPE_PRECISION (sizetype);
3456                         wide_int minsize = wi::to_wide (sizrng[0], prec);
3457                         minsize *= wi::to_wide (argsize, prec);
3458                         access_size = wide_int_to_tree (sizetype, minsize);
3459                       }
3460               }
3461             else
3462               access_size = access_nelts;
3463           }
3464 
3465       if (integer_zerop (ptr))
3466           {
3467             if (sizidx >= 0 && tree_int_cst_sgn (sizrng[0]) > 0)
3468               {
3469                 /* Warn about null pointers with positive sizes.  This is
3470                      different from also declaring the pointer argument with
3471                      attribute nonnull when the function accepts null pointers
3472                      only when the corresponding size is zero.  */
3473                 if (access.second.internal_p)
3474                     {
3475                       const std::string argtypestr
3476                         = access.second.array_as_string (ptrtype);
3477 
3478                       if (warning_at (loc, OPT_Wnonnull,
3479                                           "argument %i of variable length "
3480                                           "array %s is null but "
3481                                           "the corresponding bound argument "
3482                                           "%i value is %s",
3483                                           ptridx + 1, argtypestr.c_str (),
3484                                           sizidx + 1, sizstr))
3485                         arg_warned = OPT_Wnonnull;
3486                     }
3487                 else if (warning_at (loc, OPT_Wnonnull,
3488                                            "argument %i is null but "
3489                                            "the corresponding size argument "
3490                                            "%i value is %s",
3491                                            ptridx + 1, sizidx + 1, sizstr))
3492                     arg_warned = OPT_Wnonnull;
3493               }
3494             else if (access_size && access.second.static_p)
3495               {
3496                 /* Warn about null pointers for [static N] array arguments
3497                      but do not warn for ordinary (i.e., nonstatic) arrays.  */
3498                 if (warning_at (loc, OPT_Wnonnull,
3499                                     "argument %i to %<%T[static %E]%> "
3500                                     "is null where non-null expected",
3501                                     ptridx + 1, argtype, access_nelts))
3502                     arg_warned = OPT_Wnonnull;
3503               }
3504 
3505             if (arg_warned != no_warning)
3506               {
3507                 append_attrname (access, attrstr, sizeof attrstr);
3508                 /* Remember a warning has been issued and avoid warning
3509                      again below for the same attribute.  */
3510                 opt_warned = OPT_Wnonnull;
3511                 continue;
3512               }
3513           }
3514 
3515       access_data data (m_ptr_qry.rvals, stmt, access.second.mode,
3516                               NULL_TREE, false, NULL_TREE, false);
3517       access_ref* const pobj = (access.second.mode == access_write_only
3518                                         ? &data.dst : &data.src);
3519       tree objsize = compute_objsize (ptr, stmt, 1, pobj, &m_ptr_qry);
3520 
3521       /* The size of the destination or source object.  */
3522       tree dstsize = NULL_TREE, srcsize = NULL_TREE;
3523       if (access.second.mode == access_read_only
3524             || access.second.mode == access_none)
3525           {
3526             /* For a read-only argument there is no destination.  For
3527                no access, set the source as well and differentiate via
3528                the access flag below.  */
3529             srcsize = objsize;
3530             if (access.second.mode == access_read_only
3531                 || access.second.mode == access_none)
3532               {
3533                 /* For a read-only attribute there is no destination so
3534                      clear OBJSIZE.  This emits "reading N bytes" kind of
3535                      diagnostics instead of the "writing N bytes" kind,
3536                      unless MODE is none.  */
3537                 objsize = NULL_TREE;
3538               }
3539           }
3540       else
3541           dstsize = objsize;
3542 
3543       /* Clear the no-warning bit in case it was set by check_access
3544            in a prior iteration so that accesses via different arguments
3545            are diagnosed.  */
3546       suppress_warning (stmt, OPT_Wstringop_overflow_, false);
3547       access_mode mode = data.mode;
3548       if (mode == access_deferred)
3549           mode = TYPE_READONLY (argtype) ? access_read_only : access_read_write;
3550       check_access (stmt, access_size, /*maxread=*/ NULL_TREE, srcsize,
3551                         dstsize, mode, &data, m_ptr_qry.rvals);
3552 
3553       if (warning_suppressed_p (stmt, OPT_Wstringop_overflow_))
3554           opt_warned = OPT_Wstringop_overflow_;
3555       if (opt_warned != no_warning)
3556           {
3557             if (access.second.internal_p)
3558               {
3559                 unsigned HOST_WIDE_INT nelts =
3560                     access_nelts ? access.second.minsize : HOST_WIDE_INT_M1U;
3561                 tree arrtype = build_printable_array_type (argtype, nelts);
3562                 inform (loc, "referencing argument %u of type %qT",
3563                           ptridx + 1, arrtype);
3564               }
3565             else
3566               /* If check_access issued a warning above, append the relevant
3567                  attribute to the string.  */
3568               append_attrname (access, attrstr, sizeof attrstr);
3569           }
3570     }
3571 
3572   if (*attrstr)
3573     {
3574       if (fndecl)
3575           inform (get_location (fndecl),
3576                     "in a call to function %qD declared with attribute %qs",
3577                     fndecl, attrstr);
3578       else
3579           inform (get_location (stmt),
3580                     "in a call with type %qT and attribute %qs",
3581                     fntype, attrstr);
3582     }
3583   else if (opt_warned != no_warning)
3584     {
3585       if (fndecl)
3586           inform (get_location (fndecl),
3587                     "in a call to function %qD", fndecl);
3588       else
3589           inform (get_location (stmt),
3590                     "in a call with type %qT", fntype);
3591     }
3592 
3593   /* Set the bit in case it was cleared and not set above.  */
3594   if (opt_warned != no_warning)
3595     suppress_warning (stmt, opt_warned);
3596 }
3597 
3598 /* Check call STMT to an ordinary (non-built-in) function for invalid
3599    accesses.  Return true if a call has been handled.  */
3600 
3601 bool
check_call_access(gcall * stmt)3602 pass_waccess::check_call_access (gcall *stmt)
3603 {
3604   tree fntype = gimple_call_fntype (stmt);
3605   if (!fntype)
3606     return false;
3607 
3608   tree fntypeattrs = TYPE_ATTRIBUTES (fntype);
3609   if (!fntypeattrs)
3610     return false;
3611 
3612   /* Map of attribute access specifications for function arguments.  */
3613   rdwr_map rdwr_idx;
3614   init_attr_rdwr_indices (&rdwr_idx, fntypeattrs);
3615 
3616   unsigned nargs = call_nargs (stmt);
3617   for (unsigned i = 0; i != nargs; ++i)
3618     {
3619       tree arg = call_arg (stmt, i);
3620 
3621       /* Save the actual argument that corresponds to the access attribute
3622            operand for later processing.  */
3623       if (attr_access *access = rdwr_idx.get (i))
3624           {
3625             if (POINTER_TYPE_P (TREE_TYPE (arg)))
3626               {
3627                 access->ptr = arg;
3628                 /* A nonnull ACCESS->SIZE contains VLA bounds.  */
3629               }
3630             else
3631               {
3632                 access->size = arg;
3633                 gcc_assert (access->ptr == NULL_TREE);
3634               }
3635           }
3636     }
3637 
3638   /* Check attribute access arguments.  */
3639   tree fndecl = gimple_call_fndecl (stmt);
3640   maybe_check_access_sizes (&rdwr_idx, fndecl, fntype, stmt);
3641 
3642   check_alloc_size_call (stmt);
3643   return true;
3644 }
3645 
3646 /* Check arguments in a call STMT for attribute nonstring.  */
3647 
3648 static void
check_nonstring_args(gcall * stmt)3649 check_nonstring_args (gcall *stmt)
3650 {
3651   tree fndecl = gimple_call_fndecl (stmt);
3652 
3653   /* Detect passing non-string arguments to functions expecting
3654      nul-terminated strings.  */
3655   maybe_warn_nonstring_arg (fndecl, stmt);
3656 }
3657 
3658 /* Issue a warning if a deallocation function such as free, realloc,
3659    or C++ operator delete is called with an argument not returned by
3660    a matching allocation function such as malloc or the corresponding
3661    form of C++ operator new.  */
3662 
3663 void
maybe_check_dealloc_call(gcall * call)3664 pass_waccess::maybe_check_dealloc_call (gcall *call)
3665 {
3666   tree fndecl = gimple_call_fndecl (call);
3667   if (!fndecl)
3668     return;
3669 
3670   unsigned argno = fndecl_dealloc_argno (fndecl);
3671   if ((unsigned) call_nargs (call) <= argno)
3672     return;
3673 
3674   tree ptr = gimple_call_arg (call, argno);
3675   if (integer_zerop (ptr))
3676     return;
3677 
3678   access_ref aref;
3679   if (!compute_objsize (ptr, call, 0, &aref, &m_ptr_qry))
3680     return;
3681 
3682   tree ref = aref.ref;
3683   if (integer_zerop (ref))
3684     return;
3685 
3686   tree dealloc_decl = fndecl;
3687   location_t loc = gimple_location (call);
3688 
3689   if (DECL_P (ref) || EXPR_P (ref))
3690     {
3691       /* Diagnose freeing a declared object.  */
3692       if (aref.ref_declared ()
3693             && warning_at (loc, OPT_Wfree_nonheap_object,
3694                                "%qD called on unallocated object %qD",
3695                                dealloc_decl, ref))
3696           {
3697             inform (get_location (ref), "declared here");
3698             return;
3699           }
3700 
3701       /* Diagnose freeing a pointer that includes a positive offset.
3702            Such a pointer cannot refer to the beginning of an allocated
3703            object.  A negative offset may refer to it.  */
3704       if (aref.sizrng[0] != aref.sizrng[1]
3705             && warn_dealloc_offset (loc, call, aref))
3706           return;
3707     }
3708   else if (CONSTANT_CLASS_P (ref))
3709     {
3710       if (warning_at (loc, OPT_Wfree_nonheap_object,
3711                           "%qD called on a pointer to an unallocated "
3712                           "object %qE", dealloc_decl, ref))
3713           {
3714             if (TREE_CODE (ptr) == SSA_NAME)
3715               {
3716                 gimple *def_stmt = SSA_NAME_DEF_STMT (ptr);
3717                 if (is_gimple_assign (def_stmt))
3718                     {
3719                       location_t loc = gimple_location (def_stmt);
3720                       inform (loc, "assigned here");
3721                     }
3722               }
3723             return;
3724           }
3725     }
3726   else if (TREE_CODE (ref) == SSA_NAME)
3727     {
3728       /* Also warn if the pointer argument refers to the result
3729            of an allocation call like alloca or VLA.  */
3730       gimple *def_stmt = SSA_NAME_DEF_STMT (ref);
3731       if (!def_stmt)
3732           return;
3733 
3734       if (is_gimple_call (def_stmt))
3735           {
3736             bool warned = false;
3737             if (gimple_call_alloc_p (def_stmt))
3738               {
3739                 if (matching_alloc_calls_p (def_stmt, dealloc_decl))
3740                     {
3741                       if (warn_dealloc_offset (loc, call, aref))
3742                         return;
3743                     }
3744                 else
3745                     {
3746                       tree alloc_decl = gimple_call_fndecl (def_stmt);
3747                       const opt_code opt =
3748                         (DECL_IS_OPERATOR_NEW_P (alloc_decl)
3749                          || DECL_IS_OPERATOR_DELETE_P (dealloc_decl)
3750                          ? OPT_Wmismatched_new_delete
3751                          : OPT_Wmismatched_dealloc);
3752                       warned = warning_at (loc, opt,
3753                                                "%qD called on pointer returned "
3754                                                "from a mismatched allocation "
3755                                                "function", dealloc_decl);
3756                     }
3757               }
3758             else if (gimple_call_builtin_p (def_stmt, BUILT_IN_ALLOCA)
3759                        || gimple_call_builtin_p (def_stmt,
3760                                                        BUILT_IN_ALLOCA_WITH_ALIGN))
3761               warned = warning_at (loc, OPT_Wfree_nonheap_object,
3762                                          "%qD called on pointer to "
3763                                          "an unallocated object",
3764                                          dealloc_decl);
3765             else if (warn_dealloc_offset (loc, call, aref))
3766               return;
3767 
3768             if (warned)
3769               {
3770                 tree fndecl = gimple_call_fndecl (def_stmt);
3771                 inform (gimple_location (def_stmt),
3772                           "returned from %qD", fndecl);
3773                 return;
3774               }
3775           }
3776       else if (gimple_nop_p (def_stmt))
3777           {
3778             ref = SSA_NAME_VAR (ref);
3779             /* Diagnose freeing a pointer that includes a positive offset.  */
3780             if (TREE_CODE (ref) == PARM_DECL
3781                 && !aref.deref
3782                 && aref.sizrng[0] != aref.sizrng[1]
3783                 && aref.offrng[0] > 0 && aref.offrng[1] > 0
3784                 && warn_dealloc_offset (loc, call, aref))
3785               return;
3786           }
3787     }
3788 }
3789 
3790 /* Return true if either USE_STMT's basic block (that of a pointer's use)
3791    is dominated by INVAL_STMT's (that of a pointer's invalidating statement,
3792    which is either a clobber or a deallocation call), or if they're in
3793    the same block, USE_STMT follows INVAL_STMT.  */
3794 
3795 bool
use_after_inval_p(gimple * inval_stmt,gimple * use_stmt,bool last_block)3796 pass_waccess::use_after_inval_p (gimple *inval_stmt, gimple *use_stmt,
3797                                          bool last_block /* = false */)
3798 {
3799   tree clobvar =
3800     gimple_clobber_p (inval_stmt) ? gimple_assign_lhs (inval_stmt) : NULL_TREE;
3801 
3802   basic_block inval_bb = gimple_bb (inval_stmt);
3803   basic_block use_bb = gimple_bb (use_stmt);
3804 
3805   if (!inval_bb || !use_bb)
3806     return false;
3807 
3808   if (inval_bb != use_bb)
3809     {
3810       if (dominated_by_p (CDI_DOMINATORS, use_bb, inval_bb))
3811           return true;
3812 
3813       if (!clobvar || !last_block)
3814           return false;
3815 
3816       /* Proceed only when looking for uses of dangling pointers.  */
3817       auto gsi = gsi_for_stmt (use_stmt);
3818 
3819       /* A use statement in the last basic block in a function or one that
3820            falls through to it is after any other prior clobber of the used
3821            variable unless it's followed by a clobber of the same variable. */
3822       basic_block bb = use_bb;
3823       while (bb != inval_bb
3824                && single_succ_p (bb)
3825                && !(single_succ_edge (bb)->flags
3826                       & (EDGE_EH | EDGE_ABNORMAL | EDGE_DFS_BACK)))
3827           {
3828             for (; !gsi_end_p (gsi); gsi_next_nondebug (&gsi))
3829               {
3830                 gimple *stmt = gsi_stmt (gsi);
3831                 if (gimple_clobber_p (stmt))
3832                     {
3833                       if (clobvar == gimple_assign_lhs (stmt))
3834                         /* The use is followed by a clobber.  */
3835                         return false;
3836                     }
3837               }
3838 
3839             bb = single_succ (bb);
3840             gsi = gsi_start_bb (bb);
3841           }
3842 
3843       /* The use is one of a dangling pointer if a clobber of the variable
3844            [the pointer points to] has not been found before the function exit
3845            point.  */
3846       return bb == EXIT_BLOCK_PTR_FOR_FN (cfun);
3847     }
3848 
3849   if (bitmap_set_bit (m_bb_uids_set, inval_bb->index))
3850     /* The first time this basic block is visited assign increasing ids
3851        to consecutive statements in it.  Use the ids to determine which
3852        precedes which.  This avoids the linear traversal on subsequent
3853        visits to the same block.  */
3854     for (auto si = gsi_start_bb (inval_bb); !gsi_end_p (si);
3855            gsi_next_nondebug (&si))
3856       {
3857           gimple *stmt = gsi_stmt (si);
3858           unsigned uid = inc_gimple_stmt_max_uid (m_func);
3859           gimple_set_uid (stmt, uid);
3860       }
3861 
3862   return gimple_uid (inval_stmt) < gimple_uid (use_stmt);
3863 }
3864 
3865 /* Issue a warning for the USE_STMT of pointer or reference REF rendered
3866    invalid by INVAL_STMT.  REF may be null when it's been optimized away.
3867    When nonnull, INVAL_STMT is the deallocation function that rendered
3868    the pointer or reference dangling.  Otherwise, VAR is the auto variable
3869    (including an unnamed temporary such as a compound literal) whose
3870    lifetime's rended it dangling.  MAYBE is true to issue the "maybe"
3871    kind of warning.  EQUALITY is true when the pointer is used in
3872    an equality expression.  */
3873 
3874 void
warn_invalid_pointer(tree ref,gimple * use_stmt,gimple * inval_stmt,tree var,bool maybe,bool equality)3875 pass_waccess::warn_invalid_pointer (tree ref, gimple *use_stmt,
3876                                             gimple *inval_stmt, tree var,
3877                                             bool maybe, bool equality /* = false */)
3878 {
3879   /* Avoid printing the unhelpful "<unknown>" in the diagnostics.  */
3880   if (ref && TREE_CODE (ref) == SSA_NAME)
3881     {
3882       tree var = SSA_NAME_VAR (ref);
3883       if (!var)
3884           ref = NULL_TREE;
3885       /* Don't warn for cases like when a cdtor returns 'this' on ARM.  */
3886       else if (warning_suppressed_p (var, OPT_Wuse_after_free))
3887           return;
3888       else if (DECL_ARTIFICIAL (var))
3889           ref = NULL_TREE;
3890     }
3891 
3892   location_t use_loc = gimple_location (use_stmt);
3893   if (use_loc == UNKNOWN_LOCATION)
3894     {
3895       use_loc = m_func->function_end_locus;
3896       if (!ref)
3897           /* Avoid issuing a warning with no context other than
3898              the function.  That would make it difficult to debug
3899              in any but very simple cases.  */
3900           return;
3901     }
3902 
3903   if (is_gimple_call (inval_stmt))
3904     {
3905       if ((equality && warn_use_after_free < 3)
3906             || (maybe && warn_use_after_free < 2)
3907             || warning_suppressed_p (use_stmt, OPT_Wuse_after_free))
3908           return;
3909 
3910       const tree inval_decl = gimple_call_fndecl (inval_stmt);
3911 
3912       if ((ref && warning_at (use_loc, OPT_Wuse_after_free,
3913                                     (maybe
3914                                      ? G_("pointer %qE may be used after %qD")
3915                                      : G_("pointer %qE used after %qD")),
3916                                     ref, inval_decl))
3917             || (!ref && warning_at (use_loc, OPT_Wuse_after_free,
3918                                     (maybe
3919                                      ? G_("pointer may be used after %qD")
3920                                      : G_("pointer used after %qD")),
3921                                           inval_decl)))
3922           {
3923             location_t loc = gimple_location (inval_stmt);
3924             inform (loc, "call to %qD here", inval_decl);
3925             suppress_warning (use_stmt, OPT_Wuse_after_free);
3926           }
3927       return;
3928     }
3929 
3930   if (equality
3931       || (maybe && warn_dangling_pointer < 2)
3932       || warning_suppressed_p (use_stmt, OPT_Wdangling_pointer_))
3933     return;
3934 
3935   if (DECL_NAME (var))
3936     {
3937       if ((ref
3938              && warning_at (use_loc, OPT_Wdangling_pointer_,
3939                                 (maybe
3940                                  ? G_("dangling pointer %qE to %qD may be used")
3941                                  : G_("using dangling pointer %qE to %qD")),
3942                                 ref, var))
3943             || (!ref
3944                 && warning_at (use_loc, OPT_Wdangling_pointer_,
3945                                    (maybe
3946                                     ? G_("dangling pointer to %qD may be used")
3947                                     : G_("using a dangling pointer to %qD")),
3948                                    var)))
3949           inform (DECL_SOURCE_LOCATION (var),
3950                     "%qD declared here", var);
3951       suppress_warning (use_stmt, OPT_Wdangling_pointer_);
3952       return;
3953     }
3954 
3955   if ((ref
3956        && warning_at (use_loc, OPT_Wdangling_pointer_,
3957                           (maybe
3958                            ? G_("dangling pointer %qE to an unnamed temporary "
3959                                   "may be used")
3960                            : G_("using dangling pointer %qE to an unnamed "
3961                                   "temporary")),
3962                           ref))
3963       || (!ref
3964             && warning_at (use_loc, OPT_Wdangling_pointer_,
3965                                (maybe
3966                                 ? G_("dangling pointer to an unnamed temporary "
3967                                      "may be used")
3968                                 : G_("using a dangling pointer to an unnamed "
3969                                      "temporary")))))
3970     {
3971       inform (DECL_SOURCE_LOCATION (var),
3972                 "unnamed temporary defined here");
3973       suppress_warning (use_stmt, OPT_Wdangling_pointer_);
3974     }
3975 }
3976 
3977 /* If STMT is a call to either the standard realloc or to a user-defined
3978    reallocation function returns its LHS and set *PTR to the reallocated
3979    pointer.  Otherwise return null.  */
3980 
3981 static tree
get_realloc_lhs(gimple * stmt,tree * ptr)3982 get_realloc_lhs (gimple *stmt, tree *ptr)
3983 {
3984   if (gimple_call_builtin_p (stmt, BUILT_IN_REALLOC))
3985     {
3986       *ptr = gimple_call_arg (stmt, 0);
3987       return gimple_call_lhs (stmt);
3988     }
3989 
3990   gcall *call = dyn_cast<gcall *>(stmt);
3991   if (!call)
3992     return NULL_TREE;
3993 
3994   tree fnattr = NULL_TREE;
3995   tree fndecl = gimple_call_fndecl (call);
3996   if (fndecl)
3997     fnattr = DECL_ATTRIBUTES (fndecl);
3998   else
3999     {
4000       tree fntype = gimple_call_fntype (stmt);
4001       if (!fntype)
4002           return NULL_TREE;
4003       fnattr = TYPE_ATTRIBUTES (fntype);
4004     }
4005 
4006   if (!fnattr)
4007     return NULL_TREE;
4008 
4009   for (tree ats = fnattr;  (ats = lookup_attribute ("*dealloc", ats));
4010        ats = TREE_CHAIN (ats))
4011     {
4012       tree args = TREE_VALUE (ats);
4013       if (!args)
4014           continue;
4015 
4016       tree alloc = TREE_VALUE (args);
4017       if (!alloc)
4018           continue;
4019 
4020       if (alloc == DECL_NAME (fndecl))
4021           {
4022             unsigned argno = 0;
4023             if (tree index = TREE_CHAIN (args))
4024               argno = TREE_INT_CST_LOW (TREE_VALUE (index)) - 1;
4025             *ptr = gimple_call_arg (stmt, argno);
4026             return gimple_call_lhs (stmt);
4027           }
4028     }
4029 
4030   return NULL_TREE;
4031 }
4032 
4033 /* Warn if STMT is a call to a deallocation function that's not a match
4034    for the REALLOC_STMT call.  Return true if warned.  */
4035 
4036 static bool
maybe_warn_mismatched_realloc(tree ptr,gimple * realloc_stmt,gimple * stmt)4037 maybe_warn_mismatched_realloc (tree ptr, gimple *realloc_stmt, gimple *stmt)
4038 {
4039   if (!is_gimple_call (stmt))
4040     return false;
4041 
4042   tree fndecl = gimple_call_fndecl (stmt);
4043   if (!fndecl)
4044     return false;
4045 
4046   unsigned argno = fndecl_dealloc_argno (fndecl);
4047   if (call_nargs (stmt) <= argno)
4048     return false;
4049 
4050   if (matching_alloc_calls_p (realloc_stmt, fndecl))
4051     return false;
4052 
4053   /* Avoid printing the unhelpful "<unknown>" in the diagnostics.  */
4054   if (ptr && TREE_CODE (ptr) == SSA_NAME
4055       && (!SSA_NAME_VAR (ptr) || DECL_ARTIFICIAL (SSA_NAME_VAR (ptr))))
4056     ptr = NULL_TREE;
4057 
4058   location_t loc = gimple_location (stmt);
4059   tree realloc_decl = gimple_call_fndecl (realloc_stmt);
4060   tree dealloc_decl = gimple_call_fndecl (stmt);
4061   if (ptr && !warning_at (loc, OPT_Wmismatched_dealloc,
4062                                 "%qD called on pointer %qE passed to mismatched "
4063                                 "allocation function %qD",
4064                                 dealloc_decl, ptr, realloc_decl))
4065     return false;
4066   if (!ptr && !warning_at (loc, OPT_Wmismatched_dealloc,
4067                                  "%qD called on a pointer passed to mismatched "
4068                                  "reallocation function %qD",
4069                                  dealloc_decl, realloc_decl))
4070     return false;
4071 
4072   inform (gimple_location (realloc_stmt),
4073             "call to %qD", realloc_decl);
4074   return true;
4075 }
4076 
4077 /* Return true if P and Q point to the same object, and false if they
4078    either don't or their relationship cannot be determined.  */
4079 
4080 static bool
pointers_related_p(gimple * stmt,tree p,tree q,pointer_query & qry,auto_bitmap & visited)4081 pointers_related_p (gimple *stmt, tree p, tree q, pointer_query &qry,
4082                         auto_bitmap &visited)
4083 {
4084   if (!ptr_derefs_may_alias_p (p, q))
4085     return false;
4086 
4087   /* TODO: Work harder to rule out relatedness.  */
4088   access_ref pref, qref;
4089   if (!qry.get_ref (p, stmt, &pref, 0)
4090       || !qry.get_ref (q, stmt, &qref, 0))
4091     /* GET_REF() only rarely fails.  When it does, it's likely because
4092        it involves a self-referential PHI.  Return a conservative result.  */
4093     return false;
4094 
4095   if (pref.ref == qref.ref)
4096     return true;
4097 
4098   /* If either pointer is a PHI, iterate over all its operands and
4099      return true if they're all related to the other pointer.  */
4100   tree ptr = q;
4101   unsigned version;
4102   gphi *phi = pref.phi ();
4103   if (phi)
4104     version = SSA_NAME_VERSION (pref.ref);
4105   else
4106     {
4107       phi = qref.phi ();
4108       if (!phi)
4109           return false;
4110 
4111       ptr = p;
4112       version = SSA_NAME_VERSION (qref.ref);
4113     }
4114 
4115   if (!bitmap_set_bit (visited, version))
4116     return true;
4117 
4118   unsigned nargs = gimple_phi_num_args (phi);
4119   for (unsigned i = 0; i != nargs; ++i)
4120     {
4121       tree arg = gimple_phi_arg_def (phi, i);
4122       if (!pointers_related_p (stmt, arg, ptr, qry, visited))
4123           return false;
4124     }
4125 
4126   return true;
4127 }
4128 
4129 /* Convenience wrapper for the above.  */
4130 
4131 static bool
pointers_related_p(gimple * stmt,tree p,tree q,pointer_query & qry)4132 pointers_related_p (gimple *stmt, tree p, tree q, pointer_query &qry)
4133 {
4134   auto_bitmap visited;
4135   return pointers_related_p (stmt, p, q, qry, visited);
4136 }
4137 
4138 /* For a STMT either a call to a deallocation function or a clobber, warn
4139    for uses of the pointer PTR it was called with (including its copies
4140    or others derived from it by pointer arithmetic).  If STMT is a clobber,
4141    VAR is the decl of the clobbered variable.  When MAYBE is true use
4142    a "maybe" form of diagnostic.  */
4143 
4144 void
check_pointer_uses(gimple * stmt,tree ptr,tree var,bool maybe)4145 pass_waccess::check_pointer_uses (gimple *stmt, tree ptr,
4146                                           tree var /* = NULL_TREE */,
4147                                           bool maybe /* = false */)
4148 {
4149   gcc_assert (TREE_CODE (ptr) == SSA_NAME);
4150 
4151   const bool check_dangling = !is_gimple_call (stmt);
4152   basic_block stmt_bb = gimple_bb (stmt);
4153 
4154   /* If STMT is a reallocation function set to the reallocated pointer
4155      and the LHS of the call, respectively.  */
4156   tree realloc_ptr = NULL_TREE;
4157   tree realloc_lhs = get_realloc_lhs (stmt, &realloc_ptr);
4158 
4159   auto_bitmap visited;
4160 
4161   auto_vec<tree> pointers;
4162   pointers.safe_push (ptr);
4163 
4164   /* Starting with PTR, iterate over POINTERS added by the loop, and
4165      either warn for their uses in basic blocks dominated by the STMT
4166      or in statements that follow it in the same basic block, or add
4167      them to POINTERS if they point into the same object as PTR (i.e.,
4168      are obtained by pointer arithmetic on PTR).  */
4169   for (unsigned i = 0; i != pointers.length (); ++i)
4170     {
4171       tree ptr = pointers[i];
4172       if (!bitmap_set_bit (visited, SSA_NAME_VERSION (ptr)))
4173           /* Avoid revisiting the same pointer.  */
4174           continue;
4175 
4176       use_operand_p use_p;
4177       imm_use_iterator iter;
4178       FOR_EACH_IMM_USE_FAST (use_p, iter, ptr)
4179           {
4180             gimple *use_stmt = USE_STMT (use_p);
4181             if (use_stmt == stmt || is_gimple_debug (use_stmt))
4182               continue;
4183 
4184             if (realloc_lhs)
4185               {
4186                 /* Check to see if USE_STMT is a mismatched deallocation
4187                      call for the pointer passed to realloc.  That's a bug
4188                      regardless of the pointer's value and so warn.  */
4189                 if (maybe_warn_mismatched_realloc (*use_p->use, stmt, use_stmt))
4190                     continue;
4191 
4192                 /* Pointers passed to realloc that are used in basic blocks
4193                      where the realloc call is known to have failed are valid.
4194                      Ignore pointers that nothing is known about.  Those could
4195                      have escaped along with their nullness.  */
4196                 value_range vr;
4197                 if (m_ptr_qry.rvals->range_of_expr (vr, realloc_lhs, use_stmt))
4198                     {
4199                       if (vr.zero_p ())
4200                         continue;
4201 
4202                       if (!pointers_related_p (stmt, ptr, realloc_ptr, m_ptr_qry))
4203                         continue;
4204                     }
4205               }
4206 
4207             if (check_dangling
4208                 && gimple_code (use_stmt) == GIMPLE_RETURN)
4209               /* Avoid interfering with -Wreturn-local-addr (which runs only
4210                  with optimization enabled so it won't diagnose cases that
4211                  would be caught here when optimization is disabled).  */
4212               continue;
4213 
4214             bool equality = false;
4215             if (is_gimple_assign (use_stmt))
4216               {
4217                 tree_code code = gimple_assign_rhs_code (use_stmt);
4218                 equality = code == EQ_EXPR || code == NE_EXPR;
4219               }
4220             else if (gcond *cond = dyn_cast<gcond *>(use_stmt))
4221               {
4222                 tree_code code = gimple_cond_code (cond);
4223                 equality = code == EQ_EXPR || code == NE_EXPR;
4224               }
4225 
4226             /* Warn if USE_STMT is dominated by the deallocation STMT.
4227                Otherwise, add the pointer to POINTERS so that the uses
4228                of any other pointers derived from it can be checked.  */
4229             if (use_after_inval_p (stmt, use_stmt, check_dangling))
4230               {
4231                 if (gimple_code (use_stmt) == GIMPLE_PHI)
4232                     {
4233                       /* Only add a PHI result to POINTERS if all its
4234                          operands are related to PTR, otherwise continue.  */
4235                       tree lhs = gimple_phi_result (use_stmt);
4236                       if (!pointers_related_p (stmt, lhs, ptr, m_ptr_qry))
4237                         continue;
4238 
4239                       if (TREE_CODE (lhs) == SSA_NAME)
4240                         {
4241                           pointers.safe_push (lhs);
4242                           continue;
4243                         }
4244                     }
4245 
4246                 basic_block use_bb = gimple_bb (use_stmt);
4247                 bool this_maybe
4248                     = (maybe
4249                        || !dominated_by_p (CDI_POST_DOMINATORS, stmt_bb, use_bb));
4250                 warn_invalid_pointer (*use_p->use, use_stmt, stmt, var,
4251                                             this_maybe, equality);
4252                 continue;
4253               }
4254 
4255             if (is_gimple_assign (use_stmt))
4256               {
4257                 tree lhs = gimple_assign_lhs (use_stmt);
4258                 if (TREE_CODE (lhs) == SSA_NAME)
4259                     {
4260                       tree_code rhs_code = gimple_assign_rhs_code (use_stmt);
4261                       if (rhs_code == POINTER_PLUS_EXPR || rhs_code == SSA_NAME)
4262                         pointers.safe_push (lhs);
4263                     }
4264                 continue;
4265               }
4266 
4267             if (gcall *call = dyn_cast <gcall *>(use_stmt))
4268               {
4269                 if (gimple_call_return_arg (call) == ptr)
4270                     if (tree lhs = gimple_call_lhs (call))
4271                       if (TREE_CODE (lhs) == SSA_NAME)
4272                         pointers.safe_push (lhs);
4273                 continue;
4274               }
4275           }
4276     }
4277 }
4278 
4279 /* Check call STMT for invalid accesses.  */
4280 
4281 void
check_call(gcall * stmt)4282 pass_waccess::check_call (gcall *stmt)
4283 {
4284   if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
4285     check_builtin (stmt);
4286 
4287   /* .ASAN_MARK doesn't access any vars, only modifies shadow memory.  */
4288   if (gimple_call_internal_p (stmt)
4289       && gimple_call_internal_fn (stmt) == IFN_ASAN_MARK)
4290     return;
4291 
4292   if (!m_early_checks_p)
4293     if (tree callee = gimple_call_fndecl (stmt))
4294       {
4295           /* Check for uses of the pointer passed to either a standard
4296              or a user-defined deallocation function.  */
4297           unsigned argno = fndecl_dealloc_argno (callee);
4298           if (argno < (unsigned) call_nargs (stmt))
4299             {
4300               tree arg = call_arg (stmt, argno);
4301               if (TREE_CODE (arg) == SSA_NAME)
4302                 check_pointer_uses (stmt, arg);
4303             }
4304       }
4305 
4306   check_call_access (stmt);
4307   check_call_dangling (stmt);
4308 
4309   if (m_early_checks_p)
4310     return;
4311 
4312   maybe_check_dealloc_call (stmt);
4313   check_nonstring_args (stmt);
4314 }
4315 
4316 /* Check non-call STMT for invalid accesses.  */
4317 
4318 void
check_stmt(gimple * stmt)4319 pass_waccess::check_stmt (gimple *stmt)
4320 {
4321   if (m_check_dangling_p
4322       && gimple_clobber_p (stmt, CLOBBER_EOL))
4323     {
4324       /* Ignore clobber statements in blocks with exceptional edges.  */
4325       basic_block bb = gimple_bb (stmt);
4326       edge e = EDGE_PRED (bb, 0);
4327       if (e->flags & EDGE_EH)
4328           return;
4329 
4330       tree var = gimple_assign_lhs (stmt);
4331       m_clobbers.put (var, stmt);
4332       return;
4333     }
4334 
4335   if (is_gimple_assign (stmt))
4336     {
4337       /* Clobbered unnamed temporaries such as compound literals can be
4338            revived.  Check for an assignment to one and remove it from
4339            M_CLOBBERS.  */
4340       tree lhs = gimple_assign_lhs (stmt);
4341       while (handled_component_p (lhs))
4342           lhs = TREE_OPERAND (lhs, 0);
4343 
4344       if (auto_var_p (lhs))
4345           m_clobbers.remove (lhs);
4346       return;
4347     }
4348 
4349   if (greturn *ret = dyn_cast <greturn *> (stmt))
4350     {
4351       if (optimize && flag_isolate_erroneous_paths_dereference)
4352           /* Avoid interfering with -Wreturn-local-addr (which runs only
4353              with optimization enabled).  */
4354           return;
4355 
4356       tree arg = gimple_return_retval (ret);
4357       if (!arg || TREE_CODE (arg) != ADDR_EXPR)
4358           return;
4359 
4360       arg = TREE_OPERAND (arg, 0);
4361       while (handled_component_p (arg))
4362           arg = TREE_OPERAND (arg, 0);
4363 
4364       if (!auto_var_p (arg))
4365           return;
4366 
4367       gimple **pclobber = m_clobbers.get (arg);
4368       if (!pclobber)
4369           return;
4370 
4371       if (!use_after_inval_p (*pclobber, stmt))
4372           return;
4373 
4374       warn_invalid_pointer (NULL_TREE, stmt, *pclobber, arg, false);
4375     }
4376 }
4377 
4378 /* Check basic block BB for invalid accesses.  */
4379 
4380 void
check_block(basic_block bb)4381 pass_waccess::check_block (basic_block bb)
4382 {
4383   /* Iterate over statements, looking for function calls.  */
4384   for (auto si = gsi_start_bb (bb); !gsi_end_p (si);
4385        gsi_next_nondebug (&si))
4386     {
4387       gimple *stmt = gsi_stmt (si);
4388       if (gcall *call = dyn_cast <gcall *> (stmt))
4389           check_call (call);
4390       else
4391           check_stmt (stmt);
4392     }
4393 }
4394 
4395 /* Return the argument that the call STMT to a built-in function returns
4396    (including with an offset) or null if it doesn't.  */
4397 
4398 tree
gimple_call_return_arg(gcall * call)4399 pass_waccess::gimple_call_return_arg (gcall *call)
4400 {
4401   /* Check for attribute fn spec to see if the function returns one
4402      of its arguments.  */
4403   attr_fnspec fnspec = gimple_call_fnspec (call);
4404   unsigned int argno;
4405   if (!fnspec.returns_arg (&argno))
4406     {
4407       if (gimple_call_num_args (call) < 1)
4408           return NULL_TREE;
4409 
4410       if (!gimple_call_builtin_p (call, BUILT_IN_NORMAL))
4411           return NULL_TREE;
4412 
4413       tree fndecl = gimple_call_fndecl (call);
4414       switch (DECL_FUNCTION_CODE (fndecl))
4415           {
4416           case BUILT_IN_MEMPCPY:
4417           case BUILT_IN_MEMPCPY_CHK:
4418           case BUILT_IN_MEMCHR:
4419           case BUILT_IN_STRCHR:
4420           case BUILT_IN_STRRCHR:
4421           case BUILT_IN_STRSTR:
4422           case BUILT_IN_STPCPY:
4423           case BUILT_IN_STPCPY_CHK:
4424           case BUILT_IN_STPNCPY:
4425           case BUILT_IN_STPNCPY_CHK:
4426             argno = 0;
4427             break;
4428 
4429           default:
4430             return NULL_TREE;
4431           }
4432     }
4433 
4434   if (gimple_call_num_args (call) <= argno)
4435     return NULL_TREE;
4436 
4437   return gimple_call_arg (call, argno);
4438 }
4439 
4440 /* Check for and diagnose all uses of the dangling pointer VAR to the auto
4441    object DECL whose lifetime has ended.  OBJREF is true when VAR denotes
4442    an access to a DECL that may have been clobbered.  */
4443 
4444 void
check_dangling_uses(tree var,tree decl,bool maybe,bool objref)4445 pass_waccess::check_dangling_uses (tree var, tree decl, bool maybe /* = false */,
4446                                            bool objref /* = false */)
4447 {
4448   if (!decl || !auto_var_p (decl))
4449     return;
4450 
4451   gimple **pclob = m_clobbers.get (decl);
4452   if (!pclob)
4453     return;
4454 
4455   if (!objref)
4456     {
4457       check_pointer_uses (*pclob, var, decl, maybe);
4458       return;
4459     }
4460 
4461   gimple *use_stmt = SSA_NAME_DEF_STMT (var);
4462   if (!use_after_inval_p (*pclob, use_stmt, true))
4463     return;
4464 
4465   basic_block use_bb = gimple_bb (use_stmt);
4466   basic_block clob_bb = gimple_bb (*pclob);
4467   maybe = maybe || !dominated_by_p (CDI_POST_DOMINATORS, clob_bb, use_bb);
4468   warn_invalid_pointer (var, use_stmt, *pclob, decl, maybe, false);
4469 }
4470 
4471 /* Diagnose stores in BB and (recursively) its predecessors of the addresses
4472    of local variables into nonlocal pointers that are left dangling after
4473    the function returns.  BBS is a bitmap of basic blocks visited.  */
4474 
4475 void
check_dangling_stores(basic_block bb,hash_set<tree> & stores,auto_bitmap & bbs)4476 pass_waccess::check_dangling_stores (basic_block bb,
4477                                              hash_set<tree> &stores,
4478                                              auto_bitmap &bbs)
4479 {
4480   if (!bitmap_set_bit (bbs, bb->index))
4481     /* Avoid cycles. */
4482     return;
4483 
4484   /* Iterate backwards over the statements looking for a store of
4485      the address of a local variable into a nonlocal pointer.  */
4486   for (auto gsi = gsi_last_nondebug_bb (bb); ; gsi_prev_nondebug (&gsi))
4487     {
4488       gimple *stmt = gsi_stmt (gsi);
4489       if (!stmt)
4490           break;
4491 
4492       if (warning_suppressed_p (stmt, OPT_Wdangling_pointer_))
4493           continue;
4494 
4495       if (is_gimple_call (stmt)
4496             && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
4497           /* Avoid looking before nonconst, nonpure calls since those might
4498              use the escaped locals.  */
4499           return;
4500 
4501       if (!is_gimple_assign (stmt) || gimple_clobber_p (stmt))
4502           continue;
4503 
4504       access_ref lhs_ref;
4505       tree lhs = gimple_assign_lhs (stmt);
4506       if (!m_ptr_qry.get_ref (lhs, stmt, &lhs_ref, 0))
4507           continue;
4508 
4509       if (auto_var_p (lhs_ref.ref))
4510           continue;
4511 
4512       if (DECL_P (lhs_ref.ref))
4513           {
4514             if (!POINTER_TYPE_P (TREE_TYPE (lhs_ref.ref))
4515                 || lhs_ref.deref > 0)
4516               continue;
4517           }
4518       else if (TREE_CODE (lhs_ref.ref) == SSA_NAME)
4519           {
4520             gimple *def_stmt = SSA_NAME_DEF_STMT (lhs_ref.ref);
4521             if (!gimple_nop_p (def_stmt))
4522               /* Avoid looking at or before stores into unknown objects.  */
4523               return;
4524 
4525             tree var = SSA_NAME_VAR (lhs_ref.ref);
4526             if (TREE_CODE (var) == PARM_DECL && DECL_BY_REFERENCE (var))
4527               /* Avoid by-value arguments transformed into by-reference.  */
4528               continue;
4529 
4530           }
4531       else if (TREE_CODE (lhs_ref.ref) == MEM_REF)
4532           {
4533             tree arg = TREE_OPERAND (lhs_ref.ref, 0);
4534             if (TREE_CODE (arg) == SSA_NAME)
4535               {
4536                 gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
4537                 if (!gimple_nop_p (def_stmt))
4538                     return;
4539               }
4540           }
4541       else
4542           continue;
4543 
4544       if (stores.add (lhs_ref.ref))
4545           continue;
4546 
4547       /* FIXME: Handle stores of alloca() and VLA.  */
4548       access_ref rhs_ref;
4549       tree rhs = gimple_assign_rhs1 (stmt);
4550       if (!m_ptr_qry.get_ref (rhs, stmt, &rhs_ref, 0)
4551             || rhs_ref.deref != -1)
4552           continue;
4553 
4554       if (!auto_var_p (rhs_ref.ref))
4555           continue;
4556 
4557       location_t loc = gimple_location (stmt);
4558       if (warning_at (loc, OPT_Wdangling_pointer_,
4559                           "storing the address of local variable %qD in %qE",
4560                           rhs_ref.ref, lhs))
4561           {
4562             suppress_warning (stmt, OPT_Wdangling_pointer_);
4563 
4564             location_t loc = DECL_SOURCE_LOCATION (rhs_ref.ref);
4565             inform (loc, "%qD declared here", rhs_ref.ref);
4566 
4567             if (DECL_P (lhs_ref.ref))
4568               loc = DECL_SOURCE_LOCATION (lhs_ref.ref);
4569             else if (EXPR_HAS_LOCATION (lhs_ref.ref))
4570               loc = EXPR_LOCATION (lhs_ref.ref);
4571 
4572             if (loc != UNKNOWN_LOCATION)
4573               inform (loc, "%qE declared here", lhs_ref.ref);
4574           }
4575     }
4576 
4577   edge e;
4578   edge_iterator ei;
4579   FOR_EACH_EDGE (e, ei, bb->preds)
4580     {
4581       basic_block pred = e->src;
4582       check_dangling_stores (pred, stores, bbs);
4583     }
4584 }
4585 
4586 /* Diagnose stores of the addresses of local variables into nonlocal
4587    pointers that are left dangling after the function returns.  */
4588 
4589 void
check_dangling_stores()4590 pass_waccess::check_dangling_stores ()
4591 {
4592   auto_bitmap bbs;
4593   hash_set<tree> stores;
4594   check_dangling_stores (EXIT_BLOCK_PTR_FOR_FN (m_func), stores, bbs);
4595 }
4596 
4597 /* Check for and diagnose uses of dangling pointers to auto objects
4598    whose lifetime has ended.  */
4599 
4600 void
check_dangling_uses()4601 pass_waccess::check_dangling_uses ()
4602 {
4603   tree var;
4604   unsigned i;
4605   FOR_EACH_SSA_NAME (i, var, m_func)
4606     {
4607       /* For each SSA_NAME pointer VAR find the object it points to.
4608            If the object is a clobbered local variable, check to see
4609            if any of VAR's uses (or those of other pointers derived
4610            from VAR) happens after the clobber.  If so, warn.  */
4611 
4612       gimple *def_stmt = SSA_NAME_DEF_STMT (var);
4613       if (is_gimple_assign (def_stmt))
4614           {
4615             tree rhs = gimple_assign_rhs1 (def_stmt);
4616             if (TREE_CODE (rhs) == ADDR_EXPR)
4617               {
4618                 if (!POINTER_TYPE_P (TREE_TYPE (var)))
4619                     continue;
4620                 check_dangling_uses (var, TREE_OPERAND (rhs, 0));
4621               }
4622             else
4623               {
4624                 /* For other expressions, check the base DECL to see
4625                      if it's been clobbered, most likely as a result of
4626                      inlining a reference to it.  */
4627                 tree decl = get_base_address (rhs);
4628                 if (DECL_P (decl))
4629                     check_dangling_uses (var, decl, false, true);
4630               }
4631           }
4632       else if (POINTER_TYPE_P (TREE_TYPE (var)))
4633           {
4634             if (gcall *call = dyn_cast<gcall *>(def_stmt))
4635               {
4636                 if (tree arg = gimple_call_return_arg (call))
4637                     {
4638                       access_ref aref;
4639                       if (m_ptr_qry.get_ref (arg, call, &aref, 0)
4640                           && aref.deref < 0)
4641                         check_dangling_uses (var, aref.ref);
4642                     }
4643               }
4644             else if (gphi *phi = dyn_cast <gphi *>(def_stmt))
4645               {
4646                 unsigned nargs = gimple_phi_num_args (phi);
4647                 for (unsigned i = 0; i != nargs; ++i)
4648                     {
4649                       access_ref aref;
4650                       tree arg = gimple_phi_arg_def (phi, i);
4651                       if (m_ptr_qry.get_ref (arg, phi, &aref, 0)
4652                           && aref.deref < 0)
4653                         check_dangling_uses (var, aref.ref, true);
4654                     }
4655               }
4656           }
4657     }
4658 }
4659 
4660 /* Check CALL arguments for dangling pointers (those that have been
4661    clobbered) and warn if found.  */
4662 
4663 void
check_call_dangling(gcall * call)4664 pass_waccess::check_call_dangling (gcall *call)
4665 {
4666   unsigned nargs = gimple_call_num_args (call);
4667   for (unsigned i = 0; i != nargs; ++i)
4668     {
4669       tree arg = gimple_call_arg (call, i);
4670       if (TREE_CODE (arg) != ADDR_EXPR)
4671           continue;
4672 
4673       arg = TREE_OPERAND (arg, 0);
4674       if (!DECL_P (arg))
4675           continue;
4676 
4677       gimple **pclobber = m_clobbers.get (arg);
4678       if (!pclobber)
4679           continue;
4680 
4681       if (!use_after_inval_p (*pclobber, call))
4682           continue;
4683 
4684       warn_invalid_pointer (NULL_TREE, call, *pclobber, arg, false);
4685     }
4686 }
4687 
4688 /* Check function FUN for invalid accesses.  */
4689 
4690 unsigned
execute(function * fun)4691 pass_waccess::execute (function *fun)
4692 {
4693   calculate_dominance_info (CDI_DOMINATORS);
4694   calculate_dominance_info (CDI_POST_DOMINATORS);
4695 
4696   /* Set or clear EDGE_DFS_BACK bits on back edges.  */
4697   mark_dfs_back_edges (fun);
4698 
4699   /* Create a new ranger instance and associate it with FUN.  */
4700   m_ptr_qry.rvals = enable_ranger (fun);
4701   m_func = fun;
4702 
4703   /* Check for dangling pointers in the earliest run of the pass.
4704      The latest point -Wdangling-pointer should run is just before
4705      loop unrolling which introduces uses after clobbers.  Most cases
4706      can be detected without optimization; cases where the address of
4707      the local variable is passed to and then returned from a user-
4708      defined function before its lifetime ends and the returned pointer
4709      becomes dangling depend on inlining.  */
4710   m_check_dangling_p = m_early_checks_p;
4711 
4712   auto_bitmap bb_uids_set (&bitmap_default_obstack);
4713   m_bb_uids_set = bb_uids_set;
4714 
4715   set_gimple_stmt_max_uid (m_func, 0);
4716 
4717   basic_block bb;
4718   FOR_EACH_BB_FN (bb, fun)
4719     check_block (bb);
4720 
4721   if (m_check_dangling_p)
4722     {
4723       check_dangling_uses ();
4724       check_dangling_stores ();
4725     }
4726 
4727   if (dump_file)
4728     m_ptr_qry.dump (dump_file, (dump_flags & TDF_DETAILS) != 0);
4729 
4730   m_ptr_qry.flush_cache ();
4731 
4732   /* Release the ranger instance and replace it with a global ranger.
4733      Also reset the pointer since calling disable_ranger() deletes it.  */
4734   disable_ranger (fun);
4735   m_ptr_qry.rvals = NULL;
4736 
4737   m_clobbers.empty ();
4738   m_bb_uids_set = NULL;
4739 
4740   free_dominance_info (CDI_POST_DOMINATORS);
4741   free_dominance_info (CDI_DOMINATORS);
4742   return 0;
4743 }
4744 
4745 }   // namespace
4746 
4747 /* Return a new instance of the pass.  */
4748 
4749 gimple_opt_pass *
make_pass_warn_access(gcc::context * ctxt)4750 make_pass_warn_access (gcc::context *ctxt)
4751 {
4752   return new pass_waccess (ctxt);
4753 }
4754