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