1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2    Copyright (C) 2013-2020 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 "backend.h"
25 #include "rtl.h"
26 #include "c-family/c-common.h"
27 #include "gimple.h"
28 #include "cfghooks.h"
29 #include "tree-pass.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "ssa.h"
33 #include "cgraph.h"
34 #include "tree-pretty-print.h"
35 #include "stor-layout.h"
36 #include "cfganal.h"
37 #include "gimple-iterator.h"
38 #include "output.h"
39 #include "cfgloop.h"
40 #include "ubsan.h"
41 #include "expr.h"
42 #include "stringpool.h"
43 #include "attribs.h"
44 #include "asan.h"
45 #include "gimplify-me.h"
46 #include "dfp.h"
47 #include "builtins.h"
48 #include "tree-object-size.h"
49 #include "tree-cfg.h"
50 #include "gimple-fold.h"
51 #include "varasm.h"
52 
53 /* Map from a tree to a VAR_DECL tree.  */
54 
55 struct GTY((for_user)) tree_type_map {
56   struct tree_map_base type;
57   tree decl;
58 };
59 
60 struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
61 {
62   static inline hashval_t
hashtree_type_map_cache_hasher63   hash (tree_type_map *t)
64   {
65     return TYPE_UID (t->type.from);
66   }
67 
68   static inline bool
equaltree_type_map_cache_hasher69   equal (tree_type_map *a, tree_type_map *b)
70   {
71     return a->type.from == b->type.from;
72   }
73 
74   static int
keep_cache_entrytree_type_map_cache_hasher75   keep_cache_entry (tree_type_map *&m)
76   {
77     return ggc_marked_p (m->type.from);
78   }
79 };
80 
81 static GTY ((cache))
82      hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
83 
84 /* Lookup a VAR_DECL for TYPE, and return it if we find one.  */
85 
86 static tree
decl_for_type_lookup(tree type)87 decl_for_type_lookup (tree type)
88 {
89   /* If the hash table is not initialized yet, create it now.  */
90   if (decl_tree_for_type == NULL)
91     {
92       decl_tree_for_type
93 	= hash_table<tree_type_map_cache_hasher>::create_ggc (10);
94       /* That also means we don't have to bother with the lookup.  */
95       return NULL_TREE;
96     }
97 
98   struct tree_type_map *h, in;
99   in.type.from = type;
100 
101   h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
102   return h ? h->decl : NULL_TREE;
103 }
104 
105 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable.  */
106 
107 static void
decl_for_type_insert(tree type,tree decl)108 decl_for_type_insert (tree type, tree decl)
109 {
110   struct tree_type_map *h;
111 
112   h = ggc_alloc<tree_type_map> ();
113   h->type.from = type;
114   h->decl = decl;
115   *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
116 }
117 
118 /* Helper routine, which encodes a value in the pointer_sized_int_node.
119    Arguments with precision <= POINTER_SIZE are passed directly,
120    the rest is passed by reference.  T is a value we are to encode.
121    PHASE determines when this function is called.  */
122 
123 tree
ubsan_encode_value(tree t,enum ubsan_encode_value_phase phase)124 ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase)
125 {
126   tree type = TREE_TYPE (t);
127   scalar_mode mode = SCALAR_TYPE_MODE (type);
128   const unsigned int bitsize = GET_MODE_BITSIZE (mode);
129   if (bitsize <= POINTER_SIZE)
130     switch (TREE_CODE (type))
131       {
132       case BOOLEAN_TYPE:
133       case ENUMERAL_TYPE:
134       case INTEGER_TYPE:
135 	return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
136       case REAL_TYPE:
137 	{
138 	  tree itype = build_nonstandard_integer_type (bitsize, true);
139 	  t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
140 	  return fold_convert (pointer_sized_int_node, t);
141 	}
142       default:
143 	gcc_unreachable ();
144       }
145   else
146     {
147       if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
148 	{
149 	  /* The reason for this is that we don't want to pessimize
150 	     code by making vars unnecessarily addressable.  */
151 	  tree var;
152 	  if (phase != UBSAN_ENCODE_VALUE_GENERIC)
153 	    {
154 	      var = create_tmp_var (type);
155 	      mark_addressable (var);
156 	    }
157 	  else
158 	    {
159 	      var = create_tmp_var_raw (type);
160 	      TREE_ADDRESSABLE (var) = 1;
161 	      DECL_CONTEXT (var) = current_function_decl;
162 	    }
163 	  if (phase == UBSAN_ENCODE_VALUE_RTL)
164 	    {
165 	      rtx mem = assign_stack_temp_for_type (mode, GET_MODE_SIZE (mode),
166 						    type);
167 	      SET_DECL_RTL (var, mem);
168 	      expand_assignment (var, t, false);
169 	      return build_fold_addr_expr (var);
170 	    }
171 	  if (phase != UBSAN_ENCODE_VALUE_GENERIC)
172 	    {
173 	      tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
174 	      t = build_fold_addr_expr (var);
175 	      return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
176 	    }
177 	  else
178 	    {
179 	      var = build4 (TARGET_EXPR, type, var, t, NULL_TREE, NULL_TREE);
180 	      return build_fold_addr_expr (var);
181 	    }
182 	}
183       else
184 	return build_fold_addr_expr (t);
185     }
186 }
187 
188 /* Cached ubsan_get_type_descriptor_type () return value.  */
189 static GTY(()) tree ubsan_type_descriptor_type;
190 
191 /* Build
192    struct __ubsan_type_descriptor
193    {
194      unsigned short __typekind;
195      unsigned short __typeinfo;
196      char __typename[];
197    }
198    type.  */
199 
200 static tree
ubsan_get_type_descriptor_type(void)201 ubsan_get_type_descriptor_type (void)
202 {
203   static const char *field_names[3]
204     = { "__typekind", "__typeinfo", "__typename" };
205   tree fields[3], ret;
206 
207   if (ubsan_type_descriptor_type)
208     return ubsan_type_descriptor_type;
209 
210   tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
211   tree flex_arr_type = build_array_type (char_type_node, itype);
212 
213   ret = make_node (RECORD_TYPE);
214   for (int i = 0; i < 3; i++)
215     {
216       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
217 			      get_identifier (field_names[i]),
218 			      (i == 2) ? flex_arr_type
219 			      : short_unsigned_type_node);
220       DECL_CONTEXT (fields[i]) = ret;
221       if (i)
222 	DECL_CHAIN (fields[i - 1]) = fields[i];
223     }
224   tree type_decl = build_decl (input_location, TYPE_DECL,
225 			       get_identifier ("__ubsan_type_descriptor"),
226 			       ret);
227   DECL_IGNORED_P (type_decl) = 1;
228   DECL_ARTIFICIAL (type_decl) = 1;
229   TYPE_FIELDS (ret) = fields[0];
230   TYPE_NAME (ret) = type_decl;
231   TYPE_STUB_DECL (ret) = type_decl;
232   TYPE_ARTIFICIAL (ret) = 1;
233   layout_type (ret);
234   ubsan_type_descriptor_type = ret;
235   return ret;
236 }
237 
238 /* Cached ubsan_get_source_location_type () return value.  */
239 static GTY(()) tree ubsan_source_location_type;
240 
241 /* Build
242    struct __ubsan_source_location
243    {
244      const char *__filename;
245      unsigned int __line;
246      unsigned int __column;
247    }
248    type.  */
249 
250 tree
ubsan_get_source_location_type(void)251 ubsan_get_source_location_type (void)
252 {
253   static const char *field_names[3]
254     = { "__filename", "__line", "__column" };
255   tree fields[3], ret;
256   if (ubsan_source_location_type)
257     return ubsan_source_location_type;
258 
259   tree const_char_type = build_qualified_type (char_type_node,
260 					       TYPE_QUAL_CONST);
261 
262   ret = make_node (RECORD_TYPE);
263   for (int i = 0; i < 3; i++)
264     {
265       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
266 			      get_identifier (field_names[i]),
267 			      (i == 0) ? build_pointer_type (const_char_type)
268 			      : unsigned_type_node);
269       DECL_CONTEXT (fields[i]) = ret;
270       if (i)
271 	DECL_CHAIN (fields[i - 1]) = fields[i];
272     }
273   tree type_decl = build_decl (input_location, TYPE_DECL,
274 			       get_identifier ("__ubsan_source_location"),
275 			       ret);
276   DECL_IGNORED_P (type_decl) = 1;
277   DECL_ARTIFICIAL (type_decl) = 1;
278   TYPE_FIELDS (ret) = fields[0];
279   TYPE_NAME (ret) = type_decl;
280   TYPE_STUB_DECL (ret) = type_decl;
281   TYPE_ARTIFICIAL (ret) = 1;
282   layout_type (ret);
283   ubsan_source_location_type = ret;
284   return ret;
285 }
286 
287 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
288    type with its fields filled from a location_t LOC.  */
289 
290 static tree
ubsan_source_location(location_t loc)291 ubsan_source_location (location_t loc)
292 {
293   expanded_location xloc;
294   tree type = ubsan_get_source_location_type ();
295 
296   xloc = expand_location (loc);
297   tree str;
298   if (xloc.file == NULL)
299     {
300       str = build_int_cst (ptr_type_node, 0);
301       xloc.line = 0;
302       xloc.column = 0;
303     }
304   else
305     {
306       /* Fill in the values from LOC.  */
307       size_t len = strlen (xloc.file) + 1;
308       str = build_string (len, xloc.file);
309       TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
310       TREE_READONLY (str) = 1;
311       TREE_STATIC (str) = 1;
312       str = build_fold_addr_expr (str);
313     }
314   tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
315 				    build_int_cst (unsigned_type_node,
316 						   xloc.line), NULL_TREE,
317 				    build_int_cst (unsigned_type_node,
318 						   xloc.column));
319   TREE_CONSTANT (ctor) = 1;
320   TREE_STATIC (ctor) = 1;
321 
322   return ctor;
323 }
324 
325 /* This routine returns a magic number for TYPE.  */
326 
327 static unsigned short
get_ubsan_type_info_for_type(tree type)328 get_ubsan_type_info_for_type (tree type)
329 {
330   if (TREE_CODE (type) == REAL_TYPE)
331     return tree_to_uhwi (TYPE_SIZE (type));
332   else if (INTEGRAL_TYPE_P (type))
333     {
334       int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
335       gcc_assert (prec != -1);
336       return (prec << 1) | !TYPE_UNSIGNED (type);
337     }
338   else
339     return 0;
340 }
341 
342 /* Counters for internal labels.  ubsan_ids[0] for Lubsan_type,
343    ubsan_ids[1] for Lubsan_data labels.  */
344 static GTY(()) unsigned int ubsan_ids[2];
345 
346 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
347    descriptor.  It first looks into the hash table; if not found,
348    create the VAR_DECL, put it into the hash table and return the
349    ADDR_EXPR of it.  TYPE describes a particular type.  PSTYLE is
350    an enum controlling how we want to print the type.  */
351 
352 tree
ubsan_type_descriptor(tree type,enum ubsan_print_style pstyle)353 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
354 {
355   /* See through any typedefs.  */
356   type = TYPE_MAIN_VARIANT (type);
357 
358   tree decl = decl_for_type_lookup (type);
359   /* It is possible that some of the earlier created DECLs were found
360      unused, in that case they weren't emitted and varpool_node::get
361      returns NULL node on them.  But now we really need them.  Thus,
362      renew them here.  */
363   if (decl != NULL_TREE && varpool_node::get (decl))
364     return build_fold_addr_expr (decl);
365 
366   tree dtype = ubsan_get_type_descriptor_type ();
367   tree type2 = type;
368   const char *tname = NULL;
369   pretty_printer pretty_name;
370   unsigned char deref_depth = 0;
371   unsigned short tkind, tinfo;
372 
373   /* Get the name of the type, or the name of the pointer type.  */
374   if (pstyle == UBSAN_PRINT_POINTER)
375     {
376       gcc_assert (POINTER_TYPE_P (type));
377       type2 = TREE_TYPE (type);
378 
379       /* Remove any '*' operators from TYPE.  */
380       while (POINTER_TYPE_P (type2))
381         deref_depth++, type2 = TREE_TYPE (type2);
382 
383       if (TREE_CODE (type2) == METHOD_TYPE)
384         type2 = TYPE_METHOD_BASETYPE (type2);
385     }
386 
387   /* If an array, get its type.  */
388   type2 = strip_array_types (type2);
389 
390   if (pstyle == UBSAN_PRINT_ARRAY)
391     {
392       while (POINTER_TYPE_P (type2))
393         deref_depth++, type2 = TREE_TYPE (type2);
394     }
395 
396   if (TYPE_NAME (type2) != NULL)
397     {
398       if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
399 	tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
400       else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
401 	tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
402     }
403 
404   if (tname == NULL)
405     /* We weren't able to determine the type name.  */
406     tname = "<unknown>";
407 
408   tree eltype = type;
409   if (pstyle == UBSAN_PRINT_POINTER)
410     {
411       pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
412 		 TYPE_VOLATILE (type2) ? "volatile " : "",
413 		 TYPE_READONLY (type2) ? "const " : "",
414 		 TYPE_RESTRICT (type2) ? "restrict " : "",
415 		 TYPE_ATOMIC (type2) ? "_Atomic " : "",
416 		 TREE_CODE (type2) == RECORD_TYPE
417 		 ? "struct "
418 		 : TREE_CODE (type2) == UNION_TYPE
419 		   ? "union " : "", tname,
420 		 deref_depth == 0 ? "" : " ");
421       while (deref_depth-- > 0)
422 	pp_star (&pretty_name);
423       pp_quote (&pretty_name);
424     }
425   else if (pstyle == UBSAN_PRINT_ARRAY)
426     {
427       /* Pretty print the array dimensions.  */
428       gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
429       tree t = type;
430       pp_printf (&pretty_name, "'%s ", tname);
431       while (deref_depth-- > 0)
432 	pp_star (&pretty_name);
433       while (TREE_CODE (t) == ARRAY_TYPE)
434 	{
435 	  pp_left_bracket (&pretty_name);
436 	  tree dom = TYPE_DOMAIN (t);
437 	  if (dom != NULL_TREE
438 	      && TYPE_MAX_VALUE (dom) != NULL_TREE
439 	      && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
440 	    {
441 	      unsigned HOST_WIDE_INT m;
442 	      if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
443 		  && (m = tree_to_uhwi (TYPE_MAX_VALUE (dom))) + 1 != 0)
444 		pp_unsigned_wide_integer (&pretty_name, m + 1);
445 	      else
446 		pp_wide_int (&pretty_name,
447 			     wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
448 			     TYPE_SIGN (TREE_TYPE (dom)));
449 	    }
450 	  else
451 	    /* ??? We can't determine the variable name; print VLA unspec.  */
452 	    pp_star (&pretty_name);
453 	  pp_right_bracket (&pretty_name);
454 	  t = TREE_TYPE (t);
455 	}
456       pp_quote (&pretty_name);
457 
458       /* Save the tree with stripped types.  */
459       eltype = t;
460     }
461   else
462     pp_printf (&pretty_name, "'%s'", tname);
463 
464   switch (TREE_CODE (eltype))
465     {
466     case BOOLEAN_TYPE:
467     case ENUMERAL_TYPE:
468     case INTEGER_TYPE:
469       tkind = 0x0000;
470       break;
471     case REAL_TYPE:
472       /* FIXME: libubsan right now only supports float, double and
473 	 long double type formats.  */
474       if (TYPE_MODE (eltype) == TYPE_MODE (float_type_node)
475 	  || TYPE_MODE (eltype) == TYPE_MODE (double_type_node)
476 	  || TYPE_MODE (eltype) == TYPE_MODE (long_double_type_node))
477 	tkind = 0x0001;
478       else
479 	tkind = 0xffff;
480       break;
481     default:
482       tkind = 0xffff;
483       break;
484     }
485   tinfo = get_ubsan_type_info_for_type (eltype);
486 
487   /* Create a new VAR_DECL of type descriptor.  */
488   const char *tmp = pp_formatted_text (&pretty_name);
489   size_t len = strlen (tmp) + 1;
490   tree str = build_string (len, tmp);
491   TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
492   TREE_READONLY (str) = 1;
493   TREE_STATIC (str) = 1;
494 
495   char tmp_name[32];
496   ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
497   decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
498 		     dtype);
499   TREE_STATIC (decl) = 1;
500   TREE_PUBLIC (decl) = 0;
501   DECL_ARTIFICIAL (decl) = 1;
502   DECL_IGNORED_P (decl) = 1;
503   DECL_EXTERNAL (decl) = 0;
504   DECL_SIZE (decl)
505     = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
506   DECL_SIZE_UNIT (decl)
507     = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
508 		  TYPE_SIZE_UNIT (TREE_TYPE (str)));
509 
510   tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
511 				    build_int_cst (short_unsigned_type_node,
512 						   tkind), NULL_TREE,
513 				    build_int_cst (short_unsigned_type_node,
514 						   tinfo), NULL_TREE, str);
515   TREE_CONSTANT (ctor) = 1;
516   TREE_STATIC (ctor) = 1;
517   DECL_INITIAL (decl) = ctor;
518   varpool_node::finalize_decl (decl);
519 
520   /* Save the VAR_DECL into the hash table.  */
521   decl_for_type_insert (type, decl);
522 
523   return build_fold_addr_expr (decl);
524 }
525 
526 /* Create a structure for the ubsan library.  NAME is a name of the new
527    structure.  LOCCNT is number of locations, PLOC points to array of
528    locations.  The arguments in ... are of __ubsan_type_descriptor type
529    and there are at most two of them, followed by NULL_TREE, followed
530    by optional extra arguments and another NULL_TREE.  */
531 
532 tree
ubsan_create_data(const char * name,int loccnt,const location_t * ploc,...)533 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
534 {
535   va_list args;
536   tree ret, t;
537   tree fields[6];
538   vec<tree, va_gc> *saved_args = NULL;
539   size_t i = 0;
540   int j;
541 
542   /* It is possible that PCH zapped table with definitions of sanitizer
543      builtins.  Reinitialize them if needed.  */
544   initialize_sanitizer_builtins ();
545 
546   /* Firstly, create a pointer to type descriptor type.  */
547   tree td_type = ubsan_get_type_descriptor_type ();
548   td_type = build_pointer_type (td_type);
549 
550   /* Create the structure type.  */
551   ret = make_node (RECORD_TYPE);
552   for (j = 0; j < loccnt; j++)
553     {
554       gcc_checking_assert (i < 2);
555       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
556 			      ubsan_get_source_location_type ());
557       DECL_CONTEXT (fields[i]) = ret;
558       if (i)
559 	DECL_CHAIN (fields[i - 1]) = fields[i];
560       i++;
561     }
562 
563   va_start (args, ploc);
564   for (t = va_arg (args, tree); t != NULL_TREE;
565        i++, t = va_arg (args, tree))
566     {
567       gcc_checking_assert (i < 4);
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 			      td_type);
572       DECL_CONTEXT (fields[i]) = ret;
573       if (i)
574 	DECL_CHAIN (fields[i - 1]) = fields[i];
575     }
576 
577   for (t = va_arg (args, tree); t != NULL_TREE;
578        i++, t = va_arg (args, tree))
579     {
580       gcc_checking_assert (i < 6);
581       /* Save the tree arguments for later use.  */
582       vec_safe_push (saved_args, t);
583       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
584 			      TREE_TYPE (t));
585       DECL_CONTEXT (fields[i]) = ret;
586       if (i)
587 	DECL_CHAIN (fields[i - 1]) = fields[i];
588     }
589   va_end (args);
590 
591   tree type_decl = build_decl (input_location, TYPE_DECL,
592 			       get_identifier (name), ret);
593   DECL_IGNORED_P (type_decl) = 1;
594   DECL_ARTIFICIAL (type_decl) = 1;
595   TYPE_FIELDS (ret) = fields[0];
596   TYPE_NAME (ret) = type_decl;
597   TYPE_STUB_DECL (ret) = type_decl;
598   TYPE_ARTIFICIAL (ret) = 1;
599   layout_type (ret);
600 
601   /* Now, fill in the type.  */
602   char tmp_name[32];
603   ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
604   tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
605 			 ret);
606   TREE_STATIC (var) = 1;
607   TREE_PUBLIC (var) = 0;
608   DECL_ARTIFICIAL (var) = 1;
609   DECL_IGNORED_P (var) = 1;
610   DECL_EXTERNAL (var) = 0;
611 
612   vec<constructor_elt, va_gc> *v;
613   vec_alloc (v, i);
614   tree ctor = build_constructor (ret, v);
615 
616   /* If desirable, set the __ubsan_source_location element.  */
617   for (j = 0; j < loccnt; j++)
618     {
619       location_t loc = LOCATION_LOCUS (ploc[j]);
620       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
621     }
622 
623   size_t nelts = vec_safe_length (saved_args);
624   for (i = 0; i < nelts; i++)
625     {
626       t = (*saved_args)[i];
627       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
628     }
629 
630   TREE_CONSTANT (ctor) = 1;
631   TREE_STATIC (ctor) = 1;
632   DECL_INITIAL (var) = ctor;
633   varpool_node::finalize_decl (var);
634 
635   return var;
636 }
637 
638 /* Instrument the __builtin_unreachable call.  We just call the libubsan
639    routine instead.  */
640 
641 bool
ubsan_instrument_unreachable(gimple_stmt_iterator * gsi)642 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
643 {
644   gimple *g;
645   location_t loc = gimple_location (gsi_stmt (*gsi));
646 
647   if (flag_sanitize_undefined_trap_on_error)
648     g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
649   else
650     {
651       tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
652 				     NULL_TREE, NULL_TREE);
653       data = build_fold_addr_expr_loc (loc, data);
654       tree fn
655 	= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
656       g = gimple_build_call (fn, 1, data);
657     }
658   gimple_set_location (g, loc);
659   gsi_replace (gsi, g, false);
660   return false;
661 }
662 
663 /* Return true if T is a call to a libubsan routine.  */
664 
665 bool
is_ubsan_builtin_p(tree t)666 is_ubsan_builtin_p (tree t)
667 {
668   return TREE_CODE (t) == FUNCTION_DECL
669 	 && fndecl_built_in_p (t, BUILT_IN_NORMAL)
670 	 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
671 		     "__builtin___ubsan_", 18) == 0;
672 }
673 
674 /* Create a callgraph edge for statement STMT.  */
675 
676 static void
ubsan_create_edge(gimple * stmt)677 ubsan_create_edge (gimple *stmt)
678 {
679   gcall *call_stmt = dyn_cast <gcall *> (stmt);
680   basic_block bb = gimple_bb (stmt);
681   cgraph_node *node = cgraph_node::get (current_function_decl);
682   tree decl = gimple_call_fndecl (call_stmt);
683   if (decl)
684     node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count);
685 }
686 
687 /* Expand the UBSAN_BOUNDS special builtin function.  */
688 
689 bool
ubsan_expand_bounds_ifn(gimple_stmt_iterator * gsi)690 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
691 {
692   gimple *stmt = gsi_stmt (*gsi);
693   location_t loc = gimple_location (stmt);
694   gcc_assert (gimple_call_num_args (stmt) == 3);
695 
696   /* Pick up the arguments of the UBSAN_BOUNDS call.  */
697   tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
698   tree index = gimple_call_arg (stmt, 1);
699   tree orig_index = index;
700   tree bound = gimple_call_arg (stmt, 2);
701 
702   gimple_stmt_iterator gsi_orig = *gsi;
703 
704   /* Create condition "if (index > bound)".  */
705   basic_block then_bb, fallthru_bb;
706   gimple_stmt_iterator cond_insert_point
707     = create_cond_insert_point (gsi, false, false, true,
708 				&then_bb, &fallthru_bb);
709   index = fold_convert (TREE_TYPE (bound), index);
710   index = force_gimple_operand_gsi (&cond_insert_point, index,
711 				    true, NULL_TREE,
712 				    false, GSI_NEW_STMT);
713   gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
714   gimple_set_location (g, loc);
715   gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
716 
717   /* Generate __ubsan_handle_out_of_bounds call.  */
718   *gsi = gsi_after_labels (then_bb);
719   if (flag_sanitize_undefined_trap_on_error)
720     g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
721   else
722     {
723       tree data
724 	= ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
725 			     ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
726 			     ubsan_type_descriptor (TREE_TYPE (orig_index)),
727 			     NULL_TREE, NULL_TREE);
728       data = build_fold_addr_expr_loc (loc, data);
729       enum built_in_function bcode
730 	= (flag_sanitize_recover & SANITIZE_BOUNDS)
731 	  ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
732 	  : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
733       tree fn = builtin_decl_explicit (bcode);
734       tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE);
735       val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true,
736 				      GSI_SAME_STMT);
737       g = gimple_build_call (fn, 2, data, val);
738     }
739   gimple_set_location (g, loc);
740   gsi_insert_before (gsi, g, GSI_SAME_STMT);
741 
742   /* Get rid of the UBSAN_BOUNDS call from the IR.  */
743   unlink_stmt_vdef (stmt);
744   gsi_remove (&gsi_orig, true);
745 
746   /* Point GSI to next logical statement.  */
747   *gsi = gsi_start_bb (fallthru_bb);
748   return true;
749 }
750 
751 /* Expand UBSAN_NULL internal call.  The type is kept on the ckind
752    argument which is a constant, because the middle-end treats pointer
753    conversions as useless and therefore the type of the first argument
754    could be changed to any other pointer type.  */
755 
756 bool
ubsan_expand_null_ifn(gimple_stmt_iterator * gsip)757 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
758 {
759   gimple_stmt_iterator gsi = *gsip;
760   gimple *stmt = gsi_stmt (gsi);
761   location_t loc = gimple_location (stmt);
762   gcc_assert (gimple_call_num_args (stmt) == 3);
763   tree ptr = gimple_call_arg (stmt, 0);
764   tree ckind = gimple_call_arg (stmt, 1);
765   tree align = gimple_call_arg (stmt, 2);
766   tree check_align = NULL_TREE;
767   bool check_null;
768 
769   basic_block cur_bb = gsi_bb (gsi);
770 
771   gimple *g;
772   if (!integer_zerop (align))
773     {
774       unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
775       if (compare_tree_int (align, ptralign) == 1)
776 	{
777 	  check_align = make_ssa_name (pointer_sized_int_node);
778 	  g = gimple_build_assign (check_align, NOP_EXPR, ptr);
779 	  gimple_set_location (g, loc);
780 	  gsi_insert_before (&gsi, g, GSI_SAME_STMT);
781 	}
782     }
783   check_null = sanitize_flags_p (SANITIZE_NULL);
784 
785   if (check_align == NULL_TREE && !check_null)
786     {
787       gsi_remove (gsip, true);
788       /* Unlink the UBSAN_NULLs vops before replacing it.  */
789       unlink_stmt_vdef (stmt);
790       return true;
791     }
792 
793   /* Split the original block holding the pointer dereference.  */
794   edge e = split_block (cur_bb, stmt);
795 
796   /* Get a hold on the 'condition block', the 'then block' and the
797      'else block'.  */
798   basic_block cond_bb = e->src;
799   basic_block fallthru_bb = e->dest;
800   basic_block then_bb = create_empty_bb (cond_bb);
801   add_bb_to_loop (then_bb, cond_bb->loop_father);
802   loops_state_set (LOOPS_NEED_FIXUP);
803 
804   /* Make an edge coming from the 'cond block' into the 'then block';
805      this edge is unlikely taken, so set up the probability accordingly.  */
806   e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
807   e->probability = profile_probability::very_unlikely ();
808   then_bb->count = e->count ();
809 
810   /* Connect 'then block' with the 'else block'.  This is needed
811      as the ubsan routines we call in the 'then block' are not noreturn.
812      The 'then block' only has one outcoming edge.  */
813   make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
814 
815   /* Set up the fallthrough basic block.  */
816   e = find_edge (cond_bb, fallthru_bb);
817   e->flags = EDGE_FALSE_VALUE;
818   e->probability = profile_probability::very_likely ();
819 
820   /* Update dominance info for the newly created then_bb; note that
821      fallthru_bb's dominance info has already been updated by
822      split_block.  */
823   if (dom_info_available_p (CDI_DOMINATORS))
824     set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
825 
826   /* Put the ubsan builtin call into the newly created BB.  */
827   if (flag_sanitize_undefined_trap_on_error)
828     g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
829   else
830     {
831       enum built_in_function bcode
832 	= (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
833 				    | (check_null ? SANITIZE_NULL : 0)))
834 	  ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1
835 	  : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_ABORT;
836       tree fn = builtin_decl_implicit (bcode);
837       int align_log = tree_log2 (align);
838       tree data
839 	= ubsan_create_data ("__ubsan_null_data", 1, &loc,
840 			     ubsan_type_descriptor (TREE_TYPE (ckind),
841 						    UBSAN_PRINT_POINTER),
842 			     NULL_TREE,
843 			     build_int_cst (unsigned_char_type_node,
844 					    MAX (align_log, 0)),
845 			     fold_convert (unsigned_char_type_node, ckind),
846 			     NULL_TREE);
847       data = build_fold_addr_expr_loc (loc, data);
848       g = gimple_build_call (fn, 2, data,
849 			     check_align ? check_align
850 			     : build_zero_cst (pointer_sized_int_node));
851     }
852   gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
853   gimple_set_location (g, loc);
854   gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
855 
856   /* Unlink the UBSAN_NULLs vops before replacing it.  */
857   unlink_stmt_vdef (stmt);
858 
859   if (check_null)
860     {
861       g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
862 			     NULL_TREE, NULL_TREE);
863       gimple_set_location (g, loc);
864 
865       /* Replace the UBSAN_NULL with a GIMPLE_COND stmt.  */
866       gsi_replace (&gsi, g, false);
867       stmt = g;
868     }
869 
870   if (check_align)
871     {
872       if (check_null)
873 	{
874 	  /* Split the block with the condition again.  */
875 	  e = split_block (cond_bb, stmt);
876 	  basic_block cond1_bb = e->src;
877 	  basic_block cond2_bb = e->dest;
878 
879 	  /* Make an edge coming from the 'cond1 block' into the 'then block';
880 	     this edge is unlikely taken, so set up the probability
881 	     accordingly.  */
882 	  e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
883 	  e->probability = profile_probability::very_unlikely ();
884 
885 	  /* Set up the fallthrough basic block.  */
886 	  e = find_edge (cond1_bb, cond2_bb);
887 	  e->flags = EDGE_FALSE_VALUE;
888 	  e->probability = profile_probability::very_likely ();
889 
890 	  /* Update dominance info.  */
891 	  if (dom_info_available_p (CDI_DOMINATORS))
892 	    {
893 	      set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
894 	      set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
895 	    }
896 
897 	  gsi2 = gsi_start_bb (cond2_bb);
898 	}
899 
900       tree mask = build_int_cst (pointer_sized_int_node,
901 				 tree_to_uhwi (align) - 1);
902       g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
903 			       BIT_AND_EXPR, check_align, mask);
904       gimple_set_location (g, loc);
905       if (check_null)
906 	gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
907       else
908 	gsi_insert_before (&gsi, g, GSI_SAME_STMT);
909 
910       g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
911 			     build_int_cst (pointer_sized_int_node, 0),
912 			     NULL_TREE, NULL_TREE);
913       gimple_set_location (g, loc);
914       if (check_null)
915 	gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
916       else
917 	/* Replace the UBSAN_NULL with a GIMPLE_COND stmt.  */
918 	gsi_replace (&gsi, g, false);
919     }
920   return false;
921 }
922 
923 #define OBJSZ_MAX_OFFSET (1024 * 16)
924 
925 /* Expand UBSAN_OBJECT_SIZE internal call.  */
926 
927 bool
ubsan_expand_objsize_ifn(gimple_stmt_iterator * gsi)928 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
929 {
930   gimple *stmt = gsi_stmt (*gsi);
931   location_t loc = gimple_location (stmt);
932   gcc_assert (gimple_call_num_args (stmt) == 4);
933 
934   tree ptr = gimple_call_arg (stmt, 0);
935   tree offset = gimple_call_arg (stmt, 1);
936   tree size = gimple_call_arg (stmt, 2);
937   tree ckind = gimple_call_arg (stmt, 3);
938   gimple_stmt_iterator gsi_orig = *gsi;
939   gimple *g;
940 
941   /* See if we can discard the check.  */
942   if (TREE_CODE (size) != INTEGER_CST
943       || integer_all_onesp (size))
944     /* Yes, __builtin_object_size couldn't determine the
945        object size.  */;
946   else if (TREE_CODE (offset) == INTEGER_CST
947 	   && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
948 	   && wi::to_widest (offset) <= -1)
949     /* The offset is in range [-16K, -1].  */;
950   else
951     {
952       /* if (offset > objsize) */
953       basic_block then_bb, fallthru_bb;
954       gimple_stmt_iterator cond_insert_point
955 	= create_cond_insert_point (gsi, false, false, true,
956 				    &then_bb, &fallthru_bb);
957       g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
958       gimple_set_location (g, loc);
959       gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
960 
961       /* If the offset is small enough, we don't need the second
962 	 run-time check.  */
963       if (TREE_CODE (offset) == INTEGER_CST
964 	  && wi::to_widest (offset) >= 0
965 	  && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
966 	*gsi = gsi_after_labels (then_bb);
967       else
968 	{
969 	  /* Don't issue run-time error if (ptr > ptr + offset).  That
970 	     may happen when computing a POINTER_PLUS_EXPR.  */
971 	  basic_block then2_bb, fallthru2_bb;
972 
973 	  gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
974 	  cond_insert_point = create_cond_insert_point (&gsi2, false, false,
975 							true, &then2_bb,
976 							&fallthru2_bb);
977 	  /* Convert the pointer to an integer type.  */
978 	  tree p = make_ssa_name (pointer_sized_int_node);
979 	  g = gimple_build_assign (p, NOP_EXPR, ptr);
980 	  gimple_set_location (g, loc);
981 	  gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
982 	  p = gimple_assign_lhs (g);
983 	  /* Compute ptr + offset.  */
984 	  g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
985 				   PLUS_EXPR, p, offset);
986 	  gimple_set_location (g, loc);
987 	  gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
988 	  /* Now build the conditional and put it into the IR.  */
989 	  g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
990 				 NULL_TREE, NULL_TREE);
991 	  gimple_set_location (g, loc);
992 	  gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
993 	  *gsi = gsi_after_labels (then2_bb);
994 	}
995 
996       /* Generate __ubsan_handle_type_mismatch call.  */
997       if (flag_sanitize_undefined_trap_on_error)
998 	g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
999       else
1000 	{
1001 	  tree data
1002 	    = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
1003 				 ubsan_type_descriptor (TREE_TYPE (ptr),
1004 							UBSAN_PRINT_POINTER),
1005 				 NULL_TREE,
1006 				 build_zero_cst (unsigned_char_type_node),
1007 				 ckind,
1008 				 NULL_TREE);
1009 	  data = build_fold_addr_expr_loc (loc, data);
1010 	  enum built_in_function bcode
1011 	    = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1012 	      ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1
1013 	      : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_ABORT;
1014 	  tree p = make_ssa_name (pointer_sized_int_node);
1015 	  g = gimple_build_assign (p, NOP_EXPR, ptr);
1016 	  gimple_set_location (g, loc);
1017 	  gsi_insert_before (gsi, g, GSI_SAME_STMT);
1018 	  g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1019 	}
1020       gimple_set_location (g, loc);
1021       gsi_insert_before (gsi, g, GSI_SAME_STMT);
1022 
1023       /* Point GSI to next logical statement.  */
1024       *gsi = gsi_start_bb (fallthru_bb);
1025 
1026       /* Get rid of the UBSAN_OBJECT_SIZE call from the IR.  */
1027       unlink_stmt_vdef (stmt);
1028       gsi_remove (&gsi_orig, true);
1029       return true;
1030     }
1031 
1032   /* Get rid of the UBSAN_OBJECT_SIZE call from the IR.  */
1033   unlink_stmt_vdef (stmt);
1034   gsi_remove (gsi, true);
1035   return true;
1036 }
1037 
1038 /* Expand UBSAN_PTR internal call.  */
1039 
1040 bool
ubsan_expand_ptr_ifn(gimple_stmt_iterator * gsip)1041 ubsan_expand_ptr_ifn (gimple_stmt_iterator *gsip)
1042 {
1043   gimple_stmt_iterator gsi = *gsip;
1044   gimple *stmt = gsi_stmt (gsi);
1045   location_t loc = gimple_location (stmt);
1046   gcc_assert (gimple_call_num_args (stmt) == 2);
1047   tree ptr = gimple_call_arg (stmt, 0);
1048   tree off = gimple_call_arg (stmt, 1);
1049 
1050   if (integer_zerop (off))
1051     {
1052       gsi_remove (gsip, true);
1053       unlink_stmt_vdef (stmt);
1054       return true;
1055     }
1056 
1057   basic_block cur_bb = gsi_bb (gsi);
1058   tree ptrplusoff = make_ssa_name (pointer_sized_int_node);
1059   tree ptri = make_ssa_name (pointer_sized_int_node);
1060   int pos_neg = get_range_pos_neg (off);
1061 
1062   /* Split the original block holding the pointer dereference.  */
1063   edge e = split_block (cur_bb, stmt);
1064 
1065   /* Get a hold on the 'condition block', the 'then block' and the
1066      'else block'.  */
1067   basic_block cond_bb = e->src;
1068   basic_block fallthru_bb = e->dest;
1069   basic_block then_bb = create_empty_bb (cond_bb);
1070   basic_block cond_pos_bb = NULL, cond_neg_bb = NULL;
1071   add_bb_to_loop (then_bb, cond_bb->loop_father);
1072   loops_state_set (LOOPS_NEED_FIXUP);
1073 
1074   /* Set up the fallthrough basic block.  */
1075   e->flags = EDGE_FALSE_VALUE;
1076   if (pos_neg != 3)
1077     {
1078       e->probability = profile_probability::very_likely ();
1079 
1080       /* Connect 'then block' with the 'else block'.  This is needed
1081 	 as the ubsan routines we call in the 'then block' are not noreturn.
1082 	 The 'then block' only has one outcoming edge.  */
1083       make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
1084 
1085       /* Make an edge coming from the 'cond block' into the 'then block';
1086 	 this edge is unlikely taken, so set up the probability
1087 	 accordingly.  */
1088       e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
1089       e->probability = profile_probability::very_unlikely ();
1090       then_bb->count = e->count ();
1091     }
1092   else
1093     {
1094       e->probability = profile_probability::even ();
1095 
1096       e = split_block (fallthru_bb, (gimple *) NULL);
1097       cond_neg_bb = e->src;
1098       fallthru_bb = e->dest;
1099       e->probability = profile_probability::very_likely ();
1100       e->flags = EDGE_FALSE_VALUE;
1101 
1102       e = make_edge (cond_neg_bb, then_bb, EDGE_TRUE_VALUE);
1103       e->probability = profile_probability::very_unlikely ();
1104       then_bb->count = e->count ();
1105 
1106       cond_pos_bb = create_empty_bb (cond_bb);
1107       add_bb_to_loop (cond_pos_bb, cond_bb->loop_father);
1108 
1109       e = make_edge (cond_bb, cond_pos_bb, EDGE_TRUE_VALUE);
1110       e->probability = profile_probability::even ();
1111       cond_pos_bb->count = e->count ();
1112 
1113       e = make_edge (cond_pos_bb, then_bb, EDGE_TRUE_VALUE);
1114       e->probability = profile_probability::very_unlikely ();
1115 
1116       e = make_edge (cond_pos_bb, fallthru_bb, EDGE_FALSE_VALUE);
1117       e->probability = profile_probability::very_likely ();
1118 
1119       make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
1120     }
1121 
1122   gimple *g = gimple_build_assign (ptri, NOP_EXPR, ptr);
1123   gimple_set_location (g, loc);
1124   gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1125   g = gimple_build_assign (ptrplusoff, PLUS_EXPR, ptri, off);
1126   gimple_set_location (g, loc);
1127   gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1128 
1129   /* Update dominance info for the newly created then_bb; note that
1130      fallthru_bb's dominance info has already been updated by
1131      split_block.  */
1132   if (dom_info_available_p (CDI_DOMINATORS))
1133     {
1134       set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
1135       if (pos_neg == 3)
1136 	{
1137 	  set_immediate_dominator (CDI_DOMINATORS, cond_pos_bb, cond_bb);
1138 	  set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond_bb);
1139 	}
1140     }
1141 
1142   /* Put the ubsan builtin call into the newly created BB.  */
1143   if (flag_sanitize_undefined_trap_on_error)
1144     g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
1145   else
1146     {
1147       enum built_in_function bcode
1148 	= (flag_sanitize_recover & SANITIZE_POINTER_OVERFLOW)
1149 	  ? BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW
1150 	  : BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW_ABORT;
1151       tree fn = builtin_decl_implicit (bcode);
1152       tree data
1153 	= ubsan_create_data ("__ubsan_ptrovf_data", 1, &loc,
1154 			     NULL_TREE, NULL_TREE);
1155       data = build_fold_addr_expr_loc (loc, data);
1156       g = gimple_build_call (fn, 3, data, ptr, ptrplusoff);
1157     }
1158   gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
1159   gimple_set_location (g, loc);
1160   gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1161 
1162   /* Unlink the UBSAN_PTRs vops before replacing it.  */
1163   unlink_stmt_vdef (stmt);
1164 
1165   if (TREE_CODE (off) == INTEGER_CST)
1166     g = gimple_build_cond (wi::neg_p (wi::to_wide (off)) ? LT_EXPR : GE_EXPR,
1167 			   ptri, fold_build1 (NEGATE_EXPR, sizetype, off),
1168 			   NULL_TREE, NULL_TREE);
1169   else if (pos_neg != 3)
1170     g = gimple_build_cond (pos_neg == 1 ? LT_EXPR : GT_EXPR,
1171 			   ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1172   else
1173     {
1174       gsi2 = gsi_start_bb (cond_pos_bb);
1175       g = gimple_build_cond (LT_EXPR, ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1176       gimple_set_location (g, loc);
1177       gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1178 
1179       gsi2 = gsi_start_bb (cond_neg_bb);
1180       g = gimple_build_cond (GT_EXPR, ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1181       gimple_set_location (g, loc);
1182       gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1183 
1184       gimple_seq seq = NULL;
1185       tree t = gimple_build (&seq, loc, NOP_EXPR, ssizetype, off);
1186       t = gimple_build (&seq, loc, GE_EXPR, boolean_type_node,
1187 			t, ssize_int (0));
1188       gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
1189       g = gimple_build_cond (NE_EXPR, t, boolean_false_node,
1190 			     NULL_TREE, NULL_TREE);
1191     }
1192   gimple_set_location (g, loc);
1193   /* Replace the UBSAN_PTR with a GIMPLE_COND stmt.  */
1194   gsi_replace (&gsi, g, false);
1195   return false;
1196 }
1197 
1198 
1199 /* Cached __ubsan_vptr_type_cache decl.  */
1200 static GTY(()) tree ubsan_vptr_type_cache_decl;
1201 
1202 /* Expand UBSAN_VPTR internal call.  The type is kept on the ckind
1203    argument which is a constant, because the middle-end treats pointer
1204    conversions as useless and therefore the type of the first argument
1205    could be changed to any other pointer type.  */
1206 
1207 bool
ubsan_expand_vptr_ifn(gimple_stmt_iterator * gsip)1208 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1209 {
1210   gimple_stmt_iterator gsi = *gsip;
1211   gimple *stmt = gsi_stmt (gsi);
1212   location_t loc = gimple_location (stmt);
1213   gcc_assert (gimple_call_num_args (stmt) == 5);
1214   tree op = gimple_call_arg (stmt, 0);
1215   tree vptr = gimple_call_arg (stmt, 1);
1216   tree str_hash = gimple_call_arg (stmt, 2);
1217   tree ti_decl_addr = gimple_call_arg (stmt, 3);
1218   tree ckind_tree = gimple_call_arg (stmt, 4);
1219   ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1220   tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1221   gimple *g;
1222   basic_block fallthru_bb = NULL;
1223 
1224   if (ckind == UBSAN_DOWNCAST_POINTER)
1225     {
1226       /* Guard everything with if (op != NULL) { ... }.  */
1227       basic_block then_bb;
1228       gimple_stmt_iterator cond_insert_point
1229 	= create_cond_insert_point (gsip, false, false, true,
1230 				    &then_bb, &fallthru_bb);
1231       g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1232 			     NULL_TREE, NULL_TREE);
1233       gimple_set_location (g, loc);
1234       gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1235       *gsip = gsi_after_labels (then_bb);
1236       gsi_remove (&gsi, false);
1237       gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1238       gsi = *gsip;
1239     }
1240 
1241   tree htype = TREE_TYPE (str_hash);
1242   tree cst = wide_int_to_tree (htype,
1243 			       wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1244 			       | 0xeb382d69, 64));
1245   g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1246 			   vptr, str_hash);
1247   gimple_set_location (g, loc);
1248   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1249   g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1250 			   gimple_assign_lhs (g), cst);
1251   gimple_set_location (g, loc);
1252   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1253   tree t1 = gimple_assign_lhs (g);
1254   g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1255 			   t1, build_int_cst (integer_type_node, 47));
1256   gimple_set_location (g, loc);
1257   tree t2 = gimple_assign_lhs (g);
1258   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1259   g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1260 			   vptr, t1);
1261   gimple_set_location (g, loc);
1262   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1263   g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1264 			   t2, gimple_assign_lhs (g));
1265   gimple_set_location (g, loc);
1266   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1267   g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1268 			   gimple_assign_lhs (g), cst);
1269   gimple_set_location (g, loc);
1270   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1271   tree t3 = gimple_assign_lhs (g);
1272   g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1273 			   t3, build_int_cst (integer_type_node, 47));
1274   gimple_set_location (g, loc);
1275   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1276   g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1277 			   t3, gimple_assign_lhs (g));
1278   gimple_set_location (g, loc);
1279   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1280   g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1281 			   gimple_assign_lhs (g), cst);
1282   gimple_set_location (g, loc);
1283   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1284   if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1285     {
1286       g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1287 			       NOP_EXPR, gimple_assign_lhs (g));
1288       gimple_set_location (g, loc);
1289       gsi_insert_before (gsip, g, GSI_SAME_STMT);
1290     }
1291   tree hash = gimple_assign_lhs (g);
1292 
1293   if (ubsan_vptr_type_cache_decl == NULL_TREE)
1294     {
1295       tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1296       tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1297 			       get_identifier ("__ubsan_vptr_type_cache"),
1298 			       atype);
1299       DECL_ARTIFICIAL (array) = 1;
1300       DECL_IGNORED_P (array) = 1;
1301       TREE_PUBLIC (array) = 1;
1302       TREE_STATIC (array) = 1;
1303       DECL_EXTERNAL (array) = 1;
1304       DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1305       DECL_VISIBILITY_SPECIFIED (array) = 1;
1306       varpool_node::finalize_decl (array);
1307       ubsan_vptr_type_cache_decl = array;
1308    }
1309 
1310   g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1311 			   BIT_AND_EXPR, hash,
1312 			   build_int_cst (pointer_sized_int_node, 127));
1313   gimple_set_location (g, loc);
1314   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1315 
1316   tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1317 		       ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1318 		       NULL_TREE, NULL_TREE);
1319   g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1320 			   ARRAY_REF, c);
1321   gimple_set_location (g, loc);
1322   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1323 
1324   basic_block then_bb, fallthru2_bb;
1325   gimple_stmt_iterator cond_insert_point
1326     = create_cond_insert_point (gsip, false, false, true,
1327 				&then_bb, &fallthru2_bb);
1328   g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1329 			 NULL_TREE, NULL_TREE);
1330   gimple_set_location (g, loc);
1331   gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1332   *gsip = gsi_after_labels (then_bb);
1333   if (fallthru_bb == NULL)
1334     fallthru_bb = fallthru2_bb;
1335 
1336   tree data
1337     = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1338 			 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1339 			 build_int_cst (unsigned_char_type_node, ckind),
1340 			 NULL_TREE);
1341   data = build_fold_addr_expr_loc (loc, data);
1342   enum built_in_function bcode
1343     = (flag_sanitize_recover & SANITIZE_VPTR)
1344       ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1345       : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1346 
1347   g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1348   gimple_set_location (g, loc);
1349   gsi_insert_before (gsip, g, GSI_SAME_STMT);
1350 
1351   /* Point GSI to next logical statement.  */
1352   *gsip = gsi_start_bb (fallthru_bb);
1353 
1354   /* Get rid of the UBSAN_VPTR call from the IR.  */
1355   unlink_stmt_vdef (stmt);
1356   gsi_remove (&gsi, true);
1357   return true;
1358 }
1359 
1360 /* Instrument a memory reference.  BASE is the base of MEM, IS_LHS says
1361    whether the pointer is on the left hand side of the assignment.  */
1362 
1363 static void
instrument_mem_ref(tree mem,tree base,gimple_stmt_iterator * iter,bool is_lhs)1364 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1365 		    bool is_lhs)
1366 {
1367   enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1368   unsigned int align = 0;
1369   if (sanitize_flags_p (SANITIZE_ALIGNMENT))
1370     {
1371       align = min_align_of_type (TREE_TYPE (base));
1372       if (align <= 1)
1373 	align = 0;
1374     }
1375   if (align == 0 && !sanitize_flags_p (SANITIZE_NULL))
1376     return;
1377   tree t = TREE_OPERAND (base, 0);
1378   if (!POINTER_TYPE_P (TREE_TYPE (t)))
1379     return;
1380   if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1381     ikind = UBSAN_MEMBER_ACCESS;
1382   tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1383   tree alignt = build_int_cst (pointer_sized_int_node, align);
1384   gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1385   gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1386   gsi_insert_before (iter, g, GSI_SAME_STMT);
1387 }
1388 
1389 /* Perform the pointer instrumentation.  */
1390 
1391 static void
instrument_null(gimple_stmt_iterator gsi,tree t,bool is_lhs)1392 instrument_null (gimple_stmt_iterator gsi, tree t, bool is_lhs)
1393 {
1394   /* Handle also e.g. &s->i.  */
1395   if (TREE_CODE (t) == ADDR_EXPR)
1396     t = TREE_OPERAND (t, 0);
1397   tree base = get_base_address (t);
1398   if (base != NULL_TREE
1399       && TREE_CODE (base) == MEM_REF
1400       && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1401     instrument_mem_ref (t, base, &gsi, is_lhs);
1402 }
1403 
1404 /* Instrument pointer arithmetics PTR p+ OFF.  */
1405 
1406 static void
instrument_pointer_overflow(gimple_stmt_iterator * gsi,tree ptr,tree off)1407 instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree ptr, tree off)
1408 {
1409   if (TYPE_PRECISION (sizetype) != POINTER_SIZE)
1410     return;
1411   gcall *g = gimple_build_call_internal (IFN_UBSAN_PTR, 2, ptr, off);
1412   gimple_set_location (g, gimple_location (gsi_stmt (*gsi)));
1413   gsi_insert_before (gsi, g, GSI_SAME_STMT);
1414 }
1415 
1416 /* Instrument pointer arithmetics if any.  */
1417 
1418 static void
maybe_instrument_pointer_overflow(gimple_stmt_iterator * gsi,tree t)1419 maybe_instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree t)
1420 {
1421   if (TYPE_PRECISION (sizetype) != POINTER_SIZE)
1422     return;
1423 
1424   /* Handle also e.g. &s->i.  */
1425   if (TREE_CODE (t) == ADDR_EXPR)
1426     t = TREE_OPERAND (t, 0);
1427 
1428   if (!handled_component_p (t) && TREE_CODE (t) != MEM_REF)
1429     return;
1430 
1431   poly_int64 bitsize, bitpos, bytepos;
1432   tree offset;
1433   machine_mode mode;
1434   int volatilep = 0, reversep, unsignedp = 0;
1435   tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1436 				    &unsignedp, &reversep, &volatilep);
1437   tree moff = NULL_TREE;
1438 
1439   bool decl_p = DECL_P (inner);
1440   tree base;
1441   if (decl_p)
1442     {
1443       if (DECL_REGISTER (inner))
1444 	return;
1445       base = inner;
1446       /* If BASE is a fixed size automatic variable or
1447 	 global variable defined in the current TU and bitpos
1448 	 fits, don't instrument anything.  */
1449       poly_int64 base_size;
1450       if (offset == NULL_TREE
1451 	  && maybe_ne (bitpos, 0)
1452 	  && (VAR_P (base)
1453 	      || TREE_CODE (base) == PARM_DECL
1454 	      || TREE_CODE (base) == RESULT_DECL)
1455 	  && poly_int_tree_p (DECL_SIZE (base), &base_size)
1456 	  && known_ge (base_size, bitpos)
1457 	  && (!is_global_var (base) || decl_binds_to_current_def_p (base)))
1458 	return;
1459     }
1460   else if (TREE_CODE (inner) == MEM_REF)
1461     {
1462       base = TREE_OPERAND (inner, 0);
1463       if (TREE_CODE (base) == ADDR_EXPR
1464 	  && DECL_P (TREE_OPERAND (base, 0))
1465 	  && !TREE_ADDRESSABLE (TREE_OPERAND (base, 0))
1466 	  && !is_global_var (TREE_OPERAND (base, 0)))
1467 	return;
1468       moff = TREE_OPERAND (inner, 1);
1469       if (integer_zerop (moff))
1470 	moff = NULL_TREE;
1471     }
1472   else
1473     return;
1474 
1475   if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1476     return;
1477   bytepos = bits_to_bytes_round_down (bitpos);
1478   if (offset == NULL_TREE && known_eq (bytepos, 0) && moff == NULL_TREE)
1479     return;
1480 
1481   tree base_addr = base;
1482   if (decl_p)
1483     base_addr = build1 (ADDR_EXPR,
1484 			build_pointer_type (TREE_TYPE (base)), base);
1485   t = offset;
1486   if (maybe_ne (bytepos, 0))
1487     {
1488       if (t)
1489 	t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t,
1490 			 build_int_cst (TREE_TYPE (t), bytepos));
1491       else
1492 	t = size_int (bytepos);
1493     }
1494   if (moff)
1495     {
1496       if (t)
1497 	t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t,
1498 			 fold_convert (TREE_TYPE (t), moff));
1499       else
1500 	t = fold_convert (sizetype, moff);
1501     }
1502   t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1503 				GSI_SAME_STMT);
1504   base_addr = force_gimple_operand_gsi (gsi, base_addr, true, NULL_TREE, true,
1505 					GSI_SAME_STMT);
1506   instrument_pointer_overflow (gsi, base_addr, t);
1507 }
1508 
1509 /* Build an ubsan builtin call for the signed-integer-overflow
1510    sanitization.  CODE says what kind of builtin are we building,
1511    LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1512    are operands of the binary operation.  */
1513 
1514 tree
ubsan_build_overflow_builtin(tree_code code,location_t loc,tree lhstype,tree op0,tree op1,tree * datap)1515 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1516 			      tree op0, tree op1, tree *datap)
1517 {
1518   if (flag_sanitize_undefined_trap_on_error)
1519     return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1520 
1521   tree data;
1522   if (datap && *datap)
1523     data = *datap;
1524   else
1525     data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1526 			      ubsan_type_descriptor (lhstype), NULL_TREE,
1527 			      NULL_TREE);
1528   if (datap)
1529     *datap = data;
1530   enum built_in_function fn_code;
1531 
1532   switch (code)
1533     {
1534     case PLUS_EXPR:
1535       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1536 		? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1537 		: BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1538       break;
1539     case MINUS_EXPR:
1540       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1541 		? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1542 		: BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1543       break;
1544     case MULT_EXPR:
1545       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1546 		? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1547 		: BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1548       break;
1549     case NEGATE_EXPR:
1550       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1551 		? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1552 		: BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1553       break;
1554     default:
1555       gcc_unreachable ();
1556     }
1557   tree fn = builtin_decl_explicit (fn_code);
1558   return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1559 			      build_fold_addr_expr_loc (loc, data),
1560 			      ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL),
1561 			      op1
1562 			      ? ubsan_encode_value (op1,
1563 						    UBSAN_ENCODE_VALUE_RTL)
1564 			      : NULL_TREE);
1565 }
1566 
1567 /* Perform the signed integer instrumentation.  GSI is the iterator
1568    pointing at statement we are trying to instrument.  */
1569 
1570 static void
instrument_si_overflow(gimple_stmt_iterator gsi)1571 instrument_si_overflow (gimple_stmt_iterator gsi)
1572 {
1573   gimple *stmt = gsi_stmt (gsi);
1574   tree_code code = gimple_assign_rhs_code (stmt);
1575   tree lhs = gimple_assign_lhs (stmt);
1576   tree lhstype = TREE_TYPE (lhs);
1577   tree lhsinner = VECTOR_TYPE_P (lhstype) ? TREE_TYPE (lhstype) : lhstype;
1578   tree a, b;
1579   gimple *g;
1580 
1581   /* If this is not a signed operation, don't instrument anything here.
1582      Also punt on bit-fields.  */
1583   if (!INTEGRAL_TYPE_P (lhsinner)
1584       || TYPE_OVERFLOW_WRAPS (lhsinner)
1585       || maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (lhsinner)),
1586 		   TYPE_PRECISION (lhsinner)))
1587     return;
1588 
1589   switch (code)
1590     {
1591     case MINUS_EXPR:
1592     case PLUS_EXPR:
1593     case MULT_EXPR:
1594       /* Transform
1595 	 i = u {+,-,*} 5;
1596 	 into
1597 	 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5);  */
1598       a = gimple_assign_rhs1 (stmt);
1599       b = gimple_assign_rhs2 (stmt);
1600       g = gimple_build_call_internal (code == PLUS_EXPR
1601 				      ? IFN_UBSAN_CHECK_ADD
1602 				      : code == MINUS_EXPR
1603 				      ? IFN_UBSAN_CHECK_SUB
1604 				      : IFN_UBSAN_CHECK_MUL, 2, a, b);
1605       gimple_call_set_lhs (g, lhs);
1606       gsi_replace (&gsi, g, true);
1607       break;
1608     case NEGATE_EXPR:
1609       /* Represent i = -u;
1610 	 as
1611 	 i = UBSAN_CHECK_SUB (0, u);  */
1612       a = build_zero_cst (lhstype);
1613       b = gimple_assign_rhs1 (stmt);
1614       g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1615       gimple_call_set_lhs (g, lhs);
1616       gsi_replace (&gsi, g, true);
1617       break;
1618     case ABS_EXPR:
1619       /* Transform i = ABS_EXPR<u>;
1620 	 into
1621 	 _N = UBSAN_CHECK_SUB (0, u);
1622 	 i = ABS_EXPR<_N>;  */
1623       a = build_zero_cst (lhstype);
1624       b = gimple_assign_rhs1 (stmt);
1625       g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1626       a = make_ssa_name (lhstype);
1627       gimple_call_set_lhs (g, a);
1628       gimple_set_location (g, gimple_location (stmt));
1629       gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1630       gimple_assign_set_rhs1 (stmt, a);
1631       update_stmt (stmt);
1632       break;
1633     default:
1634       break;
1635     }
1636 }
1637 
1638 /* Instrument loads from (non-bitfield) bool and C++ enum values
1639    to check if the memory value is outside of the range of the valid
1640    type values.  */
1641 
1642 static void
instrument_bool_enum_load(gimple_stmt_iterator * gsi)1643 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1644 {
1645   gimple *stmt = gsi_stmt (*gsi);
1646   tree rhs = gimple_assign_rhs1 (stmt);
1647   tree type = TREE_TYPE (rhs);
1648   tree minv = NULL_TREE, maxv = NULL_TREE;
1649 
1650   if (TREE_CODE (type) == BOOLEAN_TYPE
1651       && sanitize_flags_p (SANITIZE_BOOL))
1652     {
1653       minv = boolean_false_node;
1654       maxv = boolean_true_node;
1655     }
1656   else if (TREE_CODE (type) == ENUMERAL_TYPE
1657 	   && sanitize_flags_p (SANITIZE_ENUM)
1658 	   && TREE_TYPE (type) != NULL_TREE
1659 	   && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1660 	   && (TYPE_PRECISION (TREE_TYPE (type))
1661 	       < GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (type))))
1662     {
1663       minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1664       maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1665     }
1666   else
1667     return;
1668 
1669   int modebitsize = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type));
1670   poly_int64 bitsize, bitpos;
1671   tree offset;
1672   machine_mode mode;
1673   int volatilep = 0, reversep, unsignedp = 0;
1674   tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1675 				   &unsignedp, &reversep, &volatilep);
1676   tree utype = build_nonstandard_integer_type (modebitsize, 1);
1677 
1678   if ((VAR_P (base) && DECL_HARD_REGISTER (base))
1679       || !multiple_p (bitpos, modebitsize)
1680       || maybe_ne (bitsize, modebitsize)
1681       || GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (utype)) != modebitsize
1682       || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1683     return;
1684 
1685   bool ends_bb = stmt_ends_bb_p (stmt);
1686   location_t loc = gimple_location (stmt);
1687   tree lhs = gimple_assign_lhs (stmt);
1688   tree ptype = build_pointer_type (TREE_TYPE (rhs));
1689   tree atype = reference_alias_ptr_type (rhs);
1690   gimple *g = gimple_build_assign (make_ssa_name (ptype),
1691 				  build_fold_addr_expr (rhs));
1692   gimple_set_location (g, loc);
1693   gsi_insert_before (gsi, g, GSI_SAME_STMT);
1694   tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1695 		     build_int_cst (atype, 0));
1696   tree urhs = make_ssa_name (utype);
1697   if (ends_bb)
1698     {
1699       gimple_assign_set_lhs (stmt, urhs);
1700       g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1701       gimple_set_location (g, loc);
1702       edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1703       gsi_insert_on_edge_immediate (e, g);
1704       gimple_assign_set_rhs_from_tree (gsi, mem);
1705       update_stmt (stmt);
1706       *gsi = gsi_for_stmt (g);
1707       g = stmt;
1708     }
1709   else
1710     {
1711       g = gimple_build_assign (urhs, mem);
1712       gimple_set_location (g, loc);
1713       gsi_insert_before (gsi, g, GSI_SAME_STMT);
1714     }
1715   minv = fold_convert (utype, minv);
1716   maxv = fold_convert (utype, maxv);
1717   if (!integer_zerop (minv))
1718     {
1719       g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1720       gimple_set_location (g, loc);
1721       gsi_insert_before (gsi, g, GSI_SAME_STMT);
1722     }
1723 
1724   gimple_stmt_iterator gsi2 = *gsi;
1725   basic_block then_bb, fallthru_bb;
1726   *gsi = create_cond_insert_point (gsi, true, false, true,
1727 				   &then_bb, &fallthru_bb);
1728   g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1729 			 int_const_binop (MINUS_EXPR, maxv, minv),
1730 			 NULL_TREE, NULL_TREE);
1731   gimple_set_location (g, loc);
1732   gsi_insert_after (gsi, g, GSI_NEW_STMT);
1733 
1734   if (!ends_bb)
1735     {
1736       gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1737       update_stmt (stmt);
1738     }
1739 
1740   gsi2 = gsi_after_labels (then_bb);
1741   if (flag_sanitize_undefined_trap_on_error)
1742     g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1743   else
1744     {
1745       tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1746 				     ubsan_type_descriptor (type), NULL_TREE,
1747 				     NULL_TREE);
1748       data = build_fold_addr_expr_loc (loc, data);
1749       enum built_in_function bcode
1750 	= (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1751 				    ? SANITIZE_BOOL : SANITIZE_ENUM))
1752 	  ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1753 	  : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1754       tree fn = builtin_decl_explicit (bcode);
1755 
1756       tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE);
1757       val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true,
1758 				      GSI_SAME_STMT);
1759       g = gimple_build_call (fn, 2, data, val);
1760     }
1761   gimple_set_location (g, loc);
1762   gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1763   ubsan_create_edge (g);
1764   *gsi = gsi_for_stmt (stmt);
1765 }
1766 
1767 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1768    new style handlers.  Libubsan uses heuristics to destinguish between old and
1769    new styles and relies on these properties for filename:
1770 
1771    a) Location's filename must not be NULL.
1772    b) Location's filename must not be equal to "".
1773    c) Location's filename must not be equal to "\1".
1774    d) First two bytes of filename must not contain '\xff' symbol.  */
1775 
1776 static bool
ubsan_use_new_style_p(location_t loc)1777 ubsan_use_new_style_p (location_t loc)
1778 {
1779   if (loc == UNKNOWN_LOCATION)
1780     return false;
1781 
1782   expanded_location xloc = expand_location (loc);
1783   if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1784       || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1785       || xloc.file[1] == '\xff')
1786     return false;
1787 
1788   return true;
1789 }
1790 
1791 /* Instrument float point-to-integer conversion.  TYPE is an integer type of
1792    destination, EXPR is floating-point expression.  */
1793 
1794 tree
ubsan_instrument_float_cast(location_t loc,tree type,tree expr)1795 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1796 {
1797   tree expr_type = TREE_TYPE (expr);
1798   tree t, tt, fn, min, max;
1799   machine_mode mode = TYPE_MODE (expr_type);
1800   int prec = TYPE_PRECISION (type);
1801   bool uns_p = TYPE_UNSIGNED (type);
1802   if (loc == UNKNOWN_LOCATION)
1803     loc = input_location;
1804 
1805   /* Float to integer conversion first truncates toward zero, so
1806      even signed char c = 127.875f; is not problematic.
1807      Therefore, we should complain only if EXPR is unordered or smaller
1808      or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1809      TYPE_MAX_VALUE + 1.0.  */
1810   if (REAL_MODE_FORMAT (mode)->b == 2)
1811     {
1812       /* For maximum, TYPE_MAX_VALUE might not be representable
1813 	 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1814 	 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1815 	 either representable or infinity.  */
1816       REAL_VALUE_TYPE maxval = dconst1;
1817       SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1818       real_convert (&maxval, mode, &maxval);
1819       max = build_real (expr_type, maxval);
1820 
1821       /* For unsigned, assume -1.0 is always representable.  */
1822       if (uns_p)
1823 	min = build_minus_one_cst (expr_type);
1824       else
1825 	{
1826 	  /* TYPE_MIN_VALUE is generally representable (or -inf),
1827 	     but TYPE_MIN_VALUE - 1.0 might not be.  */
1828 	  REAL_VALUE_TYPE minval = dconstm1, minval2;
1829 	  SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1830 	  real_convert (&minval, mode, &minval);
1831 	  real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1832 	  real_convert (&minval2, mode, &minval2);
1833 	  if (real_compare (EQ_EXPR, &minval, &minval2)
1834 	      && !real_isinf (&minval))
1835 	    {
1836 	      /* If TYPE_MIN_VALUE - 1.0 is not representable and
1837 		 rounds to TYPE_MIN_VALUE, we need to subtract
1838 		 more.  As REAL_MODE_FORMAT (mode)->p is the number
1839 		 of base digits, we want to subtract a number that
1840 		 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1841 		 times smaller than minval.  */
1842 	      minval2 = dconst1;
1843 	      gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1844 	      SET_REAL_EXP (&minval2,
1845 			    REAL_EXP (&minval2) + prec - 1
1846 			    - REAL_MODE_FORMAT (mode)->p + 1);
1847 	      real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1848 	      real_convert (&minval2, mode, &minval2);
1849 	    }
1850 	  min = build_real (expr_type, minval2);
1851 	}
1852     }
1853   else if (REAL_MODE_FORMAT (mode)->b == 10)
1854     {
1855       /* For _Decimal128 up to 34 decimal digits, - sign,
1856 	 dot, e, exponent.  */
1857       char buf[64];
1858       mpfr_t m;
1859       int p = REAL_MODE_FORMAT (mode)->p;
1860       REAL_VALUE_TYPE maxval, minval;
1861 
1862       /* Use mpfr_snprintf rounding to compute the smallest
1863 	 representable decimal number greater or equal than
1864 	 1 << (prec - !uns_p).  */
1865       mpfr_init2 (m, prec + 2);
1866       mpfr_set_ui_2exp (m, 1, prec - !uns_p, MPFR_RNDN);
1867       mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1868       decimal_real_from_string (&maxval, buf);
1869       max = build_real (expr_type, maxval);
1870 
1871       /* For unsigned, assume -1.0 is always representable.  */
1872       if (uns_p)
1873 	min = build_minus_one_cst (expr_type);
1874       else
1875 	{
1876 	  /* Use mpfr_snprintf rounding to compute the largest
1877 	     representable decimal number less or equal than
1878 	     (-1 << (prec - 1)) - 1.  */
1879 	  mpfr_set_si_2exp (m, -1, prec - 1, MPFR_RNDN);
1880 	  mpfr_sub_ui (m, m, 1, MPFR_RNDN);
1881 	  mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1882 	  decimal_real_from_string (&minval, buf);
1883 	  min = build_real (expr_type, minval);
1884 	}
1885       mpfr_clear (m);
1886     }
1887   else
1888     return NULL_TREE;
1889 
1890   t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1891   tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1892   t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1893   if (integer_zerop (t))
1894     return NULL_TREE;
1895 
1896   if (flag_sanitize_undefined_trap_on_error)
1897     fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1898   else
1899     {
1900       location_t *loc_ptr = NULL;
1901       unsigned num_locations = 0;
1902       /* Figure out if we can propagate location to ubsan_data and use new
1903          style handlers in libubsan.  */
1904       if (ubsan_use_new_style_p (loc))
1905 	{
1906 	  loc_ptr = &loc;
1907 	  num_locations = 1;
1908 	}
1909       /* Create the __ubsan_handle_float_cast_overflow fn call.  */
1910       tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1911 				     num_locations, loc_ptr,
1912 				     ubsan_type_descriptor (expr_type),
1913 				     ubsan_type_descriptor (type), NULL_TREE,
1914 				     NULL_TREE);
1915       enum built_in_function bcode
1916 	= (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1917 	  ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1918 	  : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1919       fn = builtin_decl_explicit (bcode);
1920       fn = build_call_expr_loc (loc, fn, 2,
1921 				build_fold_addr_expr_loc (loc, data),
1922 				ubsan_encode_value (expr));
1923     }
1924 
1925   return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1926 }
1927 
1928 /* Instrument values passed to function arguments with nonnull attribute.  */
1929 
1930 static void
instrument_nonnull_arg(gimple_stmt_iterator * gsi)1931 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1932 {
1933   gimple *stmt = gsi_stmt (*gsi);
1934   location_t loc[2];
1935   /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1936      while for nonnull sanitization it is clear.  */
1937   int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1938   flag_delete_null_pointer_checks = 1;
1939   loc[0] = gimple_location (stmt);
1940   loc[1] = UNKNOWN_LOCATION;
1941   for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1942     {
1943       tree arg = gimple_call_arg (stmt, i);
1944       if (POINTER_TYPE_P (TREE_TYPE (arg))
1945 	  && infer_nonnull_range_by_attribute (stmt, arg))
1946 	{
1947 	  gimple *g;
1948 	  if (!is_gimple_val (arg))
1949 	    {
1950 	      g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1951 	      gimple_set_location (g, loc[0]);
1952 	      gsi_insert_before (gsi, g, GSI_SAME_STMT);
1953 	      arg = gimple_assign_lhs (g);
1954 	    }
1955 
1956 	  basic_block then_bb, fallthru_bb;
1957 	  *gsi = create_cond_insert_point (gsi, true, false, true,
1958 					   &then_bb, &fallthru_bb);
1959 	  g = gimple_build_cond (EQ_EXPR, arg,
1960 				 build_zero_cst (TREE_TYPE (arg)),
1961 				 NULL_TREE, NULL_TREE);
1962 	  gimple_set_location (g, loc[0]);
1963 	  gsi_insert_after (gsi, g, GSI_NEW_STMT);
1964 
1965 	  *gsi = gsi_after_labels (then_bb);
1966 	  if (flag_sanitize_undefined_trap_on_error)
1967 	    g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1968 	  else
1969 	    {
1970 	      tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1971 					     2, loc, NULL_TREE,
1972 					     build_int_cst (integer_type_node,
1973 							    i + 1),
1974 					     NULL_TREE);
1975 	      data = build_fold_addr_expr_loc (loc[0], data);
1976 	      enum built_in_function bcode
1977 		= (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1978 		  ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1979 		  : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1980 	      tree fn = builtin_decl_explicit (bcode);
1981 
1982 	      g = gimple_build_call (fn, 1, data);
1983 	    }
1984 	  gimple_set_location (g, loc[0]);
1985 	  gsi_insert_before (gsi, g, GSI_SAME_STMT);
1986 	  ubsan_create_edge (g);
1987 	}
1988       *gsi = gsi_for_stmt (stmt);
1989     }
1990   flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1991 }
1992 
1993 /* Instrument returns in functions with returns_nonnull attribute.  */
1994 
1995 static void
instrument_nonnull_return(gimple_stmt_iterator * gsi)1996 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1997 {
1998   greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1999   location_t loc[2];
2000   tree arg = gimple_return_retval (stmt);
2001   /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
2002      while for nonnull return sanitization it is clear.  */
2003   int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
2004   flag_delete_null_pointer_checks = 1;
2005   loc[0] = gimple_location (stmt);
2006   loc[1] = UNKNOWN_LOCATION;
2007   if (arg
2008       && POINTER_TYPE_P (TREE_TYPE (arg))
2009       && is_gimple_val (arg)
2010       && infer_nonnull_range_by_attribute (stmt, arg))
2011     {
2012       basic_block then_bb, fallthru_bb;
2013       *gsi = create_cond_insert_point (gsi, true, false, true,
2014 				       &then_bb, &fallthru_bb);
2015       gimple *g = gimple_build_cond (EQ_EXPR, arg,
2016 				    build_zero_cst (TREE_TYPE (arg)),
2017 				    NULL_TREE, NULL_TREE);
2018       gimple_set_location (g, loc[0]);
2019       gsi_insert_after (gsi, g, GSI_NEW_STMT);
2020 
2021       *gsi = gsi_after_labels (then_bb);
2022       if (flag_sanitize_undefined_trap_on_error)
2023 	g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2024       else
2025 	{
2026 	  tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
2027 					 1, &loc[1], NULL_TREE, NULL_TREE);
2028 	  data = build_fold_addr_expr_loc (loc[0], data);
2029 	  tree data2 = ubsan_create_data ("__ubsan_nonnull_return_data",
2030 					  1, &loc[0], NULL_TREE, NULL_TREE);
2031 	  data2 = build_fold_addr_expr_loc (loc[0], data2);
2032 	  enum built_in_function bcode
2033 	    = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2034 	      ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1
2035 	      : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1_ABORT;
2036 	  tree fn = builtin_decl_explicit (bcode);
2037 
2038 	  g = gimple_build_call (fn, 2, data, data2);
2039 	}
2040       gimple_set_location (g, loc[0]);
2041       gsi_insert_before (gsi, g, GSI_SAME_STMT);
2042       ubsan_create_edge (g);
2043       *gsi = gsi_for_stmt (stmt);
2044     }
2045   flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
2046 }
2047 
2048 /* Instrument memory references.  Here we check whether the pointer
2049    points to an out-of-bounds location.  */
2050 
2051 static void
instrument_object_size(gimple_stmt_iterator * gsi,tree t,bool is_lhs)2052 instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
2053 {
2054   gimple *stmt = gsi_stmt (*gsi);
2055   location_t loc = gimple_location (stmt);
2056   tree type;
2057   tree index = NULL_TREE;
2058   HOST_WIDE_INT size_in_bytes;
2059 
2060   type = TREE_TYPE (t);
2061   if (VOID_TYPE_P (type))
2062     return;
2063 
2064   switch (TREE_CODE (t))
2065     {
2066     case COMPONENT_REF:
2067       if (TREE_CODE (t) == COMPONENT_REF
2068 	  && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
2069 	{
2070 	  tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
2071 	  t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
2072 		      repr, TREE_OPERAND (t, 2));
2073 	}
2074       break;
2075     case ARRAY_REF:
2076       index = TREE_OPERAND (t, 1);
2077       break;
2078     case INDIRECT_REF:
2079     case MEM_REF:
2080     case VAR_DECL:
2081     case PARM_DECL:
2082     case RESULT_DECL:
2083       break;
2084     default:
2085       return;
2086     }
2087 
2088   size_in_bytes = int_size_in_bytes (type);
2089   if (size_in_bytes <= 0)
2090     return;
2091 
2092   poly_int64 bitsize, bitpos;
2093   tree offset;
2094   machine_mode mode;
2095   int volatilep = 0, reversep, unsignedp = 0;
2096   tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
2097 				    &unsignedp, &reversep, &volatilep);
2098 
2099   if (!multiple_p (bitpos, BITS_PER_UNIT)
2100       || maybe_ne (bitsize, size_in_bytes * BITS_PER_UNIT))
2101     return;
2102 
2103   bool decl_p = DECL_P (inner);
2104   tree base;
2105   if (decl_p)
2106     {
2107       if (DECL_REGISTER (inner))
2108 	return;
2109       base = inner;
2110     }
2111   else if (TREE_CODE (inner) == MEM_REF)
2112     base = TREE_OPERAND (inner, 0);
2113   else
2114     return;
2115   tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
2116 
2117   while (TREE_CODE (base) == SSA_NAME)
2118     {
2119       gimple *def_stmt = SSA_NAME_DEF_STMT (base);
2120       if (gimple_assign_ssa_name_copy_p (def_stmt)
2121 	  || (gimple_assign_cast_p (def_stmt)
2122 	      && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
2123 	  || (is_gimple_assign (def_stmt)
2124 	      && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
2125 	{
2126 	  tree rhs1 = gimple_assign_rhs1 (def_stmt);
2127 	  if (TREE_CODE (rhs1) == SSA_NAME
2128 	      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
2129 	    break;
2130 	  else
2131 	    base = rhs1;
2132 	}
2133       else
2134 	break;
2135     }
2136 
2137   if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
2138     return;
2139 
2140   tree sizet;
2141   tree base_addr = base;
2142   gimple *bos_stmt = NULL;
2143   if (decl_p)
2144     base_addr = build1 (ADDR_EXPR,
2145 			build_pointer_type (TREE_TYPE (base)), base);
2146   unsigned HOST_WIDE_INT size;
2147   if (compute_builtin_object_size (base_addr, 0, &size))
2148     sizet = build_int_cst (sizetype, size);
2149   else if (optimize)
2150     {
2151       if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
2152 	loc = input_location;
2153       /* Generate __builtin_object_size call.  */
2154       sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
2155       sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
2156 				   integer_zero_node);
2157       sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
2158 					GSI_SAME_STMT);
2159       /* If the call above didn't end up being an integer constant, go one
2160 	 statement back and get the __builtin_object_size stmt.  Save it,
2161 	 we might need it later.  */
2162       if (SSA_VAR_P (sizet))
2163 	{
2164 	  gsi_prev (gsi);
2165 	  bos_stmt = gsi_stmt (*gsi);
2166 
2167 	  /* Move on to where we were.  */
2168 	  gsi_next (gsi);
2169 	}
2170     }
2171   else
2172     return;
2173 
2174   /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
2175      call.  */
2176   /* ptr + sizeof (*ptr) - base */
2177   t = fold_build2 (MINUS_EXPR, sizetype,
2178 		   fold_convert (pointer_sized_int_node, ptr),
2179 		   fold_convert (pointer_sized_int_node, base_addr));
2180   t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
2181 
2182   /* Perhaps we can omit the check.  */
2183   if (TREE_CODE (t) == INTEGER_CST
2184       && TREE_CODE (sizet) == INTEGER_CST
2185       && tree_int_cst_le (t, sizet))
2186     return;
2187 
2188   if (index != NULL_TREE
2189       && TREE_CODE (index) == SSA_NAME
2190       && TREE_CODE (sizet) == INTEGER_CST)
2191     {
2192       gimple *def = SSA_NAME_DEF_STMT (index);
2193       if (is_gimple_assign (def)
2194 	  && gimple_assign_rhs_code (def) == BIT_AND_EXPR
2195 	  && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
2196 	{
2197 	  tree cst = gimple_assign_rhs2 (def);
2198 	  tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
2199 				 TYPE_SIZE_UNIT (type));
2200 	  if (tree_int_cst_sgn (cst) >= 0
2201 	      && tree_int_cst_lt (cst, sz))
2202 	    return;
2203 	}
2204     }
2205 
2206   if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
2207     ubsan_create_edge (bos_stmt);
2208 
2209   /* We have to emit the check.  */
2210   t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
2211 				GSI_SAME_STMT);
2212   ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
2213 				  GSI_SAME_STMT);
2214   tree ckind = build_int_cst (unsigned_char_type_node,
2215 			      is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
2216   gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
2217 					 ptr, t, sizet, ckind);
2218   gimple_set_location (g, loc);
2219   gsi_insert_before (gsi, g, GSI_SAME_STMT);
2220 }
2221 
2222 /* Instrument values passed to builtin functions.  */
2223 
2224 static void
instrument_builtin(gimple_stmt_iterator * gsi)2225 instrument_builtin (gimple_stmt_iterator *gsi)
2226 {
2227   gimple *stmt = gsi_stmt (*gsi);
2228   location_t loc = gimple_location (stmt);
2229   tree arg;
2230   enum built_in_function fcode
2231     = DECL_FUNCTION_CODE (gimple_call_fndecl (stmt));
2232   int kind = 0;
2233   switch (fcode)
2234     {
2235     CASE_INT_FN (BUILT_IN_CLZ):
2236       kind = 1;
2237       gcc_fallthrough ();
2238     CASE_INT_FN (BUILT_IN_CTZ):
2239       arg = gimple_call_arg (stmt, 0);
2240       if (!integer_nonzerop (arg))
2241 	{
2242 	  gimple *g;
2243 	  if (!is_gimple_val (arg))
2244 	    {
2245 	      g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
2246 	      gimple_set_location (g, loc);
2247 	      gsi_insert_before (gsi, g, GSI_SAME_STMT);
2248 	      arg = gimple_assign_lhs (g);
2249 	    }
2250 
2251 	  basic_block then_bb, fallthru_bb;
2252 	  *gsi = create_cond_insert_point (gsi, true, false, true,
2253 					   &then_bb, &fallthru_bb);
2254 	  g = gimple_build_cond (EQ_EXPR, arg,
2255 				 build_zero_cst (TREE_TYPE (arg)),
2256 				 NULL_TREE, NULL_TREE);
2257 	  gimple_set_location (g, loc);
2258 	  gsi_insert_after (gsi, g, GSI_NEW_STMT);
2259 
2260 	  *gsi = gsi_after_labels (then_bb);
2261 	  if (flag_sanitize_undefined_trap_on_error)
2262 	    g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2263 	  else
2264 	    {
2265 	      tree t = build_int_cst (unsigned_char_type_node, kind);
2266 	      tree data = ubsan_create_data ("__ubsan_builtin_data",
2267 					     1, &loc, NULL_TREE, t, NULL_TREE);
2268 	      data = build_fold_addr_expr_loc (loc, data);
2269 	      enum built_in_function bcode
2270 		= (flag_sanitize_recover & SANITIZE_BUILTIN)
2271 		  ? BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN
2272 		  : BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN_ABORT;
2273 	      tree fn = builtin_decl_explicit (bcode);
2274 
2275 	      g = gimple_build_call (fn, 1, data);
2276 	    }
2277 	  gimple_set_location (g, loc);
2278 	  gsi_insert_before (gsi, g, GSI_SAME_STMT);
2279 	  ubsan_create_edge (g);
2280 	}
2281       *gsi = gsi_for_stmt (stmt);
2282       break;
2283     default:
2284       break;
2285     }
2286 }
2287 
2288 namespace {
2289 
2290 const pass_data pass_data_ubsan =
2291 {
2292   GIMPLE_PASS, /* type */
2293   "ubsan", /* name */
2294   OPTGROUP_NONE, /* optinfo_flags */
2295   TV_TREE_UBSAN, /* tv_id */
2296   ( PROP_cfg | PROP_ssa ), /* properties_required */
2297   0, /* properties_provided */
2298   0, /* properties_destroyed */
2299   0, /* todo_flags_start */
2300   TODO_update_ssa, /* todo_flags_finish */
2301 };
2302 
2303 class pass_ubsan : public gimple_opt_pass
2304 {
2305 public:
pass_ubsan(gcc::context * ctxt)2306   pass_ubsan (gcc::context *ctxt)
2307     : gimple_opt_pass (pass_data_ubsan, ctxt)
2308   {}
2309 
2310   /* opt_pass methods: */
gate(function *)2311   virtual bool gate (function *)
2312     {
2313       return sanitize_flags_p ((SANITIZE_NULL | SANITIZE_SI_OVERFLOW
2314 				| SANITIZE_BOOL | SANITIZE_ENUM
2315 				| SANITIZE_ALIGNMENT
2316 				| SANITIZE_NONNULL_ATTRIBUTE
2317 				| SANITIZE_RETURNS_NONNULL_ATTRIBUTE
2318 				| SANITIZE_OBJECT_SIZE
2319 				| SANITIZE_POINTER_OVERFLOW
2320 				| SANITIZE_BUILTIN));
2321     }
2322 
2323   virtual unsigned int execute (function *);
2324 
2325 }; // class pass_ubsan
2326 
2327 unsigned int
execute(function * fun)2328 pass_ubsan::execute (function *fun)
2329 {
2330   basic_block bb;
2331   gimple_stmt_iterator gsi;
2332   unsigned int ret = 0;
2333 
2334   initialize_sanitizer_builtins ();
2335 
2336   FOR_EACH_BB_FN (bb, fun)
2337     {
2338       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
2339 	{
2340 	  gimple *stmt = gsi_stmt (gsi);
2341 	  if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
2342 	    {
2343 	      gsi_next (&gsi);
2344 	      continue;
2345 	    }
2346 
2347 	  if ((sanitize_flags_p (SANITIZE_SI_OVERFLOW, fun->decl))
2348 	      && is_gimple_assign (stmt))
2349 	    instrument_si_overflow (gsi);
2350 
2351 	  if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT, fun->decl))
2352 	    {
2353 	      if (gimple_store_p (stmt))
2354 		instrument_null (gsi, gimple_get_lhs (stmt), true);
2355 	      if (gimple_assign_single_p (stmt))
2356 		instrument_null (gsi, gimple_assign_rhs1 (stmt), false);
2357 	      if (is_gimple_call (stmt))
2358 		{
2359 		  unsigned args_num = gimple_call_num_args (stmt);
2360 		  for (unsigned i = 0; i < args_num; ++i)
2361 		    {
2362 		      tree arg = gimple_call_arg (stmt, i);
2363 		      if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2364 			continue;
2365 		      instrument_null (gsi, arg, false);
2366 		    }
2367 		}
2368 	    }
2369 
2370 	  if (sanitize_flags_p (SANITIZE_BOOL | SANITIZE_ENUM, fun->decl)
2371 	      && gimple_assign_load_p (stmt))
2372 	    {
2373 	      instrument_bool_enum_load (&gsi);
2374 	      bb = gimple_bb (stmt);
2375 	    }
2376 
2377 	  if (sanitize_flags_p (SANITIZE_NONNULL_ATTRIBUTE, fun->decl)
2378 	      && is_gimple_call (stmt)
2379 	      && !gimple_call_internal_p (stmt))
2380 	    {
2381 	      instrument_nonnull_arg (&gsi);
2382 	      bb = gimple_bb (stmt);
2383 	    }
2384 
2385 	  if (sanitize_flags_p (SANITIZE_BUILTIN, fun->decl)
2386 	      && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
2387 	    {
2388 	      instrument_builtin (&gsi);
2389 	      bb = gimple_bb (stmt);
2390 	    }
2391 
2392 	  if (sanitize_flags_p (SANITIZE_RETURNS_NONNULL_ATTRIBUTE, fun->decl)
2393 	      && gimple_code (stmt) == GIMPLE_RETURN)
2394 	    {
2395 	      instrument_nonnull_return (&gsi);
2396 	      bb = gimple_bb (stmt);
2397 	    }
2398 
2399 	  if (sanitize_flags_p (SANITIZE_OBJECT_SIZE, fun->decl))
2400 	    {
2401 	      if (gimple_store_p (stmt))
2402 		instrument_object_size (&gsi, gimple_get_lhs (stmt), true);
2403 	      if (gimple_assign_load_p (stmt))
2404 		instrument_object_size (&gsi, gimple_assign_rhs1 (stmt),
2405 					false);
2406 	      if (is_gimple_call (stmt))
2407 		{
2408 		  unsigned args_num = gimple_call_num_args (stmt);
2409 		  for (unsigned i = 0; i < args_num; ++i)
2410 		    {
2411 		      tree arg = gimple_call_arg (stmt, i);
2412 		      if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2413 			continue;
2414 		      instrument_object_size (&gsi, arg, false);
2415 		    }
2416 		}
2417 	    }
2418 
2419 	  if (sanitize_flags_p (SANITIZE_POINTER_OVERFLOW, fun->decl))
2420 	    {
2421 	      if (is_gimple_assign (stmt)
2422 		  && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
2423 		instrument_pointer_overflow (&gsi,
2424 					     gimple_assign_rhs1 (stmt),
2425 					     gimple_assign_rhs2 (stmt));
2426 	      if (gimple_store_p (stmt))
2427 		maybe_instrument_pointer_overflow (&gsi,
2428 						   gimple_get_lhs (stmt));
2429 	      if (gimple_assign_single_p (stmt))
2430 		maybe_instrument_pointer_overflow (&gsi,
2431 						   gimple_assign_rhs1 (stmt));
2432 	      if (is_gimple_call (stmt))
2433 		{
2434 		  unsigned args_num = gimple_call_num_args (stmt);
2435 		  for (unsigned i = 0; i < args_num; ++i)
2436 		    {
2437 		      tree arg = gimple_call_arg (stmt, i);
2438 		      if (is_gimple_reg (arg))
2439 			continue;
2440 		      maybe_instrument_pointer_overflow (&gsi, arg);
2441 		    }
2442 		}
2443 	    }
2444 
2445 	  gsi_next (&gsi);
2446 	}
2447       if (gimple_purge_dead_eh_edges (bb))
2448 	ret = TODO_cleanup_cfg;
2449     }
2450   return ret;
2451 }
2452 
2453 } // anon namespace
2454 
2455 gimple_opt_pass *
make_pass_ubsan(gcc::context * ctxt)2456 make_pass_ubsan (gcc::context *ctxt)
2457 {
2458   return new pass_ubsan (ctxt);
2459 }
2460 
2461 #include "gt-ubsan.h"
2462