1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2015 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
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
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
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/>. */
23 #include "coretypes.h"
27 #include "double-int.h"
35 #include "fold-const.h"
36 #include "stor-layout.h"
37 #include "stringpool.h"
39 #include "dominance.h"
42 #include "basic-block.h"
45 #include "plugin-api.h"
47 #include "hard-reg-set.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"
57 #include "gimple-iterator.h"
58 #include "gimple-ssa.h"
59 #include "gimple-walk.h"
65 #include "c-family/c-common.h"
69 #include "statistics.h"
71 #include "fixed-value.h"
72 #include "insn-config.h"
81 #include "tree-ssanames.h"
83 #include "gimplify-me.h"
88 #include "tree-object-size.h"
92 /* Map from a tree to a VAR_DECL tree. */
94 struct GTY((for_user)) tree_type_map {
95 struct tree_map_base type;
99 struct tree_type_map_cache_hasher : ggc_cache_hasher<tree_type_map *>
101 static inline hashval_t
102 hash (tree_type_map *t)
104 return TYPE_UID (t->type.from);
108 equal (tree_type_map *a, tree_type_map *b)
110 return a->type.from == b->type.from;
114 handle_cache_entry (tree_type_map *&m)
116 extern void gt_ggc_mx (tree_type_map *&);
117 if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
119 else if (ggc_marked_p (m->type.from))
122 m = static_cast<tree_type_map *> (HTAB_DELETED_ENTRY);
127 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
129 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
132 decl_for_type_lookup (tree type)
134 /* If the hash table is not initialized yet, create it now. */
135 if (decl_tree_for_type == NULL)
138 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
139 /* That also means we don't have to bother with the lookup. */
143 struct tree_type_map *h, in;
146 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
147 return h ? h->decl : NULL_TREE;
150 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
153 decl_for_type_insert (tree type, tree decl)
155 struct tree_type_map *h;
157 h = ggc_alloc<tree_type_map> ();
160 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
163 /* Helper routine, which encodes a value in the pointer_sized_int_node.
164 Arguments with precision <= POINTER_SIZE are passed directly,
165 the rest is passed by reference. T is a value we are to encode.
166 IN_EXPAND_P is true if this function is called during expansion. */
169 ubsan_encode_value (tree t, bool in_expand_p)
171 tree type = TREE_TYPE (t);
172 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
173 if (bitsize <= POINTER_SIZE)
174 switch (TREE_CODE (type))
179 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
182 tree itype = build_nonstandard_integer_type (bitsize, true);
183 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
184 return fold_convert (pointer_sized_int_node, t);
191 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
193 /* The reason for this is that we don't want to pessimize
194 code by making vars unnecessarily addressable. */
195 tree var = create_tmp_var (type);
196 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
200 = assign_stack_temp_for_type (TYPE_MODE (type),
201 GET_MODE_SIZE (TYPE_MODE (type)),
203 SET_DECL_RTL (var, mem);
204 expand_assignment (var, t, false);
205 return build_fold_addr_expr (var);
207 t = build_fold_addr_expr (var);
208 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
211 return build_fold_addr_expr (t);
215 /* Cached ubsan_get_type_descriptor_type () return value. */
216 static GTY(()) tree ubsan_type_descriptor_type;
219 struct __ubsan_type_descriptor
221 unsigned short __typekind;
222 unsigned short __typeinfo;
228 ubsan_get_type_descriptor_type (void)
230 static const char *field_names[3]
231 = { "__typekind", "__typeinfo", "__typename" };
234 if (ubsan_type_descriptor_type)
235 return ubsan_type_descriptor_type;
237 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
238 tree flex_arr_type = build_array_type (char_type_node, itype);
240 ret = make_node (RECORD_TYPE);
241 for (int i = 0; i < 3; i++)
243 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
244 get_identifier (field_names[i]),
245 (i == 2) ? flex_arr_type
246 : short_unsigned_type_node);
247 DECL_CONTEXT (fields[i]) = ret;
249 DECL_CHAIN (fields[i - 1]) = fields[i];
251 tree type_decl = build_decl (input_location, TYPE_DECL,
252 get_identifier ("__ubsan_type_descriptor"),
254 DECL_IGNORED_P (type_decl) = 1;
255 DECL_ARTIFICIAL (type_decl) = 1;
256 TYPE_FIELDS (ret) = fields[0];
257 TYPE_NAME (ret) = type_decl;
258 TYPE_STUB_DECL (ret) = type_decl;
260 ubsan_type_descriptor_type = ret;
264 /* Cached ubsan_get_source_location_type () return value. */
265 static GTY(()) tree ubsan_source_location_type;
268 struct __ubsan_source_location
270 const char *__filename;
272 unsigned int __column;
277 ubsan_get_source_location_type (void)
279 static const char *field_names[3]
280 = { "__filename", "__line", "__column" };
282 if (ubsan_source_location_type)
283 return ubsan_source_location_type;
285 tree const_char_type = build_qualified_type (char_type_node,
288 ret = make_node (RECORD_TYPE);
289 for (int i = 0; i < 3; i++)
291 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
292 get_identifier (field_names[i]),
293 (i == 0) ? build_pointer_type (const_char_type)
294 : unsigned_type_node);
295 DECL_CONTEXT (fields[i]) = ret;
297 DECL_CHAIN (fields[i - 1]) = fields[i];
299 tree type_decl = build_decl (input_location, TYPE_DECL,
300 get_identifier ("__ubsan_source_location"),
302 DECL_IGNORED_P (type_decl) = 1;
303 DECL_ARTIFICIAL (type_decl) = 1;
304 TYPE_FIELDS (ret) = fields[0];
305 TYPE_NAME (ret) = type_decl;
306 TYPE_STUB_DECL (ret) = type_decl;
308 ubsan_source_location_type = ret;
312 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
313 type with its fields filled from a location_t LOC. */
316 ubsan_source_location (location_t loc)
318 expanded_location xloc;
319 tree type = ubsan_get_source_location_type ();
321 xloc = expand_location (loc);
323 if (xloc.file == NULL)
325 str = build_int_cst (ptr_type_node, 0);
331 /* Fill in the values from LOC. */
332 size_t len = strlen (xloc.file) + 1;
333 str = build_string (len, xloc.file);
334 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
335 TREE_READONLY (str) = 1;
336 TREE_STATIC (str) = 1;
337 str = build_fold_addr_expr (str);
339 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
340 build_int_cst (unsigned_type_node,
341 xloc.line), NULL_TREE,
342 build_int_cst (unsigned_type_node,
344 TREE_CONSTANT (ctor) = 1;
345 TREE_STATIC (ctor) = 1;
350 /* This routine returns a magic number for TYPE. */
352 static unsigned short
353 get_ubsan_type_info_for_type (tree type)
355 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
356 if (TREE_CODE (type) == REAL_TYPE)
357 return tree_to_uhwi (TYPE_SIZE (type));
358 else if (INTEGRAL_TYPE_P (type))
360 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
361 gcc_assert (prec != -1);
362 return (prec << 1) | !TYPE_UNSIGNED (type);
368 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
369 descriptor. It first looks into the hash table; if not found,
370 create the VAR_DECL, put it into the hash table and return the
371 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
372 an enum controlling how we want to print the type. */
375 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
377 /* See through any typedefs. */
378 type = TYPE_MAIN_VARIANT (type);
380 tree decl = decl_for_type_lookup (type);
381 /* It is possible that some of the earlier created DECLs were found
382 unused, in that case they weren't emitted and varpool_node::get
383 returns NULL node on them. But now we really need them. Thus,
385 if (decl != NULL_TREE && varpool_node::get (decl))
386 return build_fold_addr_expr (decl);
388 tree dtype = ubsan_get_type_descriptor_type ();
390 const char *tname = NULL;
391 pretty_printer pretty_name;
392 unsigned char deref_depth = 0;
393 unsigned short tkind, tinfo;
395 /* Get the name of the type, or the name of the pointer type. */
396 if (pstyle == UBSAN_PRINT_POINTER)
398 gcc_assert (POINTER_TYPE_P (type));
399 type2 = TREE_TYPE (type);
401 /* Remove any '*' operators from TYPE. */
402 while (POINTER_TYPE_P (type2))
403 deref_depth++, type2 = TREE_TYPE (type2);
405 if (TREE_CODE (type2) == METHOD_TYPE)
406 type2 = TYPE_METHOD_BASETYPE (type2);
409 /* If an array, get its type. */
410 type2 = strip_array_types (type2);
412 if (pstyle == UBSAN_PRINT_ARRAY)
414 while (POINTER_TYPE_P (type2))
415 deref_depth++, type2 = TREE_TYPE (type2);
418 if (TYPE_NAME (type2) != NULL)
420 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
421 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
422 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
423 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
427 /* We weren't able to determine the type name. */
430 if (pstyle == UBSAN_PRINT_POINTER)
432 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
433 TYPE_VOLATILE (type2) ? "volatile " : "",
434 TYPE_READONLY (type2) ? "const " : "",
435 TYPE_RESTRICT (type2) ? "restrict " : "",
436 TYPE_ATOMIC (type2) ? "_Atomic " : "",
437 TREE_CODE (type2) == RECORD_TYPE
439 : TREE_CODE (type2) == UNION_TYPE
440 ? "union " : "", tname,
441 deref_depth == 0 ? "" : " ");
442 while (deref_depth-- > 0)
443 pp_star (&pretty_name);
444 pp_quote (&pretty_name);
446 else if (pstyle == UBSAN_PRINT_ARRAY)
448 /* Pretty print the array dimensions. */
449 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
451 pp_printf (&pretty_name, "'%s ", tname);
452 while (deref_depth-- > 0)
453 pp_star (&pretty_name);
454 while (TREE_CODE (t) == ARRAY_TYPE)
456 pp_left_bracket (&pretty_name);
457 tree dom = TYPE_DOMAIN (t);
458 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
460 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
461 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
462 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
463 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
465 pp_wide_int (&pretty_name,
466 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
467 TYPE_SIGN (TREE_TYPE (dom)));
470 /* ??? We can't determine the variable name; print VLA unspec. */
471 pp_star (&pretty_name);
472 pp_right_bracket (&pretty_name);
475 pp_quote (&pretty_name);
477 /* Save the tree with stripped types. */
481 pp_printf (&pretty_name, "'%s'", tname);
483 switch (TREE_CODE (type))
491 /* FIXME: libubsan right now only supports float, double and
492 long double type formats. */
493 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
494 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
495 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
504 tinfo = get_ubsan_type_info_for_type (type);
506 /* Create a new VAR_DECL of type descriptor. */
507 const char *tmp = pp_formatted_text (&pretty_name);
508 size_t len = strlen (tmp) + 1;
509 tree str = build_string (len, tmp);
510 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
511 TREE_READONLY (str) = 1;
512 TREE_STATIC (str) = 1;
515 static unsigned int type_var_id_num;
516 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
517 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
519 TREE_STATIC (decl) = 1;
520 TREE_PUBLIC (decl) = 0;
521 DECL_ARTIFICIAL (decl) = 1;
522 DECL_IGNORED_P (decl) = 1;
523 DECL_EXTERNAL (decl) = 0;
525 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
526 DECL_SIZE_UNIT (decl)
527 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
528 TYPE_SIZE_UNIT (TREE_TYPE (str)));
530 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
531 build_int_cst (short_unsigned_type_node,
533 build_int_cst (short_unsigned_type_node,
534 tinfo), NULL_TREE, str);
535 TREE_CONSTANT (ctor) = 1;
536 TREE_STATIC (ctor) = 1;
537 DECL_INITIAL (decl) = ctor;
538 varpool_node::finalize_decl (decl);
540 /* Save the VAR_DECL into the hash table. */
541 decl_for_type_insert (type, decl);
543 return build_fold_addr_expr (decl);
546 /* Create a structure for the ubsan library. NAME is a name of the new
547 structure. LOCCNT is number of locations, PLOC points to array of
548 locations. The arguments in ... are of __ubsan_type_descriptor type
549 and there are at most two of them, followed by NULL_TREE, followed
550 by optional extra arguments and another NULL_TREE. */
553 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
558 vec<tree, va_gc> *saved_args = NULL;
562 /* Firstly, create a pointer to type descriptor type. */
563 tree td_type = ubsan_get_type_descriptor_type ();
564 td_type = build_pointer_type (td_type);
566 /* Create the structure type. */
567 ret = make_node (RECORD_TYPE);
568 for (j = 0; j < loccnt; j++)
570 gcc_checking_assert (i < 2);
571 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
572 ubsan_get_source_location_type ());
573 DECL_CONTEXT (fields[i]) = ret;
575 DECL_CHAIN (fields[i - 1]) = fields[i];
579 va_start (args, ploc);
580 for (t = va_arg (args, tree); t != NULL_TREE;
581 i++, t = va_arg (args, tree))
583 gcc_checking_assert (i < 4);
584 /* Save the tree arguments for later use. */
585 vec_safe_push (saved_args, t);
586 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
588 DECL_CONTEXT (fields[i]) = ret;
590 DECL_CHAIN (fields[i - 1]) = fields[i];
593 for (t = va_arg (args, tree); t != NULL_TREE;
594 i++, t = va_arg (args, tree))
596 gcc_checking_assert (i < 6);
597 /* Save the tree arguments for later use. */
598 vec_safe_push (saved_args, t);
599 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
601 DECL_CONTEXT (fields[i]) = ret;
603 DECL_CHAIN (fields[i - 1]) = fields[i];
607 tree type_decl = build_decl (input_location, TYPE_DECL,
608 get_identifier (name), ret);
609 DECL_IGNORED_P (type_decl) = 1;
610 DECL_ARTIFICIAL (type_decl) = 1;
611 TYPE_FIELDS (ret) = fields[0];
612 TYPE_NAME (ret) = type_decl;
613 TYPE_STUB_DECL (ret) = type_decl;
616 /* Now, fill in the type. */
618 static unsigned int ubsan_var_id_num;
619 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
620 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
622 TREE_STATIC (var) = 1;
623 TREE_PUBLIC (var) = 0;
624 DECL_ARTIFICIAL (var) = 1;
625 DECL_IGNORED_P (var) = 1;
626 DECL_EXTERNAL (var) = 0;
628 vec<constructor_elt, va_gc> *v;
630 tree ctor = build_constructor (ret, v);
632 /* If desirable, set the __ubsan_source_location element. */
633 for (j = 0; j < loccnt; j++)
635 location_t loc = LOCATION_LOCUS (ploc[j]);
636 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
639 size_t nelts = vec_safe_length (saved_args);
640 for (i = 0; i < nelts; i++)
642 t = (*saved_args)[i];
643 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
646 TREE_CONSTANT (ctor) = 1;
647 TREE_STATIC (ctor) = 1;
648 DECL_INITIAL (var) = ctor;
649 varpool_node::finalize_decl (var);
654 /* Instrument the __builtin_unreachable call. We just call the libubsan
658 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
661 location_t loc = gimple_location (gsi_stmt (*gsi));
663 if (flag_sanitize_undefined_trap_on_error)
664 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
667 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
668 NULL_TREE, NULL_TREE);
669 data = build_fold_addr_expr_loc (loc, data);
671 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
672 g = gimple_build_call (fn, 1, data);
674 gimple_set_location (g, loc);
675 gsi_replace (gsi, g, false);
679 /* Return true if T is a call to a libubsan routine. */
682 is_ubsan_builtin_p (tree t)
684 return TREE_CODE (t) == FUNCTION_DECL
685 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
686 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
687 "__builtin___ubsan_", 18) == 0;
690 /* Create a callgraph edge for statement STMT. */
693 ubsan_create_edge (gimple stmt)
695 gcall *call_stmt = dyn_cast <gcall *> (stmt);
696 basic_block bb = gimple_bb (stmt);
697 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
698 cgraph_node *node = cgraph_node::get (current_function_decl);
699 tree decl = gimple_call_fndecl (call_stmt);
701 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
705 /* Expand the UBSAN_BOUNDS special builtin function. */
708 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
710 gimple stmt = gsi_stmt (*gsi);
711 location_t loc = gimple_location (stmt);
712 gcc_assert (gimple_call_num_args (stmt) == 3);
714 /* Pick up the arguments of the UBSAN_BOUNDS call. */
715 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
716 tree index = gimple_call_arg (stmt, 1);
717 tree orig_index_type = TREE_TYPE (index);
718 tree bound = gimple_call_arg (stmt, 2);
720 gimple_stmt_iterator gsi_orig = *gsi;
722 /* Create condition "if (index > bound)". */
723 basic_block then_bb, fallthru_bb;
724 gimple_stmt_iterator cond_insert_point
725 = create_cond_insert_point (gsi, false, false, true,
726 &then_bb, &fallthru_bb);
727 index = fold_convert (TREE_TYPE (bound), index);
728 index = force_gimple_operand_gsi (&cond_insert_point, index,
730 false, GSI_NEW_STMT);
731 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
732 gimple_set_location (g, loc);
733 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
735 /* Generate __ubsan_handle_out_of_bounds call. */
736 *gsi = gsi_after_labels (then_bb);
737 if (flag_sanitize_undefined_trap_on_error)
738 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
742 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
743 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
744 ubsan_type_descriptor (orig_index_type),
745 NULL_TREE, NULL_TREE);
746 data = build_fold_addr_expr_loc (loc, data);
747 enum built_in_function bcode
748 = (flag_sanitize_recover & SANITIZE_BOUNDS)
749 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
750 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
751 tree fn = builtin_decl_explicit (bcode);
752 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
753 true, NULL_TREE, true,
755 g = gimple_build_call (fn, 2, data, val);
757 gimple_set_location (g, loc);
758 gsi_insert_before (gsi, g, GSI_SAME_STMT);
760 /* Get rid of the UBSAN_BOUNDS call from the IR. */
761 unlink_stmt_vdef (stmt);
762 gsi_remove (&gsi_orig, true);
764 /* Point GSI to next logical statement. */
765 *gsi = gsi_start_bb (fallthru_bb);
769 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
770 argument which is a constant, because the middle-end treats pointer
771 conversions as useless and therefore the type of the first argument
772 could be changed to any other pointer type. */
775 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
777 gimple_stmt_iterator gsi = *gsip;
778 gimple stmt = gsi_stmt (gsi);
779 location_t loc = gimple_location (stmt);
780 gcc_assert (gimple_call_num_args (stmt) == 3);
781 tree ptr = gimple_call_arg (stmt, 0);
782 tree ckind = gimple_call_arg (stmt, 1);
783 tree align = gimple_call_arg (stmt, 2);
784 tree check_align = NULL_TREE;
787 basic_block cur_bb = gsi_bb (gsi);
790 if (!integer_zerop (align))
792 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
793 if (compare_tree_int (align, ptralign) == 1)
795 check_align = make_ssa_name (pointer_sized_int_node);
796 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
797 gimple_set_location (g, loc);
798 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
801 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
803 if (check_align == NULL_TREE && !check_null)
805 gsi_remove (gsip, true);
806 /* Unlink the UBSAN_NULLs vops before replacing it. */
807 unlink_stmt_vdef (stmt);
811 /* Split the original block holding the pointer dereference. */
812 edge e = split_block (cur_bb, stmt);
814 /* Get a hold on the 'condition block', the 'then block' and the
816 basic_block cond_bb = e->src;
817 basic_block fallthru_bb = e->dest;
818 basic_block then_bb = create_empty_bb (cond_bb);
819 add_bb_to_loop (then_bb, cond_bb->loop_father);
820 loops_state_set (LOOPS_NEED_FIXUP);
822 /* Make an edge coming from the 'cond block' into the 'then block';
823 this edge is unlikely taken, so set up the probability accordingly. */
824 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
825 e->probability = PROB_VERY_UNLIKELY;
827 /* Connect 'then block' with the 'else block'. This is needed
828 as the ubsan routines we call in the 'then block' are not noreturn.
829 The 'then block' only has one outcoming edge. */
830 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
832 /* Set up the fallthrough basic block. */
833 e = find_edge (cond_bb, fallthru_bb);
834 e->flags = EDGE_FALSE_VALUE;
835 e->count = cond_bb->count;
836 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
838 /* Update dominance info for the newly created then_bb; note that
839 fallthru_bb's dominance info has already been updated by
841 if (dom_info_available_p (CDI_DOMINATORS))
842 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
844 /* Put the ubsan builtin call into the newly created BB. */
845 if (flag_sanitize_undefined_trap_on_error)
846 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
849 enum built_in_function bcode
850 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
851 | (check_null ? SANITIZE_NULL : 0)))
852 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
853 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
854 tree fn = builtin_decl_implicit (bcode);
856 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
857 ubsan_type_descriptor (TREE_TYPE (ckind),
858 UBSAN_PRINT_POINTER),
861 fold_convert (unsigned_char_type_node, ckind),
863 data = build_fold_addr_expr_loc (loc, data);
864 g = gimple_build_call (fn, 2, data,
865 check_align ? check_align
866 : build_zero_cst (pointer_sized_int_node));
868 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
869 gimple_set_location (g, loc);
870 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
872 /* Unlink the UBSAN_NULLs vops before replacing it. */
873 unlink_stmt_vdef (stmt);
877 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
878 NULL_TREE, NULL_TREE);
879 gimple_set_location (g, loc);
881 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
882 gsi_replace (&gsi, g, false);
890 /* Split the block with the condition again. */
891 e = split_block (cond_bb, stmt);
892 basic_block cond1_bb = e->src;
893 basic_block cond2_bb = e->dest;
895 /* Make an edge coming from the 'cond1 block' into the 'then block';
896 this edge is unlikely taken, so set up the probability
898 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
899 e->probability = PROB_VERY_UNLIKELY;
901 /* Set up the fallthrough basic block. */
902 e = find_edge (cond1_bb, cond2_bb);
903 e->flags = EDGE_FALSE_VALUE;
904 e->count = cond1_bb->count;
905 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
907 /* Update dominance info. */
908 if (dom_info_available_p (CDI_DOMINATORS))
910 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
911 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
914 gsi2 = gsi_start_bb (cond2_bb);
917 tree mask = build_int_cst (pointer_sized_int_node,
918 tree_to_uhwi (align) - 1);
919 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
920 BIT_AND_EXPR, check_align, mask);
921 gimple_set_location (g, loc);
923 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
925 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
927 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
928 build_int_cst (pointer_sized_int_node, 0),
929 NULL_TREE, NULL_TREE);
930 gimple_set_location (g, loc);
932 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
934 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
935 gsi_replace (&gsi, g, false);
940 #define OBJSZ_MAX_OFFSET (1024 * 16)
942 /* Expand UBSAN_OBJECT_SIZE internal call. */
945 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
947 gimple stmt = gsi_stmt (*gsi);
948 location_t loc = gimple_location (stmt);
949 gcc_assert (gimple_call_num_args (stmt) == 4);
951 tree ptr = gimple_call_arg (stmt, 0);
952 tree offset = gimple_call_arg (stmt, 1);
953 tree size = gimple_call_arg (stmt, 2);
954 tree ckind = gimple_call_arg (stmt, 3);
955 gimple_stmt_iterator gsi_orig = *gsi;
958 /* See if we can discard the check. */
959 if (TREE_CODE (size) != INTEGER_CST
960 || integer_all_onesp (size))
961 /* Yes, __builtin_object_size couldn't determine the
963 else if (TREE_CODE (offset) == INTEGER_CST
964 && wi::ges_p (wi::to_widest (offset), -OBJSZ_MAX_OFFSET)
965 && wi::les_p (wi::to_widest (offset), -1))
966 /* The offset is in range [-16K, -1]. */;
969 /* if (offset > objsize) */
970 basic_block then_bb, fallthru_bb;
971 gimple_stmt_iterator cond_insert_point
972 = create_cond_insert_point (gsi, false, false, true,
973 &then_bb, &fallthru_bb);
974 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
975 gimple_set_location (g, loc);
976 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
978 /* If the offset is small enough, we don't need the second
980 if (TREE_CODE (offset) == INTEGER_CST
981 && wi::ges_p (wi::to_widest (offset), 0)
982 && wi::les_p (wi::to_widest (offset), OBJSZ_MAX_OFFSET))
983 *gsi = gsi_after_labels (then_bb);
986 /* Don't issue run-time error if (ptr > ptr + offset). That
987 may happen when computing a POINTER_PLUS_EXPR. */
988 basic_block then2_bb, fallthru2_bb;
990 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
991 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
994 /* Convert the pointer to an integer type. */
995 tree p = make_ssa_name (pointer_sized_int_node);
996 g = gimple_build_assign (p, NOP_EXPR, ptr);
997 gimple_set_location (g, loc);
998 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
999 p = gimple_assign_lhs (g);
1000 /* Compute ptr + offset. */
1001 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1002 PLUS_EXPR, p, offset);
1003 gimple_set_location (g, loc);
1004 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1005 /* Now build the conditional and put it into the IR. */
1006 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
1007 NULL_TREE, NULL_TREE);
1008 gimple_set_location (g, loc);
1009 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1010 *gsi = gsi_after_labels (then2_bb);
1013 /* Generate __ubsan_handle_type_mismatch call. */
1014 if (flag_sanitize_undefined_trap_on_error)
1015 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1019 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
1020 ubsan_type_descriptor (TREE_TYPE (ptr),
1021 UBSAN_PRINT_POINTER),
1023 build_zero_cst (pointer_sized_int_node),
1026 data = build_fold_addr_expr_loc (loc, data);
1027 enum built_in_function bcode
1028 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1029 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1030 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
1031 tree p = make_ssa_name (pointer_sized_int_node);
1032 g = gimple_build_assign (p, NOP_EXPR, ptr);
1033 gimple_set_location (g, loc);
1034 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1035 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1037 gimple_set_location (g, loc);
1038 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1040 /* Point GSI to next logical statement. */
1041 *gsi = gsi_start_bb (fallthru_bb);
1043 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1044 unlink_stmt_vdef (stmt);
1045 gsi_remove (&gsi_orig, true);
1049 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1050 unlink_stmt_vdef (stmt);
1051 gsi_remove (gsi, true);
1055 /* Cached __ubsan_vptr_type_cache decl. */
1056 static GTY(()) tree ubsan_vptr_type_cache_decl;
1058 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1059 argument which is a constant, because the middle-end treats pointer
1060 conversions as useless and therefore the type of the first argument
1061 could be changed to any other pointer type. */
1064 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1066 gimple_stmt_iterator gsi = *gsip;
1067 gimple stmt = gsi_stmt (gsi);
1068 location_t loc = gimple_location (stmt);
1069 gcc_assert (gimple_call_num_args (stmt) == 5);
1070 tree op = gimple_call_arg (stmt, 0);
1071 tree vptr = gimple_call_arg (stmt, 1);
1072 tree str_hash = gimple_call_arg (stmt, 2);
1073 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1074 tree ckind_tree = gimple_call_arg (stmt, 4);
1075 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1076 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1078 basic_block fallthru_bb = NULL;
1080 if (ckind == UBSAN_DOWNCAST_POINTER)
1082 /* Guard everything with if (op != NULL) { ... }. */
1083 basic_block then_bb;
1084 gimple_stmt_iterator cond_insert_point
1085 = create_cond_insert_point (gsip, false, false, true,
1086 &then_bb, &fallthru_bb);
1087 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1088 NULL_TREE, NULL_TREE);
1089 gimple_set_location (g, loc);
1090 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1091 *gsip = gsi_after_labels (then_bb);
1092 gsi_remove (&gsi, false);
1093 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1097 tree htype = TREE_TYPE (str_hash);
1098 tree cst = wide_int_to_tree (htype,
1099 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1101 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1103 gimple_set_location (g, loc);
1104 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1105 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1106 gimple_assign_lhs (g), cst);
1107 gimple_set_location (g, loc);
1108 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1109 tree t1 = gimple_assign_lhs (g);
1110 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1111 t1, build_int_cst (integer_type_node, 47));
1112 gimple_set_location (g, loc);
1113 tree t2 = gimple_assign_lhs (g);
1114 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1115 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1117 gimple_set_location (g, loc);
1118 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1119 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1120 t2, gimple_assign_lhs (g));
1121 gimple_set_location (g, loc);
1122 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1123 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1124 gimple_assign_lhs (g), cst);
1125 gimple_set_location (g, loc);
1126 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1127 tree t3 = gimple_assign_lhs (g);
1128 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1129 t3, build_int_cst (integer_type_node, 47));
1130 gimple_set_location (g, loc);
1131 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1132 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1133 t3, gimple_assign_lhs (g));
1134 gimple_set_location (g, loc);
1135 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1136 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1137 gimple_assign_lhs (g), cst);
1138 gimple_set_location (g, loc);
1139 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1140 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1142 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1143 NOP_EXPR, gimple_assign_lhs (g));
1144 gimple_set_location (g, loc);
1145 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1147 tree hash = gimple_assign_lhs (g);
1149 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1151 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1152 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1153 get_identifier ("__ubsan_vptr_type_cache"),
1155 DECL_ARTIFICIAL (array) = 1;
1156 DECL_IGNORED_P (array) = 1;
1157 TREE_PUBLIC (array) = 1;
1158 TREE_STATIC (array) = 1;
1159 DECL_EXTERNAL (array) = 1;
1160 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1161 DECL_VISIBILITY_SPECIFIED (array) = 1;
1162 varpool_node::finalize_decl (array);
1163 ubsan_vptr_type_cache_decl = array;
1166 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1168 build_int_cst (pointer_sized_int_node, 127));
1169 gimple_set_location (g, loc);
1170 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1172 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1173 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1174 NULL_TREE, NULL_TREE);
1175 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1177 gimple_set_location (g, loc);
1178 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1180 basic_block then_bb, fallthru2_bb;
1181 gimple_stmt_iterator cond_insert_point
1182 = create_cond_insert_point (gsip, false, false, true,
1183 &then_bb, &fallthru2_bb);
1184 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1185 NULL_TREE, NULL_TREE);
1186 gimple_set_location (g, loc);
1187 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1188 *gsip = gsi_after_labels (then_bb);
1189 if (fallthru_bb == NULL)
1190 fallthru_bb = fallthru2_bb;
1193 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1194 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1195 build_int_cst (unsigned_char_type_node, ckind),
1197 data = build_fold_addr_expr_loc (loc, data);
1198 enum built_in_function bcode
1199 = (flag_sanitize_recover & SANITIZE_VPTR)
1200 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1201 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1203 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1204 gimple_set_location (g, loc);
1205 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1207 /* Point GSI to next logical statement. */
1208 *gsip = gsi_start_bb (fallthru_bb);
1210 /* Get rid of the UBSAN_VPTR call from the IR. */
1211 unlink_stmt_vdef (stmt);
1212 gsi_remove (&gsi, true);
1216 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1217 whether the pointer is on the left hand side of the assignment. */
1220 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1223 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1224 unsigned int align = 0;
1225 if (flag_sanitize & SANITIZE_ALIGNMENT)
1227 align = min_align_of_type (TREE_TYPE (base));
1231 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1233 tree t = TREE_OPERAND (base, 0);
1234 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1236 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1237 ikind = UBSAN_MEMBER_ACCESS;
1238 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1239 tree alignt = build_int_cst (pointer_sized_int_node, align);
1240 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1241 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1242 gsi_insert_before (iter, g, GSI_SAME_STMT);
1245 /* Perform the pointer instrumentation. */
1248 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1250 gimple stmt = gsi_stmt (gsi);
1251 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1252 tree base = get_base_address (t);
1253 const enum tree_code code = TREE_CODE (base);
1255 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1256 instrument_mem_ref (t, base, &gsi, is_lhs);
1259 /* Build an ubsan builtin call for the signed-integer-overflow
1260 sanitization. CODE says what kind of builtin are we building,
1261 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1262 are operands of the binary operation. */
1265 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1268 if (flag_sanitize_undefined_trap_on_error)
1269 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1271 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1272 ubsan_type_descriptor (lhstype), NULL_TREE,
1274 enum built_in_function fn_code;
1279 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1280 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1281 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1284 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1285 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1286 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1289 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1290 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1291 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1294 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1295 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1296 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1301 tree fn = builtin_decl_explicit (fn_code);
1302 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1303 build_fold_addr_expr_loc (loc, data),
1304 ubsan_encode_value (op0, true),
1305 op1 ? ubsan_encode_value (op1, true)
1309 /* Perform the signed integer instrumentation. GSI is the iterator
1310 pointing at statement we are trying to instrument. */
1313 instrument_si_overflow (gimple_stmt_iterator gsi)
1315 gimple stmt = gsi_stmt (gsi);
1316 tree_code code = gimple_assign_rhs_code (stmt);
1317 tree lhs = gimple_assign_lhs (stmt);
1318 tree lhstype = TREE_TYPE (lhs);
1322 /* If this is not a signed operation, don't instrument anything here.
1323 Also punt on bit-fields. */
1324 if (!INTEGRAL_TYPE_P (lhstype)
1325 || TYPE_OVERFLOW_WRAPS (lhstype)
1326 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1337 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1338 a = gimple_assign_rhs1 (stmt);
1339 b = gimple_assign_rhs2 (stmt);
1340 g = gimple_build_call_internal (code == PLUS_EXPR
1341 ? IFN_UBSAN_CHECK_ADD
1342 : code == MINUS_EXPR
1343 ? IFN_UBSAN_CHECK_SUB
1344 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1345 gimple_call_set_lhs (g, lhs);
1346 gsi_replace (&gsi, g, false);
1349 /* Represent i = -u;
1351 i = UBSAN_CHECK_SUB (0, u); */
1352 a = build_int_cst (lhstype, 0);
1353 b = gimple_assign_rhs1 (stmt);
1354 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1355 gimple_call_set_lhs (g, lhs);
1356 gsi_replace (&gsi, g, false);
1359 /* Transform i = ABS_EXPR<u>;
1361 _N = UBSAN_CHECK_SUB (0, u);
1362 i = ABS_EXPR<_N>; */
1363 a = build_int_cst (lhstype, 0);
1364 b = gimple_assign_rhs1 (stmt);
1365 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1366 a = make_ssa_name (lhstype);
1367 gimple_call_set_lhs (g, a);
1368 gimple_set_location (g, gimple_location (stmt));
1369 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1370 gimple_assign_set_rhs1 (stmt, a);
1378 /* Instrument loads from (non-bitfield) bool and C++ enum values
1379 to check if the memory value is outside of the range of the valid
1383 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1385 gimple stmt = gsi_stmt (*gsi);
1386 tree rhs = gimple_assign_rhs1 (stmt);
1387 tree type = TREE_TYPE (rhs);
1388 tree minv = NULL_TREE, maxv = NULL_TREE;
1390 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1392 minv = boolean_false_node;
1393 maxv = boolean_true_node;
1395 else if (TREE_CODE (type) == ENUMERAL_TYPE
1396 && (flag_sanitize & SANITIZE_ENUM)
1397 && TREE_TYPE (type) != NULL_TREE
1398 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1399 && (TYPE_PRECISION (TREE_TYPE (type))
1400 < GET_MODE_PRECISION (TYPE_MODE (type))))
1402 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1403 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1408 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1409 HOST_WIDE_INT bitsize, bitpos;
1412 int volatilep = 0, unsignedp = 0;
1413 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1414 &unsignedp, &volatilep, false);
1415 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1417 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1418 || (bitpos % modebitsize) != 0
1419 || bitsize != modebitsize
1420 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1421 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1424 bool ends_bb = stmt_ends_bb_p (stmt);
1425 location_t loc = gimple_location (stmt);
1426 tree lhs = gimple_assign_lhs (stmt);
1427 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1428 tree atype = reference_alias_ptr_type (rhs);
1429 gimple g = gimple_build_assign (make_ssa_name (ptype),
1430 build_fold_addr_expr (rhs));
1431 gimple_set_location (g, loc);
1432 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1433 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1434 build_int_cst (atype, 0));
1435 tree urhs = make_ssa_name (utype);
1438 gimple_assign_set_lhs (stmt, urhs);
1439 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1440 gimple_set_location (g, loc);
1441 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1442 gsi_insert_on_edge_immediate (e, g);
1443 gimple_assign_set_rhs_from_tree (gsi, mem);
1445 *gsi = gsi_for_stmt (g);
1450 g = gimple_build_assign (urhs, mem);
1451 gimple_set_location (g, loc);
1452 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1454 minv = fold_convert (utype, minv);
1455 maxv = fold_convert (utype, maxv);
1456 if (!integer_zerop (minv))
1458 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1459 gimple_set_location (g, loc);
1460 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1463 gimple_stmt_iterator gsi2 = *gsi;
1464 basic_block then_bb, fallthru_bb;
1465 *gsi = create_cond_insert_point (gsi, true, false, true,
1466 &then_bb, &fallthru_bb);
1467 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1468 int_const_binop (MINUS_EXPR, maxv, minv),
1469 NULL_TREE, NULL_TREE);
1470 gimple_set_location (g, loc);
1471 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1475 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1479 gsi2 = gsi_after_labels (then_bb);
1480 if (flag_sanitize_undefined_trap_on_error)
1481 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1484 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1485 ubsan_type_descriptor (type), NULL_TREE,
1487 data = build_fold_addr_expr_loc (loc, data);
1488 enum built_in_function bcode
1489 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1490 ? SANITIZE_BOOL : SANITIZE_ENUM))
1491 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1492 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1493 tree fn = builtin_decl_explicit (bcode);
1495 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1496 true, NULL_TREE, true,
1498 g = gimple_build_call (fn, 2, data, val);
1500 gimple_set_location (g, loc);
1501 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1502 ubsan_create_edge (g);
1503 *gsi = gsi_for_stmt (stmt);
1506 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1507 destination, EXPR is floating-point expression. ARG is what to pass
1508 the libubsan call as value, often EXPR itself. */
1511 ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
1513 tree expr_type = TREE_TYPE (expr);
1514 tree t, tt, fn, min, max;
1515 machine_mode mode = TYPE_MODE (expr_type);
1516 int prec = TYPE_PRECISION (type);
1517 bool uns_p = TYPE_UNSIGNED (type);
1519 /* Float to integer conversion first truncates toward zero, so
1520 even signed char c = 127.875f; is not problematic.
1521 Therefore, we should complain only if EXPR is unordered or smaller
1522 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1523 TYPE_MAX_VALUE + 1.0. */
1524 if (REAL_MODE_FORMAT (mode)->b == 2)
1526 /* For maximum, TYPE_MAX_VALUE might not be representable
1527 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1528 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1529 either representable or infinity. */
1530 REAL_VALUE_TYPE maxval = dconst1;
1531 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1532 real_convert (&maxval, mode, &maxval);
1533 max = build_real (expr_type, maxval);
1535 /* For unsigned, assume -1.0 is always representable. */
1537 min = build_minus_one_cst (expr_type);
1540 /* TYPE_MIN_VALUE is generally representable (or -inf),
1541 but TYPE_MIN_VALUE - 1.0 might not be. */
1542 REAL_VALUE_TYPE minval = dconstm1, minval2;
1543 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1544 real_convert (&minval, mode, &minval);
1545 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1546 real_convert (&minval2, mode, &minval2);
1547 if (real_compare (EQ_EXPR, &minval, &minval2)
1548 && !real_isinf (&minval))
1550 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1551 rounds to TYPE_MIN_VALUE, we need to subtract
1552 more. As REAL_MODE_FORMAT (mode)->p is the number
1553 of base digits, we want to subtract a number that
1554 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1555 times smaller than minval. */
1557 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1558 SET_REAL_EXP (&minval2,
1559 REAL_EXP (&minval2) + prec - 1
1560 - REAL_MODE_FORMAT (mode)->p + 1);
1561 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1562 real_convert (&minval2, mode, &minval2);
1564 min = build_real (expr_type, minval2);
1567 else if (REAL_MODE_FORMAT (mode)->b == 10)
1569 /* For _Decimal128 up to 34 decimal digits, - sign,
1570 dot, e, exponent. */
1573 int p = REAL_MODE_FORMAT (mode)->p;
1574 REAL_VALUE_TYPE maxval, minval;
1576 /* Use mpfr_snprintf rounding to compute the smallest
1577 representable decimal number greater or equal than
1578 1 << (prec - !uns_p). */
1579 mpfr_init2 (m, prec + 2);
1580 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1581 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1582 decimal_real_from_string (&maxval, buf);
1583 max = build_real (expr_type, maxval);
1585 /* For unsigned, assume -1.0 is always representable. */
1587 min = build_minus_one_cst (expr_type);
1590 /* Use mpfr_snprintf rounding to compute the largest
1591 representable decimal number less or equal than
1592 (-1 << (prec - 1)) - 1. */
1593 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1594 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1595 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1596 decimal_real_from_string (&minval, buf);
1597 min = build_real (expr_type, minval);
1604 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1605 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1606 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1607 if (integer_zerop (t))
1610 if (flag_sanitize_undefined_trap_on_error)
1611 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1614 initialize_sanitizer_builtins ();
1615 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1616 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1617 NULL, ubsan_type_descriptor (expr_type),
1618 ubsan_type_descriptor (type), NULL_TREE,
1620 enum built_in_function bcode
1621 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1622 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1623 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1624 fn = builtin_decl_explicit (bcode);
1625 fn = build_call_expr_loc (loc, fn, 2,
1626 build_fold_addr_expr_loc (loc, data),
1627 ubsan_encode_value (arg, false));
1630 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1633 /* Instrument values passed to function arguments with nonnull attribute. */
1636 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1638 gimple stmt = gsi_stmt (*gsi);
1640 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1641 while for nonnull sanitization it is clear. */
1642 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1643 flag_delete_null_pointer_checks = 1;
1644 loc[0] = gimple_location (stmt);
1645 loc[1] = UNKNOWN_LOCATION;
1646 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1648 tree arg = gimple_call_arg (stmt, i);
1649 if (POINTER_TYPE_P (TREE_TYPE (arg))
1650 && infer_nonnull_range (stmt, arg, false, true))
1653 if (!is_gimple_val (arg))
1655 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1656 gimple_set_location (g, loc[0]);
1657 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1658 arg = gimple_assign_lhs (g);
1661 basic_block then_bb, fallthru_bb;
1662 *gsi = create_cond_insert_point (gsi, true, false, true,
1663 &then_bb, &fallthru_bb);
1664 g = gimple_build_cond (EQ_EXPR, arg,
1665 build_zero_cst (TREE_TYPE (arg)),
1666 NULL_TREE, NULL_TREE);
1667 gimple_set_location (g, loc[0]);
1668 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1670 *gsi = gsi_after_labels (then_bb);
1671 if (flag_sanitize_undefined_trap_on_error)
1672 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1675 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1677 build_int_cst (integer_type_node,
1680 data = build_fold_addr_expr_loc (loc[0], data);
1681 enum built_in_function bcode
1682 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1683 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1684 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1685 tree fn = builtin_decl_explicit (bcode);
1687 g = gimple_build_call (fn, 1, data);
1689 gimple_set_location (g, loc[0]);
1690 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1691 ubsan_create_edge (g);
1693 *gsi = gsi_for_stmt (stmt);
1695 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1698 /* Instrument returns in functions with returns_nonnull attribute. */
1701 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1703 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1705 tree arg = gimple_return_retval (stmt);
1706 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1707 while for nonnull return sanitization it is clear. */
1708 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1709 flag_delete_null_pointer_checks = 1;
1710 loc[0] = gimple_location (stmt);
1711 loc[1] = UNKNOWN_LOCATION;
1713 && POINTER_TYPE_P (TREE_TYPE (arg))
1714 && is_gimple_val (arg)
1715 && infer_nonnull_range (stmt, arg, false, true))
1717 basic_block then_bb, fallthru_bb;
1718 *gsi = create_cond_insert_point (gsi, true, false, true,
1719 &then_bb, &fallthru_bb);
1720 gimple g = gimple_build_cond (EQ_EXPR, arg,
1721 build_zero_cst (TREE_TYPE (arg)),
1722 NULL_TREE, NULL_TREE);
1723 gimple_set_location (g, loc[0]);
1724 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1726 *gsi = gsi_after_labels (then_bb);
1727 if (flag_sanitize_undefined_trap_on_error)
1728 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1731 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1732 2, loc, NULL_TREE, NULL_TREE);
1733 data = build_fold_addr_expr_loc (loc[0], data);
1734 enum built_in_function bcode
1735 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1736 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1737 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1738 tree fn = builtin_decl_explicit (bcode);
1740 g = gimple_build_call (fn, 1, data);
1742 gimple_set_location (g, loc[0]);
1743 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1744 ubsan_create_edge (g);
1745 *gsi = gsi_for_stmt (stmt);
1747 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1750 /* Instrument memory references. Here we check whether the pointer
1751 points to an out-of-bounds location. */
1754 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1756 gimple stmt = gsi_stmt (*gsi);
1757 location_t loc = gimple_location (stmt);
1758 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1760 tree index = NULL_TREE;
1761 HOST_WIDE_INT size_in_bytes;
1763 type = TREE_TYPE (t);
1764 if (VOID_TYPE_P (type))
1767 switch (TREE_CODE (t))
1770 if (TREE_CODE (t) == COMPONENT_REF
1771 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1773 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1774 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1779 index = TREE_OPERAND (t, 1);
1791 size_in_bytes = int_size_in_bytes (type);
1792 if (size_in_bytes <= 0)
1795 HOST_WIDE_INT bitsize, bitpos;
1798 int volatilep = 0, unsignedp = 0;
1799 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1800 &unsignedp, &volatilep, false);
1802 if (bitpos % BITS_PER_UNIT != 0
1803 || bitsize != size_in_bytes * BITS_PER_UNIT)
1806 bool decl_p = DECL_P (inner);
1810 else if (TREE_CODE (inner) == MEM_REF)
1811 base = TREE_OPERAND (inner, 0);
1814 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1816 while (TREE_CODE (base) == SSA_NAME)
1818 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1819 if (gimple_assign_ssa_name_copy_p (def_stmt)
1820 || (gimple_assign_cast_p (def_stmt)
1821 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1822 || (is_gimple_assign (def_stmt)
1823 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1825 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1826 if (TREE_CODE (rhs1) == SSA_NAME
1827 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1836 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1840 tree base_addr = base;
1841 gimple bos_stmt = NULL;
1843 base_addr = build1 (ADDR_EXPR,
1844 build_pointer_type (TREE_TYPE (base)), base);
1845 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1846 if (size != (unsigned HOST_WIDE_INT) -1)
1847 sizet = build_int_cst (sizetype, size);
1850 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1851 loc = input_location;
1852 /* Generate __builtin_object_size call. */
1853 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1854 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1856 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1858 /* If the call above didn't end up being an integer constant, go one
1859 statement back and get the __builtin_object_size stmt. Save it,
1860 we might need it later. */
1861 if (SSA_VAR_P (sizet))
1864 bos_stmt = gsi_stmt (*gsi);
1866 /* Move on to where we were. */
1873 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1875 /* ptr + sizeof (*ptr) - base */
1876 t = fold_build2 (MINUS_EXPR, sizetype,
1877 fold_convert (pointer_sized_int_node, ptr),
1878 fold_convert (pointer_sized_int_node, base_addr));
1879 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1881 /* Perhaps we can omit the check. */
1882 if (TREE_CODE (t) == INTEGER_CST
1883 && TREE_CODE (sizet) == INTEGER_CST
1884 && tree_int_cst_le (t, sizet))
1887 if (index != NULL_TREE
1888 && TREE_CODE (index) == SSA_NAME
1889 && TREE_CODE (sizet) == INTEGER_CST)
1891 gimple def = SSA_NAME_DEF_STMT (index);
1892 if (is_gimple_assign (def)
1893 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1894 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1896 tree cst = gimple_assign_rhs2 (def);
1897 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1898 TYPE_SIZE_UNIT (type));
1899 if (tree_int_cst_sgn (cst) >= 0
1900 && tree_int_cst_lt (cst, sz))
1905 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1906 ubsan_create_edge (bos_stmt);
1908 /* We have to emit the check. */
1909 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1911 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1913 tree ckind = build_int_cst (unsigned_char_type_node,
1914 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1915 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1916 ptr, t, sizet, ckind);
1917 gimple_set_location (g, loc);
1918 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1921 /* True if we want to play UBSan games in the current function. */
1924 do_ubsan_in_current_function ()
1926 return (current_function_decl != NULL_TREE
1927 && !lookup_attribute ("no_sanitize_undefined",
1928 DECL_ATTRIBUTES (current_function_decl)));
1933 const pass_data pass_data_ubsan =
1935 GIMPLE_PASS, /* type */
1937 OPTGROUP_NONE, /* optinfo_flags */
1938 TV_TREE_UBSAN, /* tv_id */
1939 ( PROP_cfg | PROP_ssa ), /* properties_required */
1940 0, /* properties_provided */
1941 0, /* properties_destroyed */
1942 0, /* todo_flags_start */
1943 TODO_update_ssa, /* todo_flags_finish */
1946 class pass_ubsan : public gimple_opt_pass
1949 pass_ubsan (gcc::context *ctxt)
1950 : gimple_opt_pass (pass_data_ubsan, ctxt)
1953 /* opt_pass methods: */
1954 virtual bool gate (function *)
1956 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1957 | SANITIZE_BOOL | SANITIZE_ENUM
1958 | SANITIZE_ALIGNMENT
1959 | SANITIZE_NONNULL_ATTRIBUTE
1960 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1961 | SANITIZE_OBJECT_SIZE)
1962 && do_ubsan_in_current_function ();
1965 virtual unsigned int execute (function *);
1967 }; // class pass_ubsan
1970 pass_ubsan::execute (function *fun)
1973 gimple_stmt_iterator gsi;
1975 initialize_sanitizer_builtins ();
1977 FOR_EACH_BB_FN (bb, fun)
1979 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1981 gimple stmt = gsi_stmt (gsi);
1982 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1988 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1989 && is_gimple_assign (stmt))
1990 instrument_si_overflow (gsi);
1992 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1994 if (gimple_store_p (stmt))
1995 instrument_null (gsi, true);
1996 if (gimple_assign_load_p (stmt))
1997 instrument_null (gsi, false);
2000 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
2001 && gimple_assign_load_p (stmt))
2003 instrument_bool_enum_load (&gsi);
2004 bb = gimple_bb (stmt);
2007 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
2008 && is_gimple_call (stmt)
2009 && !gimple_call_internal_p (stmt))
2011 instrument_nonnull_arg (&gsi);
2012 bb = gimple_bb (stmt);
2015 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2016 && gimple_code (stmt) == GIMPLE_RETURN)
2018 instrument_nonnull_return (&gsi);
2019 bb = gimple_bb (stmt);
2022 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2024 if (gimple_store_p (stmt))
2025 instrument_object_size (&gsi, true);
2026 if (gimple_assign_load_p (stmt))
2027 instrument_object_size (&gsi, false);
2039 make_pass_ubsan (gcc::context *ctxt)
2041 return new pass_ubsan (ctxt);
2044 #include "gt-ubsan.h"