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