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 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1615 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1616 NULL
, ubsan_type_descriptor (expr_type
),
1617 ubsan_type_descriptor (type
), NULL_TREE
,
1619 enum built_in_function bcode
1620 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1621 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1622 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1623 fn
= builtin_decl_explicit (bcode
);
1624 fn
= build_call_expr_loc (loc
, fn
, 2,
1625 build_fold_addr_expr_loc (loc
, data
),
1626 ubsan_encode_value (arg
, false));
1629 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1632 /* Instrument values passed to function arguments with nonnull attribute. */
1635 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1637 gimple stmt
= gsi_stmt (*gsi
);
1639 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1640 while for nonnull sanitization it is clear. */
1641 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1642 flag_delete_null_pointer_checks
= 1;
1643 loc
[0] = gimple_location (stmt
);
1644 loc
[1] = UNKNOWN_LOCATION
;
1645 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1647 tree arg
= gimple_call_arg (stmt
, i
);
1648 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1649 && infer_nonnull_range (stmt
, arg
, false, true))
1652 if (!is_gimple_val (arg
))
1654 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1655 gimple_set_location (g
, loc
[0]);
1656 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1657 arg
= gimple_assign_lhs (g
);
1660 basic_block then_bb
, fallthru_bb
;
1661 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1662 &then_bb
, &fallthru_bb
);
1663 g
= gimple_build_cond (EQ_EXPR
, arg
,
1664 build_zero_cst (TREE_TYPE (arg
)),
1665 NULL_TREE
, NULL_TREE
);
1666 gimple_set_location (g
, loc
[0]);
1667 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1669 *gsi
= gsi_after_labels (then_bb
);
1670 if (flag_sanitize_undefined_trap_on_error
)
1671 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1674 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1676 build_int_cst (integer_type_node
,
1679 data
= build_fold_addr_expr_loc (loc
[0], data
);
1680 enum built_in_function bcode
1681 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1682 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1683 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1684 tree fn
= builtin_decl_explicit (bcode
);
1686 g
= gimple_build_call (fn
, 1, data
);
1688 gimple_set_location (g
, loc
[0]);
1689 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1690 ubsan_create_edge (g
);
1692 *gsi
= gsi_for_stmt (stmt
);
1694 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1697 /* Instrument returns in functions with returns_nonnull attribute. */
1700 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1702 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
1704 tree arg
= gimple_return_retval (stmt
);
1705 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1706 while for nonnull return sanitization it is clear. */
1707 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1708 flag_delete_null_pointer_checks
= 1;
1709 loc
[0] = gimple_location (stmt
);
1710 loc
[1] = UNKNOWN_LOCATION
;
1712 && POINTER_TYPE_P (TREE_TYPE (arg
))
1713 && is_gimple_val (arg
)
1714 && infer_nonnull_range (stmt
, arg
, false, true))
1716 basic_block then_bb
, fallthru_bb
;
1717 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1718 &then_bb
, &fallthru_bb
);
1719 gimple g
= gimple_build_cond (EQ_EXPR
, arg
,
1720 build_zero_cst (TREE_TYPE (arg
)),
1721 NULL_TREE
, NULL_TREE
);
1722 gimple_set_location (g
, loc
[0]);
1723 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1725 *gsi
= gsi_after_labels (then_bb
);
1726 if (flag_sanitize_undefined_trap_on_error
)
1727 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1730 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
1731 2, loc
, NULL_TREE
, NULL_TREE
);
1732 data
= build_fold_addr_expr_loc (loc
[0], data
);
1733 enum built_in_function bcode
1734 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1735 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1736 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
1737 tree fn
= builtin_decl_explicit (bcode
);
1739 g
= gimple_build_call (fn
, 1, data
);
1741 gimple_set_location (g
, loc
[0]);
1742 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1743 ubsan_create_edge (g
);
1744 *gsi
= gsi_for_stmt (stmt
);
1746 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1749 /* Instrument memory references. Here we check whether the pointer
1750 points to an out-of-bounds location. */
1753 instrument_object_size (gimple_stmt_iterator
*gsi
, bool is_lhs
)
1755 gimple stmt
= gsi_stmt (*gsi
);
1756 location_t loc
= gimple_location (stmt
);
1757 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1759 tree index
= NULL_TREE
;
1760 HOST_WIDE_INT size_in_bytes
;
1762 type
= TREE_TYPE (t
);
1763 if (VOID_TYPE_P (type
))
1766 switch (TREE_CODE (t
))
1769 if (TREE_CODE (t
) == COMPONENT_REF
1770 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
1772 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
1773 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
1778 index
= TREE_OPERAND (t
, 1);
1790 size_in_bytes
= int_size_in_bytes (type
);
1791 if (size_in_bytes
<= 0)
1794 HOST_WIDE_INT bitsize
, bitpos
;
1797 int volatilep
= 0, unsignedp
= 0;
1798 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1799 &unsignedp
, &volatilep
, false);
1801 if (bitpos
% BITS_PER_UNIT
!= 0
1802 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
1805 bool decl_p
= DECL_P (inner
);
1809 else if (TREE_CODE (inner
) == MEM_REF
)
1810 base
= TREE_OPERAND (inner
, 0);
1813 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
1815 while (TREE_CODE (base
) == SSA_NAME
)
1817 gimple def_stmt
= SSA_NAME_DEF_STMT (base
);
1818 if (gimple_assign_ssa_name_copy_p (def_stmt
)
1819 || (gimple_assign_cast_p (def_stmt
)
1820 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
1821 || (is_gimple_assign (def_stmt
)
1822 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
1824 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
1825 if (TREE_CODE (rhs1
) == SSA_NAME
1826 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
1835 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1839 tree base_addr
= base
;
1840 gimple bos_stmt
= NULL
;
1842 base_addr
= build1 (ADDR_EXPR
,
1843 build_pointer_type (TREE_TYPE (base
)), base
);
1844 unsigned HOST_WIDE_INT size
= compute_builtin_object_size (base_addr
, 0);
1845 if (size
!= (unsigned HOST_WIDE_INT
) -1)
1846 sizet
= build_int_cst (sizetype
, size
);
1849 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
1850 loc
= input_location
;
1851 /* Generate __builtin_object_size call. */
1852 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
1853 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
1855 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
1857 /* If the call above didn't end up being an integer constant, go one
1858 statement back and get the __builtin_object_size stmt. Save it,
1859 we might need it later. */
1860 if (SSA_VAR_P (sizet
))
1863 bos_stmt
= gsi_stmt (*gsi
);
1865 /* Move on to where we were. */
1872 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1874 /* ptr + sizeof (*ptr) - base */
1875 t
= fold_build2 (MINUS_EXPR
, sizetype
,
1876 fold_convert (pointer_sized_int_node
, ptr
),
1877 fold_convert (pointer_sized_int_node
, base_addr
));
1878 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
1880 /* Perhaps we can omit the check. */
1881 if (TREE_CODE (t
) == INTEGER_CST
1882 && TREE_CODE (sizet
) == INTEGER_CST
1883 && tree_int_cst_le (t
, sizet
))
1886 if (index
!= NULL_TREE
1887 && TREE_CODE (index
) == SSA_NAME
1888 && TREE_CODE (sizet
) == INTEGER_CST
)
1890 gimple def
= SSA_NAME_DEF_STMT (index
);
1891 if (is_gimple_assign (def
)
1892 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
1893 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
1895 tree cst
= gimple_assign_rhs2 (def
);
1896 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
1897 TYPE_SIZE_UNIT (type
));
1898 if (tree_int_cst_sgn (cst
) >= 0
1899 && tree_int_cst_lt (cst
, sz
))
1904 if (bos_stmt
&& gimple_call_builtin_p (bos_stmt
, BUILT_IN_OBJECT_SIZE
))
1905 ubsan_create_edge (bos_stmt
);
1907 /* We have to emit the check. */
1908 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1910 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
1912 tree ckind
= build_int_cst (unsigned_char_type_node
,
1913 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
1914 gimple g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
1915 ptr
, t
, sizet
, ckind
);
1916 gimple_set_location (g
, loc
);
1917 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1920 /* True if we want to play UBSan games in the current function. */
1923 do_ubsan_in_current_function ()
1925 return (current_function_decl
!= NULL_TREE
1926 && !lookup_attribute ("no_sanitize_undefined",
1927 DECL_ATTRIBUTES (current_function_decl
)));
1932 const pass_data pass_data_ubsan
=
1934 GIMPLE_PASS
, /* type */
1936 OPTGROUP_NONE
, /* optinfo_flags */
1937 TV_TREE_UBSAN
, /* tv_id */
1938 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1939 0, /* properties_provided */
1940 0, /* properties_destroyed */
1941 0, /* todo_flags_start */
1942 TODO_update_ssa
, /* todo_flags_finish */
1945 class pass_ubsan
: public gimple_opt_pass
1948 pass_ubsan (gcc::context
*ctxt
)
1949 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1952 /* opt_pass methods: */
1953 virtual bool gate (function
*)
1955 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1956 | SANITIZE_BOOL
| SANITIZE_ENUM
1957 | SANITIZE_ALIGNMENT
1958 | SANITIZE_NONNULL_ATTRIBUTE
1959 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1960 | SANITIZE_OBJECT_SIZE
)
1961 && do_ubsan_in_current_function ();
1964 virtual unsigned int execute (function
*);
1966 }; // class pass_ubsan
1969 pass_ubsan::execute (function
*fun
)
1972 gimple_stmt_iterator gsi
;
1974 initialize_sanitizer_builtins ();
1976 FOR_EACH_BB_FN (bb
, fun
)
1978 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1980 gimple stmt
= gsi_stmt (gsi
);
1981 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
1987 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
1988 && is_gimple_assign (stmt
))
1989 instrument_si_overflow (gsi
);
1991 if (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1993 if (gimple_store_p (stmt
))
1994 instrument_null (gsi
, true);
1995 if (gimple_assign_load_p (stmt
))
1996 instrument_null (gsi
, false);
1999 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
2000 && gimple_assign_load_p (stmt
))
2002 instrument_bool_enum_load (&gsi
);
2003 bb
= gimple_bb (stmt
);
2006 if ((flag_sanitize
& SANITIZE_NONNULL_ATTRIBUTE
)
2007 && is_gimple_call (stmt
)
2008 && !gimple_call_internal_p (stmt
))
2010 instrument_nonnull_arg (&gsi
);
2011 bb
= gimple_bb (stmt
);
2014 if ((flag_sanitize
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
2015 && gimple_code (stmt
) == GIMPLE_RETURN
)
2017 instrument_nonnull_return (&gsi
);
2018 bb
= gimple_bb (stmt
);
2021 if (flag_sanitize
& SANITIZE_OBJECT_SIZE
)
2023 if (gimple_store_p (stmt
))
2024 instrument_object_size (&gsi
, true);
2025 if (gimple_assign_load_p (stmt
))
2026 instrument_object_size (&gsi
, false);
2038 make_pass_ubsan (gcc::context
*ctxt
)
2040 return new pass_ubsan (ctxt
);
2043 #include "gt-ubsan.h"