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