1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2016 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"
26 #include "c-family/c-common.h"
29 #include "tree-pass.h"
33 #include "tree-pretty-print.h"
34 #include "stor-layout.h"
36 #include "gimple-iterator.h"
42 #include "gimplify-me.h"
45 #include "tree-object-size.h"
48 /* Map from a tree to a VAR_DECL tree. */
50 struct GTY((for_user)) tree_type_map {
51 struct tree_map_base type;
55 struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
57 static inline hashval_t
58 hash (tree_type_map *t)
60 return TYPE_UID (t->type.from);
64 equal (tree_type_map *a, tree_type_map *b)
66 return a->type.from == b->type.from;
70 keep_cache_entry (tree_type_map *&m)
72 return ggc_marked_p (m->type.from);
77 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
79 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
82 decl_for_type_lookup (tree type)
84 /* If the hash table is not initialized yet, create it now. */
85 if (decl_tree_for_type == NULL)
88 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
89 /* That also means we don't have to bother with the lookup. */
93 struct tree_type_map *h, in;
96 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
97 return h ? h->decl : NULL_TREE;
100 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
103 decl_for_type_insert (tree type, tree decl)
105 struct tree_type_map *h;
107 h = ggc_alloc<tree_type_map> ();
110 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
113 /* Helper routine, which encodes a value in the pointer_sized_int_node.
114 Arguments with precision <= POINTER_SIZE are passed directly,
115 the rest is passed by reference. T is a value we are to encode.
116 PHASE determines when this function is called. */
119 ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase)
121 tree type = TREE_TYPE (t);
122 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
123 if (bitsize <= POINTER_SIZE)
124 switch (TREE_CODE (type))
129 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
132 tree itype = build_nonstandard_integer_type (bitsize, true);
133 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
134 return fold_convert (pointer_sized_int_node, t);
141 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
143 /* The reason for this is that we don't want to pessimize
144 code by making vars unnecessarily addressable. */
146 if (phase != UBSAN_ENCODE_VALUE_GENERIC)
148 var = create_tmp_var (type);
149 mark_addressable (var);
153 var = create_tmp_var_raw (type);
154 TREE_ADDRESSABLE (var) = 1;
155 DECL_CONTEXT (var) = current_function_decl;
157 if (phase == UBSAN_ENCODE_VALUE_RTL)
160 = assign_stack_temp_for_type (TYPE_MODE (type),
161 GET_MODE_SIZE (TYPE_MODE (type)),
163 SET_DECL_RTL (var, mem);
164 expand_assignment (var, t, false);
165 return build_fold_addr_expr (var);
167 if (phase != UBSAN_ENCODE_VALUE_GENERIC)
169 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
170 t = build_fold_addr_expr (var);
171 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
175 var = build4 (TARGET_EXPR, type, var, t, NULL_TREE, NULL_TREE);
176 return build_fold_addr_expr (var);
180 return build_fold_addr_expr (t);
184 /* Cached ubsan_get_type_descriptor_type () return value. */
185 static GTY(()) tree ubsan_type_descriptor_type;
188 struct __ubsan_type_descriptor
190 unsigned short __typekind;
191 unsigned short __typeinfo;
197 ubsan_get_type_descriptor_type (void)
199 static const char *field_names[3]
200 = { "__typekind", "__typeinfo", "__typename" };
203 if (ubsan_type_descriptor_type)
204 return ubsan_type_descriptor_type;
206 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
207 tree flex_arr_type = build_array_type (char_type_node, itype);
209 ret = make_node (RECORD_TYPE);
210 for (int i = 0; i < 3; i++)
212 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
213 get_identifier (field_names[i]),
214 (i == 2) ? flex_arr_type
215 : short_unsigned_type_node);
216 DECL_CONTEXT (fields[i]) = ret;
218 DECL_CHAIN (fields[i - 1]) = fields[i];
220 tree type_decl = build_decl (input_location, TYPE_DECL,
221 get_identifier ("__ubsan_type_descriptor"),
223 DECL_IGNORED_P (type_decl) = 1;
224 DECL_ARTIFICIAL (type_decl) = 1;
225 TYPE_FIELDS (ret) = fields[0];
226 TYPE_NAME (ret) = type_decl;
227 TYPE_STUB_DECL (ret) = type_decl;
229 ubsan_type_descriptor_type = ret;
233 /* Cached ubsan_get_source_location_type () return value. */
234 static GTY(()) tree ubsan_source_location_type;
237 struct __ubsan_source_location
239 const char *__filename;
241 unsigned int __column;
246 ubsan_get_source_location_type (void)
248 static const char *field_names[3]
249 = { "__filename", "__line", "__column" };
251 if (ubsan_source_location_type)
252 return ubsan_source_location_type;
254 tree const_char_type = build_qualified_type (char_type_node,
257 ret = make_node (RECORD_TYPE);
258 for (int i = 0; i < 3; i++)
260 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
261 get_identifier (field_names[i]),
262 (i == 0) ? build_pointer_type (const_char_type)
263 : unsigned_type_node);
264 DECL_CONTEXT (fields[i]) = ret;
266 DECL_CHAIN (fields[i - 1]) = fields[i];
268 tree type_decl = build_decl (input_location, TYPE_DECL,
269 get_identifier ("__ubsan_source_location"),
271 DECL_IGNORED_P (type_decl) = 1;
272 DECL_ARTIFICIAL (type_decl) = 1;
273 TYPE_FIELDS (ret) = fields[0];
274 TYPE_NAME (ret) = type_decl;
275 TYPE_STUB_DECL (ret) = type_decl;
277 ubsan_source_location_type = ret;
281 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
282 type with its fields filled from a location_t LOC. */
285 ubsan_source_location (location_t loc)
287 expanded_location xloc;
288 tree type = ubsan_get_source_location_type ();
290 xloc = expand_location (loc);
292 if (xloc.file == NULL)
294 str = build_int_cst (ptr_type_node, 0);
300 /* Fill in the values from LOC. */
301 size_t len = strlen (xloc.file) + 1;
302 str = build_string (len, xloc.file);
303 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
304 TREE_READONLY (str) = 1;
305 TREE_STATIC (str) = 1;
306 str = build_fold_addr_expr (str);
308 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
309 build_int_cst (unsigned_type_node,
310 xloc.line), NULL_TREE,
311 build_int_cst (unsigned_type_node,
313 TREE_CONSTANT (ctor) = 1;
314 TREE_STATIC (ctor) = 1;
319 /* This routine returns a magic number for TYPE. */
321 static unsigned short
322 get_ubsan_type_info_for_type (tree type)
324 if (TREE_CODE (type) == REAL_TYPE)
325 return tree_to_uhwi (TYPE_SIZE (type));
326 else if (INTEGRAL_TYPE_P (type))
328 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
329 gcc_assert (prec != -1);
330 return (prec << 1) | !TYPE_UNSIGNED (type);
336 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
337 ubsan_ids[1] for Lubsan_data labels. */
338 static GTY(()) unsigned int ubsan_ids[2];
340 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
341 descriptor. It first looks into the hash table; if not found,
342 create the VAR_DECL, put it into the hash table and return the
343 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
344 an enum controlling how we want to print the type. */
347 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
349 /* See through any typedefs. */
350 type = TYPE_MAIN_VARIANT (type);
352 tree decl = decl_for_type_lookup (type);
353 /* It is possible that some of the earlier created DECLs were found
354 unused, in that case they weren't emitted and varpool_node::get
355 returns NULL node on them. But now we really need them. Thus,
357 if (decl != NULL_TREE && varpool_node::get (decl))
358 return build_fold_addr_expr (decl);
360 tree dtype = ubsan_get_type_descriptor_type ();
362 const char *tname = NULL;
363 pretty_printer pretty_name;
364 unsigned char deref_depth = 0;
365 unsigned short tkind, tinfo;
367 /* Get the name of the type, or the name of the pointer type. */
368 if (pstyle == UBSAN_PRINT_POINTER)
370 gcc_assert (POINTER_TYPE_P (type));
371 type2 = TREE_TYPE (type);
373 /* Remove any '*' operators from TYPE. */
374 while (POINTER_TYPE_P (type2))
375 deref_depth++, type2 = TREE_TYPE (type2);
377 if (TREE_CODE (type2) == METHOD_TYPE)
378 type2 = TYPE_METHOD_BASETYPE (type2);
381 /* If an array, get its type. */
382 type2 = strip_array_types (type2);
384 if (pstyle == UBSAN_PRINT_ARRAY)
386 while (POINTER_TYPE_P (type2))
387 deref_depth++, type2 = TREE_TYPE (type2);
390 if (TYPE_NAME (type2) != NULL)
392 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
393 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
394 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
395 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
399 /* We weren't able to determine the type name. */
402 if (pstyle == UBSAN_PRINT_POINTER)
404 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
405 TYPE_VOLATILE (type2) ? "volatile " : "",
406 TYPE_READONLY (type2) ? "const " : "",
407 TYPE_RESTRICT (type2) ? "restrict " : "",
408 TYPE_ATOMIC (type2) ? "_Atomic " : "",
409 TREE_CODE (type2) == RECORD_TYPE
411 : TREE_CODE (type2) == UNION_TYPE
412 ? "union " : "", tname,
413 deref_depth == 0 ? "" : " ");
414 while (deref_depth-- > 0)
415 pp_star (&pretty_name);
416 pp_quote (&pretty_name);
418 else if (pstyle == UBSAN_PRINT_ARRAY)
420 /* Pretty print the array dimensions. */
421 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
423 pp_printf (&pretty_name, "'%s ", tname);
424 while (deref_depth-- > 0)
425 pp_star (&pretty_name);
426 while (TREE_CODE (t) == ARRAY_TYPE)
428 pp_left_bracket (&pretty_name);
429 tree dom = TYPE_DOMAIN (t);
430 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
432 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
433 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
434 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
435 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
437 pp_wide_int (&pretty_name,
438 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
439 TYPE_SIGN (TREE_TYPE (dom)));
442 /* ??? We can't determine the variable name; print VLA unspec. */
443 pp_star (&pretty_name);
444 pp_right_bracket (&pretty_name);
447 pp_quote (&pretty_name);
449 /* Save the tree with stripped types. */
453 pp_printf (&pretty_name, "'%s'", tname);
455 switch (TREE_CODE (type))
463 /* FIXME: libubsan right now only supports float, double and
464 long double type formats. */
465 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
466 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
467 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
476 tinfo = get_ubsan_type_info_for_type (type);
478 /* Create a new VAR_DECL of type descriptor. */
479 const char *tmp = pp_formatted_text (&pretty_name);
480 size_t len = strlen (tmp) + 1;
481 tree str = build_string (len, tmp);
482 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
483 TREE_READONLY (str) = 1;
484 TREE_STATIC (str) = 1;
487 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
488 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
490 TREE_STATIC (decl) = 1;
491 TREE_PUBLIC (decl) = 0;
492 DECL_ARTIFICIAL (decl) = 1;
493 DECL_IGNORED_P (decl) = 1;
494 DECL_EXTERNAL (decl) = 0;
496 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
497 DECL_SIZE_UNIT (decl)
498 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
499 TYPE_SIZE_UNIT (TREE_TYPE (str)));
501 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
502 build_int_cst (short_unsigned_type_node,
504 build_int_cst (short_unsigned_type_node,
505 tinfo), NULL_TREE, str);
506 TREE_CONSTANT (ctor) = 1;
507 TREE_STATIC (ctor) = 1;
508 DECL_INITIAL (decl) = ctor;
509 varpool_node::finalize_decl (decl);
511 /* Save the VAR_DECL into the hash table. */
512 decl_for_type_insert (type, decl);
514 return build_fold_addr_expr (decl);
517 /* Create a structure for the ubsan library. NAME is a name of the new
518 structure. LOCCNT is number of locations, PLOC points to array of
519 locations. The arguments in ... are of __ubsan_type_descriptor type
520 and there are at most two of them, followed by NULL_TREE, followed
521 by optional extra arguments and another NULL_TREE. */
524 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
529 vec<tree, va_gc> *saved_args = NULL;
533 /* Firstly, create a pointer to type descriptor type. */
534 tree td_type = ubsan_get_type_descriptor_type ();
535 td_type = build_pointer_type (td_type);
537 /* Create the structure type. */
538 ret = make_node (RECORD_TYPE);
539 for (j = 0; j < loccnt; j++)
541 gcc_checking_assert (i < 2);
542 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
543 ubsan_get_source_location_type ());
544 DECL_CONTEXT (fields[i]) = ret;
546 DECL_CHAIN (fields[i - 1]) = fields[i];
550 va_start (args, ploc);
551 for (t = va_arg (args, tree); t != NULL_TREE;
552 i++, t = va_arg (args, tree))
554 gcc_checking_assert (i < 4);
555 /* Save the tree arguments for later use. */
556 vec_safe_push (saved_args, t);
557 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
559 DECL_CONTEXT (fields[i]) = ret;
561 DECL_CHAIN (fields[i - 1]) = fields[i];
564 for (t = va_arg (args, tree); t != NULL_TREE;
565 i++, t = va_arg (args, tree))
567 gcc_checking_assert (i < 6);
568 /* Save the tree arguments for later use. */
569 vec_safe_push (saved_args, t);
570 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
572 DECL_CONTEXT (fields[i]) = ret;
574 DECL_CHAIN (fields[i - 1]) = fields[i];
578 tree type_decl = build_decl (input_location, TYPE_DECL,
579 get_identifier (name), ret);
580 DECL_IGNORED_P (type_decl) = 1;
581 DECL_ARTIFICIAL (type_decl) = 1;
582 TYPE_FIELDS (ret) = fields[0];
583 TYPE_NAME (ret) = type_decl;
584 TYPE_STUB_DECL (ret) = type_decl;
587 /* Now, fill in the type. */
589 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
590 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
592 TREE_STATIC (var) = 1;
593 TREE_PUBLIC (var) = 0;
594 DECL_ARTIFICIAL (var) = 1;
595 DECL_IGNORED_P (var) = 1;
596 DECL_EXTERNAL (var) = 0;
598 vec<constructor_elt, va_gc> *v;
600 tree ctor = build_constructor (ret, v);
602 /* If desirable, set the __ubsan_source_location element. */
603 for (j = 0; j < loccnt; j++)
605 location_t loc = LOCATION_LOCUS (ploc[j]);
606 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
609 size_t nelts = vec_safe_length (saved_args);
610 for (i = 0; i < nelts; i++)
612 t = (*saved_args)[i];
613 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
616 TREE_CONSTANT (ctor) = 1;
617 TREE_STATIC (ctor) = 1;
618 DECL_INITIAL (var) = ctor;
619 varpool_node::finalize_decl (var);
624 /* Instrument the __builtin_unreachable call. We just call the libubsan
628 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
631 location_t loc = gimple_location (gsi_stmt (*gsi));
633 if (flag_sanitize_undefined_trap_on_error)
634 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
637 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
638 NULL_TREE, NULL_TREE);
639 data = build_fold_addr_expr_loc (loc, data);
641 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
642 g = gimple_build_call (fn, 1, data);
644 gimple_set_location (g, loc);
645 gsi_replace (gsi, g, false);
649 /* Return true if T is a call to a libubsan routine. */
652 is_ubsan_builtin_p (tree t)
654 return TREE_CODE (t) == FUNCTION_DECL
655 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
656 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
657 "__builtin___ubsan_", 18) == 0;
660 /* Create a callgraph edge for statement STMT. */
663 ubsan_create_edge (gimple *stmt)
665 gcall *call_stmt = dyn_cast <gcall *> (stmt);
666 basic_block bb = gimple_bb (stmt);
667 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
668 cgraph_node *node = cgraph_node::get (current_function_decl);
669 tree decl = gimple_call_fndecl (call_stmt);
671 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
675 /* Expand the UBSAN_BOUNDS special builtin function. */
678 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
680 gimple *stmt = gsi_stmt (*gsi);
681 location_t loc = gimple_location (stmt);
682 gcc_assert (gimple_call_num_args (stmt) == 3);
684 /* Pick up the arguments of the UBSAN_BOUNDS call. */
685 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
686 tree index = gimple_call_arg (stmt, 1);
687 tree orig_index = index;
688 tree bound = gimple_call_arg (stmt, 2);
690 gimple_stmt_iterator gsi_orig = *gsi;
692 /* Create condition "if (index > bound)". */
693 basic_block then_bb, fallthru_bb;
694 gimple_stmt_iterator cond_insert_point
695 = create_cond_insert_point (gsi, false, false, true,
696 &then_bb, &fallthru_bb);
697 index = fold_convert (TREE_TYPE (bound), index);
698 index = force_gimple_operand_gsi (&cond_insert_point, index,
700 false, GSI_NEW_STMT);
701 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
702 gimple_set_location (g, loc);
703 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
705 /* Generate __ubsan_handle_out_of_bounds call. */
706 *gsi = gsi_after_labels (then_bb);
707 if (flag_sanitize_undefined_trap_on_error)
708 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
712 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
713 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
714 ubsan_type_descriptor (TREE_TYPE (orig_index)),
715 NULL_TREE, NULL_TREE);
716 data = build_fold_addr_expr_loc (loc, data);
717 enum built_in_function bcode
718 = (flag_sanitize_recover & SANITIZE_BOUNDS)
719 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
720 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
721 tree fn = builtin_decl_explicit (bcode);
722 tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE);
723 val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true,
725 g = gimple_build_call (fn, 2, data, val);
727 gimple_set_location (g, loc);
728 gsi_insert_before (gsi, g, GSI_SAME_STMT);
730 /* Get rid of the UBSAN_BOUNDS call from the IR. */
731 unlink_stmt_vdef (stmt);
732 gsi_remove (&gsi_orig, true);
734 /* Point GSI to next logical statement. */
735 *gsi = gsi_start_bb (fallthru_bb);
739 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
740 argument which is a constant, because the middle-end treats pointer
741 conversions as useless and therefore the type of the first argument
742 could be changed to any other pointer type. */
745 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
747 gimple_stmt_iterator gsi = *gsip;
748 gimple *stmt = gsi_stmt (gsi);
749 location_t loc = gimple_location (stmt);
750 gcc_assert (gimple_call_num_args (stmt) == 3);
751 tree ptr = gimple_call_arg (stmt, 0);
752 tree ckind = gimple_call_arg (stmt, 1);
753 tree align = gimple_call_arg (stmt, 2);
754 tree check_align = NULL_TREE;
757 basic_block cur_bb = gsi_bb (gsi);
760 if (!integer_zerop (align))
762 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
763 if (compare_tree_int (align, ptralign) == 1)
765 check_align = make_ssa_name (pointer_sized_int_node);
766 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
767 gimple_set_location (g, loc);
768 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
771 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
773 if (check_align == NULL_TREE && !check_null)
775 gsi_remove (gsip, true);
776 /* Unlink the UBSAN_NULLs vops before replacing it. */
777 unlink_stmt_vdef (stmt);
781 /* Split the original block holding the pointer dereference. */
782 edge e = split_block (cur_bb, stmt);
784 /* Get a hold on the 'condition block', the 'then block' and the
786 basic_block cond_bb = e->src;
787 basic_block fallthru_bb = e->dest;
788 basic_block then_bb = create_empty_bb (cond_bb);
789 add_bb_to_loop (then_bb, cond_bb->loop_father);
790 loops_state_set (LOOPS_NEED_FIXUP);
792 /* Make an edge coming from the 'cond block' into the 'then block';
793 this edge is unlikely taken, so set up the probability accordingly. */
794 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
795 e->probability = PROB_VERY_UNLIKELY;
797 /* Connect 'then block' with the 'else block'. This is needed
798 as the ubsan routines we call in the 'then block' are not noreturn.
799 The 'then block' only has one outcoming edge. */
800 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
802 /* Set up the fallthrough basic block. */
803 e = find_edge (cond_bb, fallthru_bb);
804 e->flags = EDGE_FALSE_VALUE;
805 e->count = cond_bb->count;
806 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
808 /* Update dominance info for the newly created then_bb; note that
809 fallthru_bb's dominance info has already been updated by
811 if (dom_info_available_p (CDI_DOMINATORS))
812 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
814 /* Put the ubsan builtin call into the newly created BB. */
815 if (flag_sanitize_undefined_trap_on_error)
816 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
819 enum built_in_function bcode
820 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
821 | (check_null ? SANITIZE_NULL : 0)))
822 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
823 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
824 tree fn = builtin_decl_implicit (bcode);
826 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
827 ubsan_type_descriptor (TREE_TYPE (ckind),
828 UBSAN_PRINT_POINTER),
831 fold_convert (unsigned_char_type_node, ckind),
833 data = build_fold_addr_expr_loc (loc, data);
834 g = gimple_build_call (fn, 2, data,
835 check_align ? check_align
836 : build_zero_cst (pointer_sized_int_node));
838 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
839 gimple_set_location (g, loc);
840 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
842 /* Unlink the UBSAN_NULLs vops before replacing it. */
843 unlink_stmt_vdef (stmt);
847 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
848 NULL_TREE, NULL_TREE);
849 gimple_set_location (g, loc);
851 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
852 gsi_replace (&gsi, g, false);
860 /* Split the block with the condition again. */
861 e = split_block (cond_bb, stmt);
862 basic_block cond1_bb = e->src;
863 basic_block cond2_bb = e->dest;
865 /* Make an edge coming from the 'cond1 block' into the 'then block';
866 this edge is unlikely taken, so set up the probability
868 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
869 e->probability = PROB_VERY_UNLIKELY;
871 /* Set up the fallthrough basic block. */
872 e = find_edge (cond1_bb, cond2_bb);
873 e->flags = EDGE_FALSE_VALUE;
874 e->count = cond1_bb->count;
875 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
877 /* Update dominance info. */
878 if (dom_info_available_p (CDI_DOMINATORS))
880 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
881 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
884 gsi2 = gsi_start_bb (cond2_bb);
887 tree mask = build_int_cst (pointer_sized_int_node,
888 tree_to_uhwi (align) - 1);
889 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
890 BIT_AND_EXPR, check_align, mask);
891 gimple_set_location (g, loc);
893 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
895 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
897 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
898 build_int_cst (pointer_sized_int_node, 0),
899 NULL_TREE, NULL_TREE);
900 gimple_set_location (g, loc);
902 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
904 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
905 gsi_replace (&gsi, g, false);
910 #define OBJSZ_MAX_OFFSET (1024 * 16)
912 /* Expand UBSAN_OBJECT_SIZE internal call. */
915 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
917 gimple *stmt = gsi_stmt (*gsi);
918 location_t loc = gimple_location (stmt);
919 gcc_assert (gimple_call_num_args (stmt) == 4);
921 tree ptr = gimple_call_arg (stmt, 0);
922 tree offset = gimple_call_arg (stmt, 1);
923 tree size = gimple_call_arg (stmt, 2);
924 tree ckind = gimple_call_arg (stmt, 3);
925 gimple_stmt_iterator gsi_orig = *gsi;
928 /* See if we can discard the check. */
929 if (TREE_CODE (size) != INTEGER_CST
930 || integer_all_onesp (size))
931 /* Yes, __builtin_object_size couldn't determine the
933 else if (TREE_CODE (offset) == INTEGER_CST
934 && wi::ges_p (wi::to_widest (offset), -OBJSZ_MAX_OFFSET)
935 && wi::les_p (wi::to_widest (offset), -1))
936 /* The offset is in range [-16K, -1]. */;
939 /* if (offset > objsize) */
940 basic_block then_bb, fallthru_bb;
941 gimple_stmt_iterator cond_insert_point
942 = create_cond_insert_point (gsi, false, false, true,
943 &then_bb, &fallthru_bb);
944 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
945 gimple_set_location (g, loc);
946 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
948 /* If the offset is small enough, we don't need the second
950 if (TREE_CODE (offset) == INTEGER_CST
951 && wi::ges_p (wi::to_widest (offset), 0)
952 && wi::les_p (wi::to_widest (offset), OBJSZ_MAX_OFFSET))
953 *gsi = gsi_after_labels (then_bb);
956 /* Don't issue run-time error if (ptr > ptr + offset). That
957 may happen when computing a POINTER_PLUS_EXPR. */
958 basic_block then2_bb, fallthru2_bb;
960 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
961 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
964 /* Convert the pointer to an integer type. */
965 tree p = make_ssa_name (pointer_sized_int_node);
966 g = gimple_build_assign (p, NOP_EXPR, ptr);
967 gimple_set_location (g, loc);
968 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
969 p = gimple_assign_lhs (g);
970 /* Compute ptr + offset. */
971 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
972 PLUS_EXPR, p, offset);
973 gimple_set_location (g, loc);
974 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
975 /* Now build the conditional and put it into the IR. */
976 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
977 NULL_TREE, NULL_TREE);
978 gimple_set_location (g, loc);
979 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
980 *gsi = gsi_after_labels (then2_bb);
983 /* Generate __ubsan_handle_type_mismatch call. */
984 if (flag_sanitize_undefined_trap_on_error)
985 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
989 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
990 ubsan_type_descriptor (TREE_TYPE (ptr),
991 UBSAN_PRINT_POINTER),
993 build_zero_cst (pointer_sized_int_node),
996 data = build_fold_addr_expr_loc (loc, data);
997 enum built_in_function bcode
998 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
999 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1000 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
1001 tree p = make_ssa_name (pointer_sized_int_node);
1002 g = gimple_build_assign (p, NOP_EXPR, ptr);
1003 gimple_set_location (g, loc);
1004 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1005 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1007 gimple_set_location (g, loc);
1008 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1010 /* Point GSI to next logical statement. */
1011 *gsi = gsi_start_bb (fallthru_bb);
1013 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1014 unlink_stmt_vdef (stmt);
1015 gsi_remove (&gsi_orig, true);
1019 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1020 unlink_stmt_vdef (stmt);
1021 gsi_remove (gsi, true);
1025 /* Cached __ubsan_vptr_type_cache decl. */
1026 static GTY(()) tree ubsan_vptr_type_cache_decl;
1028 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1029 argument which is a constant, because the middle-end treats pointer
1030 conversions as useless and therefore the type of the first argument
1031 could be changed to any other pointer type. */
1034 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1036 gimple_stmt_iterator gsi = *gsip;
1037 gimple *stmt = gsi_stmt (gsi);
1038 location_t loc = gimple_location (stmt);
1039 gcc_assert (gimple_call_num_args (stmt) == 5);
1040 tree op = gimple_call_arg (stmt, 0);
1041 tree vptr = gimple_call_arg (stmt, 1);
1042 tree str_hash = gimple_call_arg (stmt, 2);
1043 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1044 tree ckind_tree = gimple_call_arg (stmt, 4);
1045 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1046 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1048 basic_block fallthru_bb = NULL;
1050 if (ckind == UBSAN_DOWNCAST_POINTER)
1052 /* Guard everything with if (op != NULL) { ... }. */
1053 basic_block then_bb;
1054 gimple_stmt_iterator cond_insert_point
1055 = create_cond_insert_point (gsip, false, false, true,
1056 &then_bb, &fallthru_bb);
1057 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1058 NULL_TREE, NULL_TREE);
1059 gimple_set_location (g, loc);
1060 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1061 *gsip = gsi_after_labels (then_bb);
1062 gsi_remove (&gsi, false);
1063 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1067 tree htype = TREE_TYPE (str_hash);
1068 tree cst = wide_int_to_tree (htype,
1069 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1071 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1073 gimple_set_location (g, loc);
1074 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1075 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1076 gimple_assign_lhs (g), cst);
1077 gimple_set_location (g, loc);
1078 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1079 tree t1 = gimple_assign_lhs (g);
1080 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1081 t1, build_int_cst (integer_type_node, 47));
1082 gimple_set_location (g, loc);
1083 tree t2 = gimple_assign_lhs (g);
1084 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1085 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1087 gimple_set_location (g, loc);
1088 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1089 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1090 t2, gimple_assign_lhs (g));
1091 gimple_set_location (g, loc);
1092 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1093 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1094 gimple_assign_lhs (g), cst);
1095 gimple_set_location (g, loc);
1096 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1097 tree t3 = gimple_assign_lhs (g);
1098 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1099 t3, build_int_cst (integer_type_node, 47));
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 t3, 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 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1112 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1113 NOP_EXPR, gimple_assign_lhs (g));
1114 gimple_set_location (g, loc);
1115 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1117 tree hash = gimple_assign_lhs (g);
1119 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1121 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1122 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1123 get_identifier ("__ubsan_vptr_type_cache"),
1125 DECL_ARTIFICIAL (array) = 1;
1126 DECL_IGNORED_P (array) = 1;
1127 TREE_PUBLIC (array) = 1;
1128 TREE_STATIC (array) = 1;
1129 DECL_EXTERNAL (array) = 1;
1130 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1131 DECL_VISIBILITY_SPECIFIED (array) = 1;
1132 varpool_node::finalize_decl (array);
1133 ubsan_vptr_type_cache_decl = array;
1136 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1138 build_int_cst (pointer_sized_int_node, 127));
1139 gimple_set_location (g, loc);
1140 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1142 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1143 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1144 NULL_TREE, NULL_TREE);
1145 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1147 gimple_set_location (g, loc);
1148 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1150 basic_block then_bb, fallthru2_bb;
1151 gimple_stmt_iterator cond_insert_point
1152 = create_cond_insert_point (gsip, false, false, true,
1153 &then_bb, &fallthru2_bb);
1154 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1155 NULL_TREE, NULL_TREE);
1156 gimple_set_location (g, loc);
1157 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1158 *gsip = gsi_after_labels (then_bb);
1159 if (fallthru_bb == NULL)
1160 fallthru_bb = fallthru2_bb;
1163 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1164 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1165 build_int_cst (unsigned_char_type_node, ckind),
1167 data = build_fold_addr_expr_loc (loc, data);
1168 enum built_in_function bcode
1169 = (flag_sanitize_recover & SANITIZE_VPTR)
1170 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1171 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1173 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1174 gimple_set_location (g, loc);
1175 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1177 /* Point GSI to next logical statement. */
1178 *gsip = gsi_start_bb (fallthru_bb);
1180 /* Get rid of the UBSAN_VPTR call from the IR. */
1181 unlink_stmt_vdef (stmt);
1182 gsi_remove (&gsi, true);
1186 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1187 whether the pointer is on the left hand side of the assignment. */
1190 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1193 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1194 unsigned int align = 0;
1195 if (flag_sanitize & SANITIZE_ALIGNMENT)
1197 align = min_align_of_type (TREE_TYPE (base));
1201 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1203 tree t = TREE_OPERAND (base, 0);
1204 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1206 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1207 ikind = UBSAN_MEMBER_ACCESS;
1208 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1209 tree alignt = build_int_cst (pointer_sized_int_node, align);
1210 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1211 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1212 gsi_insert_before (iter, g, GSI_SAME_STMT);
1215 /* Perform the pointer instrumentation. */
1218 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1220 gimple *stmt = gsi_stmt (gsi);
1221 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1222 tree base = get_base_address (t);
1223 const enum tree_code code = TREE_CODE (base);
1225 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1226 instrument_mem_ref (t, base, &gsi, is_lhs);
1229 /* Build an ubsan builtin call for the signed-integer-overflow
1230 sanitization. CODE says what kind of builtin are we building,
1231 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1232 are operands of the binary operation. */
1235 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1238 if (flag_sanitize_undefined_trap_on_error)
1239 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1241 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1242 ubsan_type_descriptor (lhstype), NULL_TREE,
1244 enum built_in_function fn_code;
1245 bool uns_p = TYPE_UNSIGNED (lhstype);
1246 unsigned sanitize_code = uns_p ? SANITIZE_SI_OVERFLOW | SANITIZE_UI_OVERFLOW
1247 : SANITIZE_SI_OVERFLOW;
1252 fn_code = (flag_sanitize_recover & sanitize_code)
1253 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1254 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1257 fn_code = (flag_sanitize_recover & sanitize_code)
1258 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1259 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1262 fn_code = (flag_sanitize_recover & sanitize_code)
1263 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1264 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1267 fn_code = (flag_sanitize_recover & sanitize_code)
1268 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1269 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1274 tree fn = builtin_decl_explicit (fn_code);
1275 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1276 build_fold_addr_expr_loc (loc, data),
1277 ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL),
1279 ? ubsan_encode_value (op1,
1280 UBSAN_ENCODE_VALUE_RTL)
1284 /* Perform the signed integer instrumentation. GSI is the iterator
1285 pointing at statement we are trying to instrument. */
1288 instrument_si_overflow (gimple_stmt_iterator gsi)
1290 gimple *stmt = gsi_stmt (gsi);
1291 tree_code code = gimple_assign_rhs_code (stmt);
1292 tree lhs = gimple_assign_lhs (stmt);
1293 tree lhstype = TREE_TYPE (lhs);
1297 /* If this is not a signed operation, don't instrument anything here.
1298 Also punt on bit-fields. */
1299 if (!INTEGRAL_TYPE_P (lhstype)
1300 || TYPE_OVERFLOW_WRAPS (lhstype)
1301 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1312 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1313 a = gimple_assign_rhs1 (stmt);
1314 b = gimple_assign_rhs2 (stmt);
1315 g = gimple_build_call_internal (code == PLUS_EXPR
1316 ? IFN_UBSAN_CHECK_ADD
1317 : code == MINUS_EXPR
1318 ? IFN_UBSAN_CHECK_SUB
1319 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1320 gimple_call_set_lhs (g, lhs);
1321 gsi_replace (&gsi, g, true);
1324 /* Represent i = -u;
1326 i = UBSAN_CHECK_SUB (0, u); */
1327 a = build_int_cst (lhstype, 0);
1328 b = gimple_assign_rhs1 (stmt);
1329 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1330 gimple_call_set_lhs (g, lhs);
1331 gsi_replace (&gsi, g, true);
1334 /* Transform i = ABS_EXPR<u>;
1336 _N = UBSAN_CHECK_SUB (0, u);
1337 i = ABS_EXPR<_N>; */
1338 a = build_int_cst (lhstype, 0);
1339 b = gimple_assign_rhs1 (stmt);
1340 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1341 a = make_ssa_name (lhstype);
1342 gimple_call_set_lhs (g, a);
1343 gimple_set_location (g, gimple_location (stmt));
1344 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1345 gimple_assign_set_rhs1 (stmt, a);
1353 /* Instrument loads from (non-bitfield) bool and C++ enum values
1354 to check if the memory value is outside of the range of the valid
1358 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1360 gimple *stmt = gsi_stmt (*gsi);
1361 tree rhs = gimple_assign_rhs1 (stmt);
1362 tree type = TREE_TYPE (rhs);
1363 tree minv = NULL_TREE, maxv = NULL_TREE;
1365 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1367 minv = boolean_false_node;
1368 maxv = boolean_true_node;
1370 else if (TREE_CODE (type) == ENUMERAL_TYPE
1371 && (flag_sanitize & SANITIZE_ENUM)
1372 && TREE_TYPE (type) != NULL_TREE
1373 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1374 && (TYPE_PRECISION (TREE_TYPE (type))
1375 < GET_MODE_PRECISION (TYPE_MODE (type))))
1377 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1378 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1383 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1384 HOST_WIDE_INT bitsize, bitpos;
1387 int volatilep = 0, reversep, unsignedp = 0;
1388 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1389 &unsignedp, &reversep, &volatilep, false);
1390 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1392 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1393 || (bitpos % modebitsize) != 0
1394 || bitsize != modebitsize
1395 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1396 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1399 bool ends_bb = stmt_ends_bb_p (stmt);
1400 location_t loc = gimple_location (stmt);
1401 tree lhs = gimple_assign_lhs (stmt);
1402 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1403 tree atype = reference_alias_ptr_type (rhs);
1404 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1405 build_fold_addr_expr (rhs));
1406 gimple_set_location (g, loc);
1407 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1408 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1409 build_int_cst (atype, 0));
1410 tree urhs = make_ssa_name (utype);
1413 gimple_assign_set_lhs (stmt, urhs);
1414 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1415 gimple_set_location (g, loc);
1416 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1417 gsi_insert_on_edge_immediate (e, g);
1418 gimple_assign_set_rhs_from_tree (gsi, mem);
1420 *gsi = gsi_for_stmt (g);
1425 g = gimple_build_assign (urhs, mem);
1426 gimple_set_location (g, loc);
1427 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1429 minv = fold_convert (utype, minv);
1430 maxv = fold_convert (utype, maxv);
1431 if (!integer_zerop (minv))
1433 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1434 gimple_set_location (g, loc);
1435 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1438 gimple_stmt_iterator gsi2 = *gsi;
1439 basic_block then_bb, fallthru_bb;
1440 *gsi = create_cond_insert_point (gsi, true, false, true,
1441 &then_bb, &fallthru_bb);
1442 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1443 int_const_binop (MINUS_EXPR, maxv, minv),
1444 NULL_TREE, NULL_TREE);
1445 gimple_set_location (g, loc);
1446 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1450 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1454 gsi2 = gsi_after_labels (then_bb);
1455 if (flag_sanitize_undefined_trap_on_error)
1456 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1459 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1460 ubsan_type_descriptor (type), NULL_TREE,
1462 data = build_fold_addr_expr_loc (loc, data);
1463 enum built_in_function bcode
1464 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1465 ? SANITIZE_BOOL : SANITIZE_ENUM))
1466 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1467 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1468 tree fn = builtin_decl_explicit (bcode);
1470 tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE);
1471 val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true,
1473 g = gimple_build_call (fn, 2, data, val);
1475 gimple_set_location (g, loc);
1476 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1477 ubsan_create_edge (g);
1478 *gsi = gsi_for_stmt (stmt);
1481 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1482 new style handlers. Libubsan uses heuristics to destinguish between old and
1483 new styles and relies on these properties for filename:
1485 a) Location's filename must not be NULL.
1486 b) Location's filename must not be equal to "".
1487 c) Location's filename must not be equal to "\1".
1488 d) First two bytes of filename must not contain '\xff' symbol. */
1491 ubsan_use_new_style_p (location_t loc)
1493 if (loc == UNKNOWN_LOCATION)
1496 expanded_location xloc = expand_location (loc);
1497 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1498 || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1499 || xloc.file[1] == '\xff')
1505 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1506 destination, EXPR is floating-point expression. */
1509 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1511 tree expr_type = TREE_TYPE (expr);
1512 tree t, tt, fn, min, max;
1513 machine_mode mode = TYPE_MODE (expr_type);
1514 int prec = TYPE_PRECISION (type);
1515 bool uns_p = TYPE_UNSIGNED (type);
1516 if (loc == UNKNOWN_LOCATION)
1517 loc = input_location;
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 location_t *loc_ptr = NULL;
1615 unsigned num_locations = 0;
1616 initialize_sanitizer_builtins ();
1617 /* Figure out if we can propagate location to ubsan_data and use new
1618 style handlers in libubsan. */
1619 if (ubsan_use_new_style_p (loc))
1624 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1625 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1626 num_locations, loc_ptr,
1627 ubsan_type_descriptor (expr_type),
1628 ubsan_type_descriptor (type), NULL_TREE,
1630 enum built_in_function bcode
1631 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1632 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1633 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1634 fn = builtin_decl_explicit (bcode);
1635 fn = build_call_expr_loc (loc, fn, 2,
1636 build_fold_addr_expr_loc (loc, data),
1637 ubsan_encode_value (expr));
1640 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1643 /* Instrument values passed to function arguments with nonnull attribute. */
1646 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1648 gimple *stmt = gsi_stmt (*gsi);
1650 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1651 while for nonnull sanitization it is clear. */
1652 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1653 flag_delete_null_pointer_checks = 1;
1654 loc[0] = gimple_location (stmt);
1655 loc[1] = UNKNOWN_LOCATION;
1656 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1658 tree arg = gimple_call_arg (stmt, i);
1659 if (POINTER_TYPE_P (TREE_TYPE (arg))
1660 && infer_nonnull_range_by_attribute (stmt, arg))
1663 if (!is_gimple_val (arg))
1665 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1666 gimple_set_location (g, loc[0]);
1667 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1668 arg = gimple_assign_lhs (g);
1671 basic_block then_bb, fallthru_bb;
1672 *gsi = create_cond_insert_point (gsi, true, false, true,
1673 &then_bb, &fallthru_bb);
1674 g = gimple_build_cond (EQ_EXPR, arg,
1675 build_zero_cst (TREE_TYPE (arg)),
1676 NULL_TREE, NULL_TREE);
1677 gimple_set_location (g, loc[0]);
1678 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1680 *gsi = gsi_after_labels (then_bb);
1681 if (flag_sanitize_undefined_trap_on_error)
1682 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1685 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1687 build_int_cst (integer_type_node,
1690 data = build_fold_addr_expr_loc (loc[0], data);
1691 enum built_in_function bcode
1692 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1693 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1694 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1695 tree fn = builtin_decl_explicit (bcode);
1697 g = gimple_build_call (fn, 1, data);
1699 gimple_set_location (g, loc[0]);
1700 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1701 ubsan_create_edge (g);
1703 *gsi = gsi_for_stmt (stmt);
1705 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1708 /* Instrument returns in functions with returns_nonnull attribute. */
1711 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1713 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1715 tree arg = gimple_return_retval (stmt);
1716 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1717 while for nonnull return sanitization it is clear. */
1718 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1719 flag_delete_null_pointer_checks = 1;
1720 loc[0] = gimple_location (stmt);
1721 loc[1] = UNKNOWN_LOCATION;
1723 && POINTER_TYPE_P (TREE_TYPE (arg))
1724 && is_gimple_val (arg)
1725 && infer_nonnull_range_by_attribute (stmt, arg))
1727 basic_block then_bb, fallthru_bb;
1728 *gsi = create_cond_insert_point (gsi, true, false, true,
1729 &then_bb, &fallthru_bb);
1730 gimple *g = gimple_build_cond (EQ_EXPR, arg,
1731 build_zero_cst (TREE_TYPE (arg)),
1732 NULL_TREE, NULL_TREE);
1733 gimple_set_location (g, loc[0]);
1734 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1736 *gsi = gsi_after_labels (then_bb);
1737 if (flag_sanitize_undefined_trap_on_error)
1738 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1741 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1742 2, loc, NULL_TREE, NULL_TREE);
1743 data = build_fold_addr_expr_loc (loc[0], data);
1744 enum built_in_function bcode
1745 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1746 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1747 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1748 tree fn = builtin_decl_explicit (bcode);
1750 g = gimple_build_call (fn, 1, data);
1752 gimple_set_location (g, loc[0]);
1753 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1754 ubsan_create_edge (g);
1755 *gsi = gsi_for_stmt (stmt);
1757 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1760 /* Instrument memory references. Here we check whether the pointer
1761 points to an out-of-bounds location. */
1764 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1766 gimple *stmt = gsi_stmt (*gsi);
1767 location_t loc = gimple_location (stmt);
1768 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1770 tree index = NULL_TREE;
1771 HOST_WIDE_INT size_in_bytes;
1773 type = TREE_TYPE (t);
1774 if (VOID_TYPE_P (type))
1777 switch (TREE_CODE (t))
1780 if (TREE_CODE (t) == COMPONENT_REF
1781 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1783 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1784 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1789 index = TREE_OPERAND (t, 1);
1801 size_in_bytes = int_size_in_bytes (type);
1802 if (size_in_bytes <= 0)
1805 HOST_WIDE_INT bitsize, bitpos;
1808 int volatilep = 0, reversep, unsignedp = 0;
1809 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1810 &unsignedp, &reversep, &volatilep, false);
1812 if (bitpos % BITS_PER_UNIT != 0
1813 || bitsize != size_in_bytes * BITS_PER_UNIT)
1816 bool decl_p = DECL_P (inner);
1820 else if (TREE_CODE (inner) == MEM_REF)
1821 base = TREE_OPERAND (inner, 0);
1824 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1826 while (TREE_CODE (base) == SSA_NAME)
1828 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
1829 if (gimple_assign_ssa_name_copy_p (def_stmt)
1830 || (gimple_assign_cast_p (def_stmt)
1831 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1832 || (is_gimple_assign (def_stmt)
1833 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1835 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1836 if (TREE_CODE (rhs1) == SSA_NAME
1837 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1846 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1850 tree base_addr = base;
1851 gimple *bos_stmt = NULL;
1853 base_addr = build1 (ADDR_EXPR,
1854 build_pointer_type (TREE_TYPE (base)), base);
1855 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1856 if (size != (unsigned HOST_WIDE_INT) -1)
1857 sizet = build_int_cst (sizetype, size);
1860 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1861 loc = input_location;
1862 /* Generate __builtin_object_size call. */
1863 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1864 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1866 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1868 /* If the call above didn't end up being an integer constant, go one
1869 statement back and get the __builtin_object_size stmt. Save it,
1870 we might need it later. */
1871 if (SSA_VAR_P (sizet))
1874 bos_stmt = gsi_stmt (*gsi);
1876 /* Move on to where we were. */
1883 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1885 /* ptr + sizeof (*ptr) - base */
1886 t = fold_build2 (MINUS_EXPR, sizetype,
1887 fold_convert (pointer_sized_int_node, ptr),
1888 fold_convert (pointer_sized_int_node, base_addr));
1889 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1891 /* Perhaps we can omit the check. */
1892 if (TREE_CODE (t) == INTEGER_CST
1893 && TREE_CODE (sizet) == INTEGER_CST
1894 && tree_int_cst_le (t, sizet))
1897 if (index != NULL_TREE
1898 && TREE_CODE (index) == SSA_NAME
1899 && TREE_CODE (sizet) == INTEGER_CST)
1901 gimple *def = SSA_NAME_DEF_STMT (index);
1902 if (is_gimple_assign (def)
1903 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1904 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1906 tree cst = gimple_assign_rhs2 (def);
1907 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1908 TYPE_SIZE_UNIT (type));
1909 if (tree_int_cst_sgn (cst) >= 0
1910 && tree_int_cst_lt (cst, sz))
1915 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1916 ubsan_create_edge (bos_stmt);
1918 /* We have to emit the check. */
1919 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1921 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1923 tree ckind = build_int_cst (unsigned_char_type_node,
1924 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1925 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1926 ptr, t, sizet, ckind);
1927 gimple_set_location (g, loc);
1928 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1931 /* True if we want to play UBSan games in the current function. */
1934 do_ubsan_in_current_function ()
1936 return (current_function_decl != NULL_TREE
1937 && !lookup_attribute ("no_sanitize_undefined",
1938 DECL_ATTRIBUTES (current_function_decl)));
1943 const pass_data pass_data_ubsan =
1945 GIMPLE_PASS, /* type */
1947 OPTGROUP_NONE, /* optinfo_flags */
1948 TV_TREE_UBSAN, /* tv_id */
1949 ( PROP_cfg | PROP_ssa ), /* properties_required */
1950 0, /* properties_provided */
1951 0, /* properties_destroyed */
1952 0, /* todo_flags_start */
1953 TODO_update_ssa, /* todo_flags_finish */
1956 class pass_ubsan : public gimple_opt_pass
1959 pass_ubsan (gcc::context *ctxt)
1960 : gimple_opt_pass (pass_data_ubsan, ctxt)
1963 /* opt_pass methods: */
1964 virtual bool gate (function *)
1966 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1967 | SANITIZE_UI_OVERFLOW
1968 | SANITIZE_BOOL | SANITIZE_ENUM
1969 | SANITIZE_ALIGNMENT
1970 | SANITIZE_NONNULL_ATTRIBUTE
1971 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1972 | SANITIZE_OBJECT_SIZE)
1973 && do_ubsan_in_current_function ();
1976 virtual unsigned int execute (function *);
1978 }; // class pass_ubsan
1981 pass_ubsan::execute (function *fun)
1984 gimple_stmt_iterator gsi;
1985 unsigned int ret = 0;
1987 initialize_sanitizer_builtins ();
1989 FOR_EACH_BB_FN (bb, fun)
1991 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1993 gimple *stmt = gsi_stmt (gsi);
1994 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
2000 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
2001 && is_gimple_assign (stmt))
2002 instrument_si_overflow (gsi);
2004 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
2006 if (gimple_store_p (stmt))
2007 instrument_null (gsi, true);
2008 if (gimple_assign_load_p (stmt))
2009 instrument_null (gsi, false);
2012 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
2013 && gimple_assign_load_p (stmt))
2015 instrument_bool_enum_load (&gsi);
2016 bb = gimple_bb (stmt);
2019 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
2020 && is_gimple_call (stmt)
2021 && !gimple_call_internal_p (stmt))
2023 instrument_nonnull_arg (&gsi);
2024 bb = gimple_bb (stmt);
2027 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2028 && gimple_code (stmt) == GIMPLE_RETURN)
2030 instrument_nonnull_return (&gsi);
2031 bb = gimple_bb (stmt);
2034 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2036 if (gimple_store_p (stmt))
2037 instrument_object_size (&gsi, true);
2038 if (gimple_assign_load_p (stmt))
2039 instrument_object_size (&gsi, false);
2044 if (gimple_purge_dead_eh_edges (bb))
2045 ret = TODO_cleanup_cfg;
2053 make_pass_ubsan (gcc::context *ctxt)
2055 return new pass_ubsan (ctxt);
2058 #include "gt-ubsan.h"