re PR sanitizer/63956 ([UBSAN] ICE segfault in cxx_eval_call_expression ../../gcc...
[platform/upstream/gcc.git] / gcc / ubsan.c
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2    Copyright (C) 2013-2014 Free Software Foundation, Inc.
3    Contributed by Marek Polacek <polacek@redhat.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tree.h"
25 #include "stor-layout.h"
26 #include "stringpool.h"
27 #include "predict.h"
28 #include "dominance.h"
29 #include "cfg.h"
30 #include "cfganal.h"
31 #include "basic-block.h"
32 #include "hash-map.h"
33 #include "is-a.h"
34 #include "plugin-api.h"
35 #include "vec.h"
36 #include "hashtab.h"
37 #include "hash-set.h"
38 #include "machmode.h"
39 #include "tm.h"
40 #include "hard-reg-set.h"
41 #include "input.h"
42 #include "function.h"
43 #include "ipa-ref.h"
44 #include "cgraph.h"
45 #include "tree-pass.h"
46 #include "tree-ssa-alias.h"
47 #include "tree-pretty-print.h"
48 #include "internal-fn.h"
49 #include "gimple-expr.h"
50 #include "gimple.h"
51 #include "gimple-iterator.h"
52 #include "gimple-ssa.h"
53 #include "gimple-walk.h"
54 #include "output.h"
55 #include "tm_p.h"
56 #include "toplev.h"
57 #include "cfgloop.h"
58 #include "ubsan.h"
59 #include "c-family/c-common.h"
60 #include "rtl.h"
61 #include "expr.h"
62 #include "tree-ssanames.h"
63 #include "asan.h"
64 #include "gimplify-me.h"
65 #include "intl.h"
66 #include "realmpfr.h"
67 #include "dfp.h"
68 #include "builtins.h"
69 #include "tree-object-size.h"
70 #include "tree-eh.h"
71
72 /* Map from a tree to a VAR_DECL tree.  */
73
74 struct GTY((for_user)) tree_type_map {
75   struct tree_map_base type;
76   tree decl;
77 };
78
79 struct tree_type_map_cache_hasher : ggc_cache_hasher<tree_type_map *>
80 {
81   static inline hashval_t
82   hash (tree_type_map *t)
83   {
84     return TYPE_UID (t->type.from);
85   }
86
87   static inline bool
88   equal (tree_type_map *a, tree_type_map *b)
89   {
90     return a->type.from == b->type.from;
91   }
92
93   static void
94   handle_cache_entry (tree_type_map *&m)
95   {
96     extern void gt_ggc_mx (tree_type_map *&);
97     if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
98       return;
99     else if (ggc_marked_p (m->type.from))
100       gt_ggc_mx (m);
101     else
102       m = static_cast<tree_type_map *> (HTAB_DELETED_ENTRY);
103   }
104 };
105
106 static GTY ((cache))
107      hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
108
109 /* Lookup a VAR_DECL for TYPE, and return it if we find one.  */
110
111 static tree
112 decl_for_type_lookup (tree type)
113 {
114   /* If the hash table is not initialized yet, create it now.  */
115   if (decl_tree_for_type == NULL)
116     {
117       decl_tree_for_type
118         = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
119       /* That also means we don't have to bother with the lookup.  */
120       return NULL_TREE;
121     }
122
123   struct tree_type_map *h, in;
124   in.type.from = type;
125
126   h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
127   return h ? h->decl : NULL_TREE;
128 }
129
130 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable.  */
131
132 static void
133 decl_for_type_insert (tree type, tree decl)
134 {
135   struct tree_type_map *h;
136
137   h = ggc_alloc<tree_type_map> ();
138   h->type.from = type;
139   h->decl = decl;
140   *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
141 }
142
143 /* Helper routine, which encodes a value in the pointer_sized_int_node.
144    Arguments with precision <= POINTER_SIZE are passed directly,
145    the rest is passed by reference.  T is a value we are to encode.
146    IN_EXPAND_P is true if this function is called during expansion.  */
147
148 tree
149 ubsan_encode_value (tree t, bool in_expand_p)
150 {
151   tree type = TREE_TYPE (t);
152   const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
153   if (bitsize <= POINTER_SIZE)
154     switch (TREE_CODE (type))
155       {
156       case BOOLEAN_TYPE:
157       case ENUMERAL_TYPE:
158       case INTEGER_TYPE:
159         return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
160       case REAL_TYPE:
161         {
162           tree itype = build_nonstandard_integer_type (bitsize, true);
163           t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
164           return fold_convert (pointer_sized_int_node, t);
165         }
166       default:
167         gcc_unreachable ();
168       }
169   else
170     {
171       if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
172         {
173           /* The reason for this is that we don't want to pessimize
174              code by making vars unnecessarily addressable.  */
175           tree var = create_tmp_var (type);
176           tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
177           if (in_expand_p)
178             {
179               rtx mem
180                 = assign_stack_temp_for_type (TYPE_MODE (type),
181                                               GET_MODE_SIZE (TYPE_MODE (type)),
182                                               type);
183               SET_DECL_RTL (var, mem);
184               expand_assignment (var, t, false);
185               return build_fold_addr_expr (var);
186             }
187           t = build_fold_addr_expr (var);
188           return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
189         }
190       else
191         return build_fold_addr_expr (t);
192     }
193 }
194
195 /* Cached ubsan_get_type_descriptor_type () return value.  */
196 static GTY(()) tree ubsan_type_descriptor_type;
197
198 /* Build
199    struct __ubsan_type_descriptor
200    {
201      unsigned short __typekind;
202      unsigned short __typeinfo;
203      char __typename[];
204    }
205    type.  */
206
207 static tree
208 ubsan_get_type_descriptor_type (void)
209 {
210   static const char *field_names[3]
211     = { "__typekind", "__typeinfo", "__typename" };
212   tree fields[3], ret;
213
214   if (ubsan_type_descriptor_type)
215     return ubsan_type_descriptor_type;
216
217   tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
218   tree flex_arr_type = build_array_type (char_type_node, itype);
219
220   ret = make_node (RECORD_TYPE);
221   for (int i = 0; i < 3; i++)
222     {
223       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
224                               get_identifier (field_names[i]),
225                               (i == 2) ? flex_arr_type
226                               : short_unsigned_type_node);
227       DECL_CONTEXT (fields[i]) = ret;
228       if (i)
229         DECL_CHAIN (fields[i - 1]) = fields[i];
230     }
231   tree type_decl = build_decl (input_location, TYPE_DECL,
232                                get_identifier ("__ubsan_type_descriptor"),
233                                ret);
234   DECL_IGNORED_P (type_decl) = 1;
235   DECL_ARTIFICIAL (type_decl) = 1;
236   TYPE_FIELDS (ret) = fields[0];
237   TYPE_NAME (ret) = type_decl;
238   TYPE_STUB_DECL (ret) = type_decl;
239   layout_type (ret);
240   ubsan_type_descriptor_type = ret;
241   return ret;
242 }
243
244 /* Cached ubsan_get_source_location_type () return value.  */
245 static GTY(()) tree ubsan_source_location_type;
246
247 /* Build
248    struct __ubsan_source_location
249    {
250      const char *__filename;
251      unsigned int __line;
252      unsigned int __column;
253    }
254    type.  */
255
256 tree
257 ubsan_get_source_location_type (void)
258 {
259   static const char *field_names[3]
260     = { "__filename", "__line", "__column" };
261   tree fields[3], ret;
262   if (ubsan_source_location_type)
263     return ubsan_source_location_type;
264
265   tree const_char_type = build_qualified_type (char_type_node,
266                                                TYPE_QUAL_CONST);
267
268   ret = make_node (RECORD_TYPE);
269   for (int i = 0; i < 3; i++)
270     {
271       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
272                               get_identifier (field_names[i]),
273                               (i == 0) ? build_pointer_type (const_char_type)
274                               : unsigned_type_node);
275       DECL_CONTEXT (fields[i]) = ret;
276       if (i)
277         DECL_CHAIN (fields[i - 1]) = fields[i];
278     }
279   tree type_decl = build_decl (input_location, TYPE_DECL,
280                                get_identifier ("__ubsan_source_location"),
281                                ret);
282   DECL_IGNORED_P (type_decl) = 1;
283   DECL_ARTIFICIAL (type_decl) = 1;
284   TYPE_FIELDS (ret) = fields[0];
285   TYPE_NAME (ret) = type_decl;
286   TYPE_STUB_DECL (ret) = type_decl;
287   layout_type (ret);
288   ubsan_source_location_type = ret;
289   return ret;
290 }
291
292 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
293    type with its fields filled from a location_t LOC.  */
294
295 static tree
296 ubsan_source_location (location_t loc)
297 {
298   expanded_location xloc;
299   tree type = ubsan_get_source_location_type ();
300
301   xloc = expand_location (loc);
302   tree str;
303   if (xloc.file == NULL)
304     {
305       str = build_int_cst (ptr_type_node, 0);
306       xloc.line = 0;
307       xloc.column = 0;
308     }
309   else
310     {
311       /* Fill in the values from LOC.  */
312       size_t len = strlen (xloc.file);
313       str = build_string (len + 1, xloc.file);
314       TREE_TYPE (str) = build_array_type (char_type_node,
315                                           build_index_type (size_int (len)));
316       TREE_READONLY (str) = 1;
317       TREE_STATIC (str) = 1;
318       str = build_fold_addr_expr (str);
319     }
320   tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
321                                     build_int_cst (unsigned_type_node,
322                                                    xloc.line), NULL_TREE,
323                                     build_int_cst (unsigned_type_node,
324                                                    xloc.column));
325   TREE_CONSTANT (ctor) = 1;
326   TREE_STATIC (ctor) = 1;
327
328   return ctor;
329 }
330
331 /* This routine returns a magic number for TYPE.  */
332
333 static unsigned short
334 get_ubsan_type_info_for_type (tree type)
335 {
336   gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
337   if (TREE_CODE (type) == REAL_TYPE)
338     return tree_to_uhwi (TYPE_SIZE (type));
339   else if (INTEGRAL_TYPE_P (type))
340     {
341       int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
342       gcc_assert (prec != -1);
343       return (prec << 1) | !TYPE_UNSIGNED (type);
344     }
345   else
346     return 0;
347 }
348
349 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
350    descriptor.  It first looks into the hash table; if not found,
351    create the VAR_DECL, put it into the hash table and return the
352    ADDR_EXPR of it.  TYPE describes a particular type.  PSTYLE is
353    an enum controlling how we want to print the type.  */
354
355 tree
356 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
357 {
358   /* See through any typedefs.  */
359   type = TYPE_MAIN_VARIANT (type);
360
361   tree decl = decl_for_type_lookup (type);
362   /* It is possible that some of the earlier created DECLs were found
363      unused, in that case they weren't emitted and varpool_node::get
364      returns NULL node on them.  But now we really need them.  Thus,
365      renew them here.  */
366   if (decl != NULL_TREE && varpool_node::get (decl))
367     return build_fold_addr_expr (decl);
368
369   tree dtype = ubsan_get_type_descriptor_type ();
370   tree type2 = type;
371   const char *tname = NULL;
372   char *pretty_name;
373   unsigned char deref_depth = 0;
374   unsigned short tkind, tinfo;
375
376   /* Get the name of the type, or the name of the pointer type.  */
377   if (pstyle == UBSAN_PRINT_POINTER)
378     {
379       gcc_assert (POINTER_TYPE_P (type));
380       type2 = TREE_TYPE (type);
381
382       /* Remove any '*' operators from TYPE.  */
383       while (POINTER_TYPE_P (type2))
384         deref_depth++, type2 = TREE_TYPE (type2);
385
386       if (TREE_CODE (type2) == METHOD_TYPE)
387         type2 = TYPE_METHOD_BASETYPE (type2);
388     }
389
390   /* If an array, get its type.  */
391   type2 = strip_array_types (type2);
392
393   if (pstyle == UBSAN_PRINT_ARRAY)
394     {
395       while (POINTER_TYPE_P (type2))
396         deref_depth++, type2 = TREE_TYPE (type2);
397     }
398
399   if (TYPE_NAME (type2) != NULL)
400     {
401       if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
402         tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
403       else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
404         tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
405     }
406
407   if (tname == NULL)
408     /* We weren't able to determine the type name.  */
409     tname = "<unknown>";
410
411   /* Decorate the type name with '', '*', "struct", or "union".  */
412   pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
413   if (pstyle == UBSAN_PRINT_POINTER)
414     {
415       int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
416                          TYPE_VOLATILE (type2) ? "volatile " : "",
417                          TYPE_READONLY (type2) ? "const " : "",
418                          TYPE_RESTRICT (type2) ? "restrict " : "",
419                          TYPE_ATOMIC (type2) ? "_Atomic " : "",
420                          TREE_CODE (type2) == RECORD_TYPE
421                          ? "struct "
422                          : TREE_CODE (type2) == UNION_TYPE
423                            ? "union " : "", tname,
424                          deref_depth == 0 ? "" : " ");
425       while (deref_depth-- > 0)
426         pretty_name[pos++] = '*';
427       pretty_name[pos++] = '\'';
428       pretty_name[pos] = '\0';
429     }
430   else if (pstyle == UBSAN_PRINT_ARRAY)
431     {
432       /* Pretty print the array dimensions.  */
433       gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
434       tree t = type;
435       int pos = sprintf (pretty_name, "'%s ", tname);
436       while (deref_depth-- > 0)
437         pretty_name[pos++] = '*';
438       while (TREE_CODE (t) == ARRAY_TYPE)
439         {
440           pretty_name[pos++] = '[';
441           tree dom = TYPE_DOMAIN (t);
442           if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
443             pos += sprintf (&pretty_name[pos], HOST_WIDE_INT_PRINT_DEC,
444                             tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
445           else
446             /* ??? We can't determine the variable name; print VLA unspec.  */
447             pretty_name[pos++] = '*';
448           pretty_name[pos++] = ']';
449           t = TREE_TYPE (t);
450         }
451       pretty_name[pos++] = '\'';
452       pretty_name[pos] = '\0';
453
454      /* Save the tree with stripped types.  */
455      type = t;
456     }
457   else
458     sprintf (pretty_name, "'%s'", tname);
459
460   switch (TREE_CODE (type))
461     {
462     case BOOLEAN_TYPE:
463     case ENUMERAL_TYPE:
464     case INTEGER_TYPE:
465       tkind = 0x0000;
466       break;
467     case REAL_TYPE:
468       /* FIXME: libubsan right now only supports float, double and
469          long double type formats.  */
470       if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
471           || TYPE_MODE (type) == TYPE_MODE (double_type_node)
472           || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
473         tkind = 0x0001;
474       else
475         tkind = 0xffff;
476       break;
477     default:
478       tkind = 0xffff;
479       break;
480     }
481   tinfo = get_ubsan_type_info_for_type (type);
482
483   /* Create a new VAR_DECL of type descriptor.  */
484   char tmp_name[32];
485   static unsigned int type_var_id_num;
486   ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
487   decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
488                           dtype);
489   TREE_STATIC (decl) = 1;
490   TREE_PUBLIC (decl) = 0;
491   DECL_ARTIFICIAL (decl) = 1;
492   DECL_IGNORED_P (decl) = 1;
493   DECL_EXTERNAL (decl) = 0;
494
495   size_t len = strlen (pretty_name);
496   tree str = build_string (len + 1, pretty_name);
497   TREE_TYPE (str) = build_array_type (char_type_node,
498                                       build_index_type (size_int (len)));
499   TREE_READONLY (str) = 1;
500   TREE_STATIC (str) = 1;
501   tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
502                                     build_int_cst (short_unsigned_type_node,
503                                                    tkind), NULL_TREE,
504                                     build_int_cst (short_unsigned_type_node,
505                                                    tinfo), NULL_TREE, str);
506   TREE_CONSTANT (ctor) = 1;
507   TREE_STATIC (ctor) = 1;
508   DECL_INITIAL (decl) = ctor;
509   varpool_node::finalize_decl (decl);
510
511   /* Save the VAR_DECL into the hash table.  */
512   decl_for_type_insert (type, decl);
513
514   return build_fold_addr_expr (decl);
515 }
516
517 /* Create a structure for the ubsan library.  NAME is a name of the new
518    structure.  LOCCNT is number of locations, PLOC points to array of
519    locations.  The arguments in ... are of __ubsan_type_descriptor type
520    and there are at most two of them, followed by NULL_TREE, followed
521    by optional extra arguments and another NULL_TREE.  */
522
523 tree
524 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
525 {
526   va_list args;
527   tree ret, t;
528   tree fields[6];
529   vec<tree, va_gc> *saved_args = NULL;
530   size_t i = 0;
531   int j;
532
533   /* Firstly, create a pointer to type descriptor type.  */
534   tree td_type = ubsan_get_type_descriptor_type ();
535   td_type = build_pointer_type (td_type);
536
537   /* Create the structure type.  */
538   ret = make_node (RECORD_TYPE);
539   for (j = 0; j < loccnt; j++)
540     {
541       gcc_checking_assert (i < 2);
542       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
543                               ubsan_get_source_location_type ());
544       DECL_CONTEXT (fields[i]) = ret;
545       if (i)
546         DECL_CHAIN (fields[i - 1]) = fields[i];
547       i++;
548     }
549
550   va_start (args, ploc);
551   for (t = va_arg (args, tree); t != NULL_TREE;
552        i++, t = va_arg (args, tree))
553     {
554       gcc_checking_assert (i < 4);
555       /* Save the tree arguments for later use.  */
556       vec_safe_push (saved_args, t);
557       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
558                               td_type);
559       DECL_CONTEXT (fields[i]) = ret;
560       if (i)
561         DECL_CHAIN (fields[i - 1]) = fields[i];
562     }
563
564   for (t = va_arg (args, tree); t != NULL_TREE;
565        i++, t = va_arg (args, tree))
566     {
567       gcc_checking_assert (i < 6);
568       /* Save the tree arguments for later use.  */
569       vec_safe_push (saved_args, t);
570       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
571                               TREE_TYPE (t));
572       DECL_CONTEXT (fields[i]) = ret;
573       if (i)
574         DECL_CHAIN (fields[i - 1]) = fields[i];
575     }
576   va_end (args);
577
578   tree type_decl = build_decl (input_location, TYPE_DECL,
579                                get_identifier (name), ret);
580   DECL_IGNORED_P (type_decl) = 1;
581   DECL_ARTIFICIAL (type_decl) = 1;
582   TYPE_FIELDS (ret) = fields[0];
583   TYPE_NAME (ret) = type_decl;
584   TYPE_STUB_DECL (ret) = type_decl;
585   layout_type (ret);
586
587   /* Now, fill in the type.  */
588   char tmp_name[32];
589   static unsigned int ubsan_var_id_num;
590   ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
591   tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
592                          ret);
593   TREE_STATIC (var) = 1;
594   TREE_PUBLIC (var) = 0;
595   DECL_ARTIFICIAL (var) = 1;
596   DECL_IGNORED_P (var) = 1;
597   DECL_EXTERNAL (var) = 0;
598
599   vec<constructor_elt, va_gc> *v;
600   vec_alloc (v, i);
601   tree ctor = build_constructor (ret, v);
602
603   /* If desirable, set the __ubsan_source_location element.  */
604   for (j = 0; j < loccnt; j++)
605     {
606       location_t loc = LOCATION_LOCUS (ploc[j]);
607       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
608     } 
609
610   size_t nelts = vec_safe_length (saved_args);
611   for (i = 0; i < nelts; i++)
612     {
613       t = (*saved_args)[i];
614       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
615     }
616
617   TREE_CONSTANT (ctor) = 1;
618   TREE_STATIC (ctor) = 1;
619   DECL_INITIAL (var) = ctor;
620   varpool_node::finalize_decl (var);
621
622   return var;
623 }
624
625 /* Instrument the __builtin_unreachable call.  We just call the libubsan
626    routine instead.  */
627
628 bool
629 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
630 {
631   gimple g;
632   location_t loc = gimple_location (gsi_stmt (*gsi));
633
634   if (flag_sanitize_undefined_trap_on_error)
635     g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
636   else
637     {
638       tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
639                                      NULL_TREE, NULL_TREE);
640       data = build_fold_addr_expr_loc (loc, data);
641       tree fn
642         = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
643       g = gimple_build_call (fn, 1, data);
644     }
645   gimple_set_location (g, loc);
646   gsi_replace (gsi, g, false);
647   return false;
648 }
649
650 /* Return true if T is a call to a libubsan routine.  */
651
652 bool
653 is_ubsan_builtin_p (tree t)
654 {
655   return TREE_CODE (t) == FUNCTION_DECL
656          && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
657          && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
658                      "__builtin___ubsan_", 18) == 0;
659 }
660
661 /* Expand the UBSAN_BOUNDS special builtin function.  */
662
663 bool
664 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
665 {
666   gimple stmt = gsi_stmt (*gsi);
667   location_t loc = gimple_location (stmt);
668   gcc_assert (gimple_call_num_args (stmt) == 3);
669
670   /* Pick up the arguments of the UBSAN_BOUNDS call.  */
671   tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
672   tree index = gimple_call_arg (stmt, 1);
673   tree orig_index_type = TREE_TYPE (index);
674   tree bound = gimple_call_arg (stmt, 2);
675
676   gimple_stmt_iterator gsi_orig = *gsi;
677
678   /* Create condition "if (index > bound)".  */
679   basic_block then_bb, fallthru_bb;
680   gimple_stmt_iterator cond_insert_point
681     = create_cond_insert_point (gsi, false, false, true,
682                                 &then_bb, &fallthru_bb);
683   index = fold_convert (TREE_TYPE (bound), index);
684   index = force_gimple_operand_gsi (&cond_insert_point, index,
685                                     true, NULL_TREE,
686                                     false, GSI_NEW_STMT);
687   gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
688   gimple_set_location (g, loc);
689   gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
690
691   /* Generate __ubsan_handle_out_of_bounds call.  */
692   *gsi = gsi_after_labels (then_bb);
693   if (flag_sanitize_undefined_trap_on_error)
694     g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
695   else
696     {
697       tree data
698         = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
699                              ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
700                              ubsan_type_descriptor (orig_index_type),
701                              NULL_TREE, NULL_TREE);
702       data = build_fold_addr_expr_loc (loc, data);
703       enum built_in_function bcode
704         = (flag_sanitize_recover & SANITIZE_BOUNDS)
705           ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
706           : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
707       tree fn = builtin_decl_explicit (bcode);
708       tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
709                                            true, NULL_TREE, true,
710                                            GSI_SAME_STMT);
711       g = gimple_build_call (fn, 2, data, val);
712     }
713   gimple_set_location (g, loc);
714   gsi_insert_before (gsi, g, GSI_SAME_STMT);
715
716   /* Get rid of the UBSAN_BOUNDS call from the IR.  */
717   unlink_stmt_vdef (stmt);
718   gsi_remove (&gsi_orig, true);
719
720   /* Point GSI to next logical statement.  */
721   *gsi = gsi_start_bb (fallthru_bb);
722   return true;
723 }
724
725 /* Expand UBSAN_NULL internal call.  The type is kept on the ckind
726    argument which is a constant, because the middle-end treats pointer
727    conversions as useless and therefore the type of the first argument
728    could be changed to any other pointer type.  */
729
730 bool
731 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
732 {
733   gimple_stmt_iterator gsi = *gsip;
734   gimple stmt = gsi_stmt (gsi);
735   location_t loc = gimple_location (stmt);
736   gcc_assert (gimple_call_num_args (stmt) == 3);
737   tree ptr = gimple_call_arg (stmt, 0);
738   tree ckind = gimple_call_arg (stmt, 1);
739   tree align = gimple_call_arg (stmt, 2);
740   tree check_align = NULL_TREE;
741   bool check_null;
742
743   basic_block cur_bb = gsi_bb (gsi);
744
745   gimple g;
746   if (!integer_zerop (align))
747     {
748       unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
749       if (compare_tree_int (align, ptralign) == 1)
750         {
751           check_align = make_ssa_name (pointer_sized_int_node);
752           g = gimple_build_assign (check_align, NOP_EXPR, ptr);
753           gimple_set_location (g, loc);
754           gsi_insert_before (&gsi, g, GSI_SAME_STMT);
755         }
756     }
757   check_null = (flag_sanitize & SANITIZE_NULL) != 0;
758
759   if (check_align == NULL_TREE && !check_null)
760     {
761       gsi_remove (gsip, true);
762       /* Unlink the UBSAN_NULLs vops before replacing it.  */
763       unlink_stmt_vdef (stmt);
764       return true;
765     }
766
767   /* Split the original block holding the pointer dereference.  */
768   edge e = split_block (cur_bb, stmt);
769
770   /* Get a hold on the 'condition block', the 'then block' and the
771      'else block'.  */
772   basic_block cond_bb = e->src;
773   basic_block fallthru_bb = e->dest;
774   basic_block then_bb = create_empty_bb (cond_bb);
775   add_bb_to_loop (then_bb, cond_bb->loop_father);
776   loops_state_set (LOOPS_NEED_FIXUP);
777
778   /* Make an edge coming from the 'cond block' into the 'then block';
779      this edge is unlikely taken, so set up the probability accordingly.  */
780   e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
781   e->probability = PROB_VERY_UNLIKELY;
782
783   /* Connect 'then block' with the 'else block'.  This is needed
784      as the ubsan routines we call in the 'then block' are not noreturn.
785      The 'then block' only has one outcoming edge.  */
786   make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
787
788   /* Set up the fallthrough basic block.  */
789   e = find_edge (cond_bb, fallthru_bb);
790   e->flags = EDGE_FALSE_VALUE;
791   e->count = cond_bb->count;
792   e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
793
794   /* Update dominance info for the newly created then_bb; note that
795      fallthru_bb's dominance info has already been updated by
796      split_block.  */
797   if (dom_info_available_p (CDI_DOMINATORS))
798     set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
799
800   /* Put the ubsan builtin call into the newly created BB.  */
801   if (flag_sanitize_undefined_trap_on_error)
802     g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
803   else
804     {
805       enum built_in_function bcode
806         = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
807                                     | (check_null ? SANITIZE_NULL : 0)))
808           ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
809           : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
810       tree fn = builtin_decl_implicit (bcode);
811       tree data
812         = ubsan_create_data ("__ubsan_null_data", 1, &loc,
813                              ubsan_type_descriptor (TREE_TYPE (ckind),
814                                                     UBSAN_PRINT_POINTER),
815                              NULL_TREE,
816                              align,
817                              fold_convert (unsigned_char_type_node, ckind),
818                              NULL_TREE);
819       data = build_fold_addr_expr_loc (loc, data);
820       g = gimple_build_call (fn, 2, data,
821                              check_align ? check_align
822                              : build_zero_cst (pointer_sized_int_node));
823     }
824   gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
825   gimple_set_location (g, loc);
826   gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
827
828   /* Unlink the UBSAN_NULLs vops before replacing it.  */
829   unlink_stmt_vdef (stmt);
830
831   if (check_null)
832     {
833       g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
834                              NULL_TREE, NULL_TREE);
835       gimple_set_location (g, loc);
836
837       /* Replace the UBSAN_NULL with a GIMPLE_COND stmt.  */
838       gsi_replace (&gsi, g, false);
839     }
840
841   if (check_align)
842     {
843       if (check_null)
844         {
845           /* Split the block with the condition again.  */
846           e = split_block (cond_bb, stmt);
847           basic_block cond1_bb = e->src;
848           basic_block cond2_bb = e->dest;
849
850           /* Make an edge coming from the 'cond1 block' into the 'then block';
851              this edge is unlikely taken, so set up the probability
852              accordingly.  */
853           e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
854           e->probability = PROB_VERY_UNLIKELY;
855
856           /* Set up the fallthrough basic block.  */
857           e = find_edge (cond1_bb, cond2_bb);
858           e->flags = EDGE_FALSE_VALUE;
859           e->count = cond1_bb->count;
860           e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
861
862           /* Update dominance info.  */
863           if (dom_info_available_p (CDI_DOMINATORS))
864             {
865               set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
866               set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
867             }
868
869           gsi2 = gsi_start_bb (cond2_bb);
870         }
871
872       tree mask = build_int_cst (pointer_sized_int_node,
873                                  tree_to_uhwi (align) - 1);
874       g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
875                                BIT_AND_EXPR, check_align, mask);
876       gimple_set_location (g, loc);
877       if (check_null)
878         gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
879       else
880         gsi_insert_before (&gsi, g, GSI_SAME_STMT);
881
882       g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
883                              build_int_cst (pointer_sized_int_node, 0),
884                              NULL_TREE, NULL_TREE);
885       gimple_set_location (g, loc);
886       if (check_null)
887         gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
888       else
889         /* Replace the UBSAN_NULL with a GIMPLE_COND stmt.  */
890         gsi_replace (&gsi, g, false);
891     }
892   return false;
893 }
894
895 /* Expand UBSAN_OBJECT_SIZE internal call.  */
896
897 bool
898 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
899 {
900   gimple stmt = gsi_stmt (*gsi);
901   location_t loc = gimple_location (stmt);
902   gcc_assert (gimple_call_num_args (stmt) == 4);
903
904   tree ptr = gimple_call_arg (stmt, 0);
905   tree offset = gimple_call_arg (stmt, 1);
906   tree size = gimple_call_arg (stmt, 2);
907   tree ckind = gimple_call_arg (stmt, 3);
908   gimple_stmt_iterator gsi_orig = *gsi;
909   gimple g;
910
911   /* See if we can discard the check.  */
912   if (TREE_CODE (size) != INTEGER_CST
913       || integer_all_onesp (size))
914     /* Yes, __builtin_object_size couldn't determine the
915        object size.  */;
916   else
917     {
918       /* if (offset > objsize) */
919       basic_block then_bb, fallthru_bb;
920       gimple_stmt_iterator cond_insert_point
921         = create_cond_insert_point (gsi, false, false, true,
922                                     &then_bb, &fallthru_bb);
923       g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
924       gimple_set_location (g, loc);
925       gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
926
927       /* Generate __ubsan_handle_type_mismatch call.  */
928       *gsi = gsi_after_labels (then_bb);
929       if (flag_sanitize_undefined_trap_on_error)
930         g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
931       else
932         {
933           tree data
934             = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
935                                  ubsan_type_descriptor (TREE_TYPE (ptr),
936                                                         UBSAN_PRINT_POINTER),
937                                  NULL_TREE,
938                                  build_zero_cst (pointer_sized_int_node),
939                                  ckind,
940                                  NULL_TREE);
941           data = build_fold_addr_expr_loc (loc, data);
942           enum built_in_function bcode
943             = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
944               ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
945               : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
946           tree p = make_ssa_name (pointer_sized_int_node);
947           g = gimple_build_assign (p, NOP_EXPR, ptr);
948           gimple_set_location (g, loc);
949           gsi_insert_before (gsi, g, GSI_SAME_STMT);
950           g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
951         }
952       gimple_set_location (g, loc);
953       gsi_insert_before (gsi, g, GSI_SAME_STMT);
954
955       /* Point GSI to next logical statement.  */
956       *gsi = gsi_start_bb (fallthru_bb);
957     }
958
959   /* Get rid of the UBSAN_OBJECT_SIZE call from the IR.  */
960   unlink_stmt_vdef (stmt);
961   gsi_remove (&gsi_orig, true);
962   return gsi_end_p (*gsi);
963 }
964
965 /* Instrument a memory reference.  BASE is the base of MEM, IS_LHS says
966    whether the pointer is on the left hand side of the assignment.  */
967
968 static void
969 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
970                     bool is_lhs)
971 {
972   enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
973   unsigned int align = 0;
974   if (flag_sanitize & SANITIZE_ALIGNMENT)
975     {
976       align = min_align_of_type (TREE_TYPE (base));
977       if (align <= 1)
978         align = 0;
979     }
980   if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
981     return;
982   tree t = TREE_OPERAND (base, 0);
983   if (!POINTER_TYPE_P (TREE_TYPE (t)))
984     return;
985   if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && mem != base)
986     ikind = UBSAN_MEMBER_ACCESS;
987   tree kind = build_int_cst (TREE_TYPE (t), ikind);
988   tree alignt = build_int_cst (pointer_sized_int_node, align);
989   gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
990   gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
991   gsi_insert_before (iter, g, GSI_SAME_STMT);
992 }
993
994 /* Perform the pointer instrumentation.  */
995
996 static void
997 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
998 {
999   gimple stmt = gsi_stmt (gsi);
1000   tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1001   tree base = get_base_address (t);
1002   const enum tree_code code = TREE_CODE (base);
1003   if (code == MEM_REF
1004       && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1005     instrument_mem_ref (t, base, &gsi, is_lhs);
1006 }
1007
1008 /* Build an ubsan builtin call for the signed-integer-overflow
1009    sanitization.  CODE says what kind of builtin are we building,
1010    LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1011    are operands of the binary operation.  */
1012
1013 tree
1014 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1015                               tree op0, tree op1)
1016 {
1017   if (flag_sanitize_undefined_trap_on_error)
1018     return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1019
1020   tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1021                                  ubsan_type_descriptor (lhstype), NULL_TREE,
1022                                  NULL_TREE);
1023   enum built_in_function fn_code;
1024
1025   switch (code)
1026     {
1027     case PLUS_EXPR:
1028       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1029                 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1030                 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1031       break;
1032     case MINUS_EXPR:
1033       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1034                 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1035                 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1036       break;
1037     case MULT_EXPR:
1038       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1039                 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1040                 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1041       break;
1042     case NEGATE_EXPR:
1043       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1044                 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1045                 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1046       break;
1047     default:
1048       gcc_unreachable ();
1049     }
1050   tree fn = builtin_decl_explicit (fn_code);
1051   return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1052                               build_fold_addr_expr_loc (loc, data),
1053                               ubsan_encode_value (op0, true),
1054                               op1 ? ubsan_encode_value (op1, true)
1055                                   : NULL_TREE);
1056 }
1057
1058 /* Perform the signed integer instrumentation.  GSI is the iterator
1059    pointing at statement we are trying to instrument.  */
1060
1061 static void
1062 instrument_si_overflow (gimple_stmt_iterator gsi)
1063 {
1064   gimple stmt = gsi_stmt (gsi);
1065   tree_code code = gimple_assign_rhs_code (stmt);
1066   tree lhs = gimple_assign_lhs (stmt);
1067   tree lhstype = TREE_TYPE (lhs);
1068   tree a, b;
1069   gimple g;
1070
1071   /* If this is not a signed operation, don't instrument anything here.
1072      Also punt on bit-fields.  */
1073   if (!INTEGRAL_TYPE_P (lhstype)
1074       || TYPE_OVERFLOW_WRAPS (lhstype)
1075       || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1076     return;
1077
1078   switch (code)
1079     {
1080     case MINUS_EXPR:
1081     case PLUS_EXPR:
1082     case MULT_EXPR:
1083       /* Transform
1084          i = u {+,-,*} 5;
1085          into
1086          i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5);  */
1087       a = gimple_assign_rhs1 (stmt);
1088       b = gimple_assign_rhs2 (stmt);
1089       g = gimple_build_call_internal (code == PLUS_EXPR
1090                                       ? IFN_UBSAN_CHECK_ADD
1091                                       : code == MINUS_EXPR
1092                                       ? IFN_UBSAN_CHECK_SUB
1093                                       : IFN_UBSAN_CHECK_MUL, 2, a, b);
1094       gimple_call_set_lhs (g, lhs);
1095       gsi_replace (&gsi, g, false);
1096       break;
1097     case NEGATE_EXPR:
1098       /* Represent i = -u;
1099          as
1100          i = UBSAN_CHECK_SUB (0, u);  */
1101       a = build_int_cst (lhstype, 0);
1102       b = gimple_assign_rhs1 (stmt);
1103       g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1104       gimple_call_set_lhs (g, lhs);
1105       gsi_replace (&gsi, g, false);
1106       break;
1107     case ABS_EXPR:
1108       /* Transform i = ABS_EXPR<u>;
1109          into
1110          _N = UBSAN_CHECK_SUB (0, u);
1111          i = ABS_EXPR<_N>;  */
1112       a = build_int_cst (lhstype, 0);
1113       b = gimple_assign_rhs1 (stmt);
1114       g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1115       a = make_ssa_name (lhstype);
1116       gimple_call_set_lhs (g, a);
1117       gimple_set_location (g, gimple_location (stmt));
1118       gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1119       gimple_assign_set_rhs1 (stmt, a);
1120       update_stmt (stmt);
1121       break;
1122     default:
1123       break;
1124     }
1125 }
1126
1127 /* Instrument loads from (non-bitfield) bool and C++ enum values
1128    to check if the memory value is outside of the range of the valid
1129    type values.  */
1130
1131 static void
1132 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1133 {
1134   gimple stmt = gsi_stmt (*gsi);
1135   tree rhs = gimple_assign_rhs1 (stmt);
1136   tree type = TREE_TYPE (rhs);
1137   tree minv = NULL_TREE, maxv = NULL_TREE;
1138
1139   if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1140     {
1141       minv = boolean_false_node;
1142       maxv = boolean_true_node;
1143     }
1144   else if (TREE_CODE (type) == ENUMERAL_TYPE
1145            && (flag_sanitize & SANITIZE_ENUM)
1146            && TREE_TYPE (type) != NULL_TREE
1147            && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1148            && (TYPE_PRECISION (TREE_TYPE (type))
1149                < GET_MODE_PRECISION (TYPE_MODE (type))))
1150     {
1151       minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1152       maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1153     }
1154   else
1155     return;
1156
1157   int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1158   HOST_WIDE_INT bitsize, bitpos;
1159   tree offset;
1160   machine_mode mode;
1161   int volatilep = 0, unsignedp = 0;
1162   tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1163                                    &unsignedp, &volatilep, false);
1164   tree utype = build_nonstandard_integer_type (modebitsize, 1);
1165
1166   if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1167       || (bitpos % modebitsize) != 0
1168       || bitsize != modebitsize
1169       || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1170       || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1171     return;
1172
1173   bool can_throw = stmt_could_throw_p (stmt);
1174   location_t loc = gimple_location (stmt);
1175   tree lhs = gimple_assign_lhs (stmt);
1176   tree ptype = build_pointer_type (TREE_TYPE (rhs));
1177   tree atype = reference_alias_ptr_type (rhs);
1178   gimple g = gimple_build_assign (make_ssa_name (ptype),
1179                                   build_fold_addr_expr (rhs));
1180   gimple_set_location (g, loc);
1181   gsi_insert_before (gsi, g, GSI_SAME_STMT);
1182   tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1183                      build_int_cst (atype, 0));
1184   tree urhs = make_ssa_name (utype);
1185   if (can_throw)
1186     {
1187       gimple_assign_set_lhs (stmt, urhs);
1188       g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1189       gimple_set_location (g, loc);
1190       edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1191       gsi_insert_on_edge_immediate (e, g);
1192       gimple_assign_set_rhs_from_tree (gsi, mem);
1193       update_stmt (stmt);
1194       *gsi = gsi_for_stmt (g);
1195       g = stmt;
1196     }
1197   else
1198     {
1199       g = gimple_build_assign (urhs, mem);
1200       gimple_set_location (g, loc);
1201       gsi_insert_before (gsi, g, GSI_SAME_STMT);
1202     }
1203   minv = fold_convert (utype, minv);
1204   maxv = fold_convert (utype, maxv);
1205   if (!integer_zerop (minv))
1206     {
1207       g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1208       gimple_set_location (g, loc);
1209       gsi_insert_before (gsi, g, GSI_SAME_STMT);
1210     }
1211
1212   gimple_stmt_iterator gsi2 = *gsi;
1213   basic_block then_bb, fallthru_bb;
1214   *gsi = create_cond_insert_point (gsi, true, false, true,
1215                                    &then_bb, &fallthru_bb);
1216   g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1217                          int_const_binop (MINUS_EXPR, maxv, minv),
1218                          NULL_TREE, NULL_TREE);
1219   gimple_set_location (g, loc);
1220   gsi_insert_after (gsi, g, GSI_NEW_STMT);
1221
1222   if (!can_throw)
1223     {
1224       gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1225       update_stmt (stmt);
1226     }
1227
1228   gsi2 = gsi_after_labels (then_bb);
1229   if (flag_sanitize_undefined_trap_on_error)
1230     g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1231   else
1232     {
1233       tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1234                                      ubsan_type_descriptor (type), NULL_TREE,
1235                                      NULL_TREE);
1236       data = build_fold_addr_expr_loc (loc, data);
1237       enum built_in_function bcode
1238         = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1239                                     ? SANITIZE_BOOL : SANITIZE_ENUM))
1240           ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1241           : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1242       tree fn = builtin_decl_explicit (bcode);
1243
1244       tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1245                                            true, NULL_TREE, true,
1246                                            GSI_SAME_STMT);
1247       g = gimple_build_call (fn, 2, data, val);
1248     }
1249   gimple_set_location (g, loc);
1250   gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1251   *gsi = gsi_for_stmt (stmt);
1252 }
1253
1254 /* Instrument float point-to-integer conversion.  TYPE is an integer type of
1255    destination, EXPR is floating-point expression.  */
1256
1257 tree
1258 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1259 {
1260   tree expr_type = TREE_TYPE (expr);
1261   tree t, tt, fn, min, max;
1262   machine_mode mode = TYPE_MODE (expr_type);
1263   int prec = TYPE_PRECISION (type);
1264   bool uns_p = TYPE_UNSIGNED (type);
1265
1266   /* Float to integer conversion first truncates toward zero, so
1267      even signed char c = 127.875f; is not problematic.
1268      Therefore, we should complain only if EXPR is unordered or smaller
1269      or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1270      TYPE_MAX_VALUE + 1.0.  */
1271   if (REAL_MODE_FORMAT (mode)->b == 2)
1272     {
1273       /* For maximum, TYPE_MAX_VALUE might not be representable
1274          in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1275          EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1276          either representable or infinity.  */
1277       REAL_VALUE_TYPE maxval = dconst1;
1278       SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1279       real_convert (&maxval, mode, &maxval);
1280       max = build_real (expr_type, maxval);
1281
1282       /* For unsigned, assume -1.0 is always representable.  */
1283       if (uns_p)
1284         min = build_minus_one_cst (expr_type);
1285       else
1286         {
1287           /* TYPE_MIN_VALUE is generally representable (or -inf),
1288              but TYPE_MIN_VALUE - 1.0 might not be.  */
1289           REAL_VALUE_TYPE minval = dconstm1, minval2;
1290           SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1291           real_convert (&minval, mode, &minval);
1292           real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1293           real_convert (&minval2, mode, &minval2);
1294           if (real_compare (EQ_EXPR, &minval, &minval2)
1295               && !real_isinf (&minval))
1296             {
1297               /* If TYPE_MIN_VALUE - 1.0 is not representable and
1298                  rounds to TYPE_MIN_VALUE, we need to subtract
1299                  more.  As REAL_MODE_FORMAT (mode)->p is the number
1300                  of base digits, we want to subtract a number that
1301                  will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1302                  times smaller than minval.  */
1303               minval2 = dconst1;
1304               gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1305               SET_REAL_EXP (&minval2,
1306                             REAL_EXP (&minval2) + prec - 1
1307                             - REAL_MODE_FORMAT (mode)->p + 1);
1308               real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1309               real_convert (&minval2, mode, &minval2);
1310             }
1311           min = build_real (expr_type, minval2);
1312         }
1313     }
1314   else if (REAL_MODE_FORMAT (mode)->b == 10)
1315     {
1316       /* For _Decimal128 up to 34 decimal digits, - sign,
1317          dot, e, exponent.  */
1318       char buf[64];
1319       mpfr_t m;
1320       int p = REAL_MODE_FORMAT (mode)->p;
1321       REAL_VALUE_TYPE maxval, minval;
1322
1323       /* Use mpfr_snprintf rounding to compute the smallest
1324          representable decimal number greater or equal than
1325          1 << (prec - !uns_p).  */
1326       mpfr_init2 (m, prec + 2);
1327       mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1328       mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1329       decimal_real_from_string (&maxval, buf);
1330       max = build_real (expr_type, maxval);
1331
1332       /* For unsigned, assume -1.0 is always representable.  */
1333       if (uns_p)
1334         min = build_minus_one_cst (expr_type);
1335       else
1336         {
1337           /* Use mpfr_snprintf rounding to compute the largest
1338              representable decimal number less or equal than
1339              (-1 << (prec - 1)) - 1.  */
1340           mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1341           mpfr_sub_ui (m, m, 1, GMP_RNDN);
1342           mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1343           decimal_real_from_string (&minval, buf);
1344           min = build_real (expr_type, minval);
1345         }
1346       mpfr_clear (m);
1347     }
1348   else
1349     return NULL_TREE;
1350
1351   if (flag_sanitize_undefined_trap_on_error)
1352     fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1353   else
1354     {
1355       /* Create the __ubsan_handle_float_cast_overflow fn call.  */
1356       tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1357                                      NULL, ubsan_type_descriptor (expr_type),
1358                                      ubsan_type_descriptor (type), NULL_TREE,
1359                                      NULL_TREE);
1360       enum built_in_function bcode
1361         = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1362           ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1363           : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1364       fn = builtin_decl_explicit (bcode);
1365       fn = build_call_expr_loc (loc, fn, 2,
1366                                 build_fold_addr_expr_loc (loc, data),
1367                                 ubsan_encode_value (expr, false));
1368     }
1369
1370   t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1371   tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1372   return fold_build3 (COND_EXPR, void_type_node,
1373                       fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt),
1374                       fn, integer_zero_node);
1375 }
1376
1377 /* Instrument values passed to function arguments with nonnull attribute.  */
1378
1379 static void
1380 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1381 {
1382   gimple stmt = gsi_stmt (*gsi);
1383   location_t loc[2];
1384   /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1385      while for nonnull sanitization it is clear.  */
1386   int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1387   flag_delete_null_pointer_checks = 1;
1388   loc[0] = gimple_location (stmt);
1389   loc[1] = UNKNOWN_LOCATION;
1390   for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1391     {
1392       tree arg = gimple_call_arg (stmt, i);
1393       if (POINTER_TYPE_P (TREE_TYPE (arg))
1394           && infer_nonnull_range (stmt, arg, false, true))
1395         {
1396           gimple g;
1397           if (!is_gimple_val (arg))
1398             {
1399               g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1400               gimple_set_location (g, loc[0]);
1401               gsi_insert_before (gsi, g, GSI_SAME_STMT);
1402               arg = gimple_assign_lhs (g);
1403             }
1404
1405           basic_block then_bb, fallthru_bb;
1406           *gsi = create_cond_insert_point (gsi, true, false, true,
1407                                            &then_bb, &fallthru_bb);
1408           g = gimple_build_cond (EQ_EXPR, arg,
1409                                  build_zero_cst (TREE_TYPE (arg)),
1410                                  NULL_TREE, NULL_TREE);
1411           gimple_set_location (g, loc[0]);
1412           gsi_insert_after (gsi, g, GSI_NEW_STMT);
1413
1414           *gsi = gsi_after_labels (then_bb);
1415           if (flag_sanitize_undefined_trap_on_error)
1416             g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1417           else
1418             {
1419               tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1420                                              2, loc, NULL_TREE,
1421                                              build_int_cst (integer_type_node,
1422                                                             i + 1),
1423                                              NULL_TREE);
1424               data = build_fold_addr_expr_loc (loc[0], data);
1425               enum built_in_function bcode
1426                 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1427                   ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1428                   : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1429               tree fn = builtin_decl_explicit (bcode);
1430
1431               g = gimple_build_call (fn, 1, data);
1432             }
1433           gimple_set_location (g, loc[0]);
1434           gsi_insert_before (gsi, g, GSI_SAME_STMT);
1435         }
1436       *gsi = gsi_for_stmt (stmt);
1437     }
1438   flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1439 }
1440
1441 /* Instrument returns in functions with returns_nonnull attribute.  */
1442
1443 static void
1444 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1445 {
1446   greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1447   location_t loc[2];
1448   tree arg = gimple_return_retval (stmt);
1449   /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1450      while for nonnull return sanitization it is clear.  */
1451   int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1452   flag_delete_null_pointer_checks = 1;
1453   loc[0] = gimple_location (stmt);
1454   loc[1] = UNKNOWN_LOCATION;
1455   if (arg
1456       && POINTER_TYPE_P (TREE_TYPE (arg))
1457       && is_gimple_val (arg)
1458       && infer_nonnull_range (stmt, arg, false, true))
1459     {
1460       basic_block then_bb, fallthru_bb;
1461       *gsi = create_cond_insert_point (gsi, true, false, true,
1462                                        &then_bb, &fallthru_bb);
1463       gimple g = gimple_build_cond (EQ_EXPR, arg,
1464                                     build_zero_cst (TREE_TYPE (arg)),
1465                                     NULL_TREE, NULL_TREE);
1466       gimple_set_location (g, loc[0]);
1467       gsi_insert_after (gsi, g, GSI_NEW_STMT);
1468
1469       *gsi = gsi_after_labels (then_bb);
1470       if (flag_sanitize_undefined_trap_on_error)
1471         g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1472       else
1473         {
1474           tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1475                                          2, loc, NULL_TREE, NULL_TREE);
1476           data = build_fold_addr_expr_loc (loc[0], data);
1477           enum built_in_function bcode
1478             = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1479               ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1480               : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1481           tree fn = builtin_decl_explicit (bcode);
1482
1483           g = gimple_build_call (fn, 1, data);
1484         }
1485       gimple_set_location (g, loc[0]);
1486       gsi_insert_before (gsi, g, GSI_SAME_STMT);
1487       *gsi = gsi_for_stmt (stmt);
1488     }
1489   flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1490 }
1491
1492 /* Instrument memory references.  Here we check whether the pointer
1493    points to an out-of-bounds location.  */
1494
1495 static void
1496 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1497 {
1498   gimple stmt = gsi_stmt (*gsi);
1499   location_t loc = gimple_location (stmt);
1500   tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1501   tree type;
1502   tree index = NULL_TREE;
1503   HOST_WIDE_INT size_in_bytes;
1504
1505   type = TREE_TYPE (t);
1506   if (VOID_TYPE_P (type))
1507     return;
1508
1509   switch (TREE_CODE (t))
1510     {
1511     case COMPONENT_REF:
1512       if (TREE_CODE (t) == COMPONENT_REF
1513           && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1514         {
1515           tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1516           t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1517                       repr, NULL_TREE);
1518         }
1519       break;
1520     case ARRAY_REF:
1521       index = TREE_OPERAND (t, 1);
1522       break;
1523     case INDIRECT_REF:
1524     case MEM_REF:
1525     case VAR_DECL:
1526     case PARM_DECL:
1527     case RESULT_DECL:
1528       break;
1529     default:
1530       return;
1531     }
1532
1533   size_in_bytes = int_size_in_bytes (type);
1534   if (size_in_bytes <= 0)
1535     return;
1536
1537   HOST_WIDE_INT bitsize, bitpos;
1538   tree offset;
1539   machine_mode mode;
1540   int volatilep = 0, unsignedp = 0;
1541   tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1542                                     &unsignedp, &volatilep, false);
1543
1544   if (bitpos % BITS_PER_UNIT != 0
1545       || bitsize != size_in_bytes * BITS_PER_UNIT)
1546     return;
1547
1548   bool decl_p = DECL_P (inner);
1549   tree base;
1550   if (decl_p)
1551     base = inner;
1552   else if (TREE_CODE (inner) == MEM_REF)
1553     base = TREE_OPERAND (inner, 0);
1554   else
1555     return;
1556   tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1557
1558   while (TREE_CODE (base) == SSA_NAME)
1559     {
1560       gimple def_stmt = SSA_NAME_DEF_STMT (base);
1561       if (gimple_assign_ssa_name_copy_p (def_stmt)
1562           || (gimple_assign_cast_p (def_stmt)
1563               && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1564           || (is_gimple_assign (def_stmt)
1565               && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1566         base = gimple_assign_rhs1 (def_stmt);
1567       else
1568         break;
1569     }
1570
1571   if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1572     return;
1573
1574   tree sizet;
1575   tree base_addr = base;
1576   if (decl_p)
1577     base_addr = build1 (ADDR_EXPR,
1578                         build_pointer_type (TREE_TYPE (base)), base);
1579   unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1580   if (size != (unsigned HOST_WIDE_INT) -1)
1581     sizet = build_int_cst (sizetype, size);
1582   else if (optimize)
1583     {
1584       if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1585         loc = input_location;
1586       /* Generate __builtin_object_size call.  */
1587       sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1588       sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1589                                    integer_zero_node);
1590       sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1591                                         GSI_SAME_STMT);
1592     }
1593   else
1594     return;
1595
1596   /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1597      call.  */
1598   /* ptr + sizeof (*ptr) - base */
1599   t = fold_build2 (MINUS_EXPR, sizetype,
1600                    fold_convert (pointer_sized_int_node, ptr),
1601                    fold_convert (pointer_sized_int_node, base_addr));
1602   t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1603
1604   /* Perhaps we can omit the check.  */
1605   if (TREE_CODE (t) == INTEGER_CST
1606       && TREE_CODE (sizet) == INTEGER_CST
1607       && tree_int_cst_le (t, sizet))
1608     return;
1609
1610   if (index != NULL_TREE
1611       && TREE_CODE (index) == SSA_NAME
1612       && TREE_CODE (sizet) == INTEGER_CST)
1613     {
1614       gimple def = SSA_NAME_DEF_STMT (index);
1615       if (is_gimple_assign (def)
1616           && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1617           && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1618         {
1619           tree cst = gimple_assign_rhs2 (def);
1620           tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1621                                  TYPE_SIZE_UNIT (type));
1622           if (tree_int_cst_sgn (cst) >= 0
1623               && tree_int_cst_lt (cst, sz))
1624             return;
1625         }
1626     }
1627
1628   /* Nope.  Emit the check.  */
1629   t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1630                                 GSI_SAME_STMT);
1631   ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1632                                   GSI_SAME_STMT);
1633   tree ckind = build_int_cst (unsigned_char_type_node,
1634                               is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1635   gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1636                                          ptr, t, sizet, ckind);
1637   gimple_set_location (g, loc);
1638   gsi_insert_before (gsi, g, GSI_SAME_STMT);
1639 }
1640
1641 namespace {
1642
1643 const pass_data pass_data_ubsan =
1644 {
1645   GIMPLE_PASS, /* type */
1646   "ubsan", /* name */
1647   OPTGROUP_NONE, /* optinfo_flags */
1648   TV_TREE_UBSAN, /* tv_id */
1649   ( PROP_cfg | PROP_ssa ), /* properties_required */
1650   0, /* properties_provided */
1651   0, /* properties_destroyed */
1652   0, /* todo_flags_start */
1653   TODO_update_ssa, /* todo_flags_finish */
1654 };
1655
1656 class pass_ubsan : public gimple_opt_pass
1657 {
1658 public:
1659   pass_ubsan (gcc::context *ctxt)
1660     : gimple_opt_pass (pass_data_ubsan, ctxt)
1661   {}
1662
1663   /* opt_pass methods: */
1664   virtual bool gate (function *)
1665     {
1666       return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1667                               | SANITIZE_BOOL | SANITIZE_ENUM
1668                               | SANITIZE_ALIGNMENT
1669                               | SANITIZE_NONNULL_ATTRIBUTE
1670                               | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1671                               | SANITIZE_OBJECT_SIZE)
1672              && current_function_decl != NULL_TREE
1673              && !lookup_attribute ("no_sanitize_undefined",
1674                                    DECL_ATTRIBUTES (current_function_decl));
1675     }
1676
1677   virtual unsigned int execute (function *);
1678
1679 }; // class pass_ubsan
1680
1681 unsigned int
1682 pass_ubsan::execute (function *fun)
1683 {
1684   basic_block bb;
1685   gimple_stmt_iterator gsi;
1686
1687   initialize_sanitizer_builtins ();
1688
1689   FOR_EACH_BB_FN (bb, fun)
1690     {
1691       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1692         {
1693           gimple stmt = gsi_stmt (gsi);
1694           if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1695             {
1696               gsi_next (&gsi);
1697               continue;
1698             }
1699
1700           if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1701               && is_gimple_assign (stmt))
1702             instrument_si_overflow (gsi);
1703
1704           if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1705             {
1706               if (gimple_store_p (stmt))
1707                 instrument_null (gsi, true);
1708               if (gimple_assign_load_p (stmt))
1709                 instrument_null (gsi, false);
1710             }
1711
1712           if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1713               && gimple_assign_load_p (stmt))
1714             {
1715               instrument_bool_enum_load (&gsi);
1716               bb = gimple_bb (stmt);
1717             }
1718
1719           if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1720               && is_gimple_call (stmt)
1721               && !gimple_call_internal_p (stmt))
1722             {
1723               instrument_nonnull_arg (&gsi);
1724               bb = gimple_bb (stmt);
1725             }
1726
1727           if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1728               && gimple_code (stmt) == GIMPLE_RETURN)
1729             {
1730               instrument_nonnull_return (&gsi);
1731               bb = gimple_bb (stmt);
1732             }
1733
1734           if (flag_sanitize & SANITIZE_OBJECT_SIZE)
1735             {
1736               if (gimple_store_p (stmt))
1737                 instrument_object_size (&gsi, true);
1738               if (gimple_assign_load_p (stmt))
1739                 instrument_object_size (&gsi, false);
1740             }
1741
1742           gsi_next (&gsi);
1743         }
1744     }
1745   return 0;
1746 }
1747
1748 } // anon namespace
1749
1750 gimple_opt_pass *
1751 make_pass_ubsan (gcc::context *ctxt)
1752 {
1753   return new pass_ubsan (ctxt);
1754 }
1755
1756 #include "gt-ubsan.h"