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