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"
91 /* Map from a tree to a VAR_DECL tree. */
93 struct GTY((for_user
)) tree_type_map
{
94 struct tree_map_base type
;
98 struct tree_type_map_cache_hasher
: ggc_cache_hasher
<tree_type_map
*>
100 static inline hashval_t
101 hash (tree_type_map
*t
)
103 return TYPE_UID (t
->type
.from
);
107 equal (tree_type_map
*a
, tree_type_map
*b
)
109 return a
->type
.from
== b
->type
.from
;
113 handle_cache_entry (tree_type_map
*&m
)
115 extern void gt_ggc_mx (tree_type_map
*&);
116 if (m
== HTAB_EMPTY_ENTRY
|| m
== HTAB_DELETED_ENTRY
)
118 else if (ggc_marked_p (m
->type
.from
))
121 m
= static_cast<tree_type_map
*> (HTAB_DELETED_ENTRY
);
126 hash_table
<tree_type_map_cache_hasher
> *decl_tree_for_type
;
128 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
131 decl_for_type_lookup (tree type
)
133 /* If the hash table is not initialized yet, create it now. */
134 if (decl_tree_for_type
== NULL
)
137 = hash_table
<tree_type_map_cache_hasher
>::create_ggc (10);
138 /* That also means we don't have to bother with the lookup. */
142 struct tree_type_map
*h
, in
;
145 h
= decl_tree_for_type
->find_with_hash (&in
, TYPE_UID (type
));
146 return h
? h
->decl
: NULL_TREE
;
149 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
152 decl_for_type_insert (tree type
, tree decl
)
154 struct tree_type_map
*h
;
156 h
= ggc_alloc
<tree_type_map
> ();
159 *decl_tree_for_type
->find_slot_with_hash (h
, TYPE_UID (type
), INSERT
) = h
;
162 /* Helper routine, which encodes a value in the pointer_sized_int_node.
163 Arguments with precision <= POINTER_SIZE are passed directly,
164 the rest is passed by reference. T is a value we are to encode.
165 IN_EXPAND_P is true if this function is called during expansion. */
168 ubsan_encode_value (tree t
, bool in_expand_p
)
170 tree type
= TREE_TYPE (t
);
171 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
172 if (bitsize
<= POINTER_SIZE
)
173 switch (TREE_CODE (type
))
178 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
181 tree itype
= build_nonstandard_integer_type (bitsize
, true);
182 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
183 return fold_convert (pointer_sized_int_node
, t
);
190 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
192 /* The reason for this is that we don't want to pessimize
193 code by making vars unnecessarily addressable. */
194 tree var
= create_tmp_var (type
);
195 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
199 = assign_stack_temp_for_type (TYPE_MODE (type
),
200 GET_MODE_SIZE (TYPE_MODE (type
)),
202 SET_DECL_RTL (var
, mem
);
203 expand_assignment (var
, t
, false);
204 return build_fold_addr_expr (var
);
206 t
= build_fold_addr_expr (var
);
207 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
210 return build_fold_addr_expr (t
);
214 /* Cached ubsan_get_type_descriptor_type () return value. */
215 static GTY(()) tree ubsan_type_descriptor_type
;
218 struct __ubsan_type_descriptor
220 unsigned short __typekind;
221 unsigned short __typeinfo;
227 ubsan_get_type_descriptor_type (void)
229 static const char *field_names
[3]
230 = { "__typekind", "__typeinfo", "__typename" };
233 if (ubsan_type_descriptor_type
)
234 return ubsan_type_descriptor_type
;
236 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
237 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
239 ret
= make_node (RECORD_TYPE
);
240 for (int i
= 0; i
< 3; i
++)
242 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
243 get_identifier (field_names
[i
]),
244 (i
== 2) ? flex_arr_type
245 : short_unsigned_type_node
);
246 DECL_CONTEXT (fields
[i
]) = ret
;
248 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
250 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
251 get_identifier ("__ubsan_type_descriptor"),
253 DECL_IGNORED_P (type_decl
) = 1;
254 DECL_ARTIFICIAL (type_decl
) = 1;
255 TYPE_FIELDS (ret
) = fields
[0];
256 TYPE_NAME (ret
) = type_decl
;
257 TYPE_STUB_DECL (ret
) = type_decl
;
259 ubsan_type_descriptor_type
= ret
;
263 /* Cached ubsan_get_source_location_type () return value. */
264 static GTY(()) tree ubsan_source_location_type
;
267 struct __ubsan_source_location
269 const char *__filename;
271 unsigned int __column;
276 ubsan_get_source_location_type (void)
278 static const char *field_names
[3]
279 = { "__filename", "__line", "__column" };
281 if (ubsan_source_location_type
)
282 return ubsan_source_location_type
;
284 tree const_char_type
= build_qualified_type (char_type_node
,
287 ret
= make_node (RECORD_TYPE
);
288 for (int i
= 0; i
< 3; i
++)
290 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
291 get_identifier (field_names
[i
]),
292 (i
== 0) ? build_pointer_type (const_char_type
)
293 : unsigned_type_node
);
294 DECL_CONTEXT (fields
[i
]) = ret
;
296 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
298 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
299 get_identifier ("__ubsan_source_location"),
301 DECL_IGNORED_P (type_decl
) = 1;
302 DECL_ARTIFICIAL (type_decl
) = 1;
303 TYPE_FIELDS (ret
) = fields
[0];
304 TYPE_NAME (ret
) = type_decl
;
305 TYPE_STUB_DECL (ret
) = type_decl
;
307 ubsan_source_location_type
= ret
;
311 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
312 type with its fields filled from a location_t LOC. */
315 ubsan_source_location (location_t loc
)
317 expanded_location xloc
;
318 tree type
= ubsan_get_source_location_type ();
320 xloc
= expand_location (loc
);
322 if (xloc
.file
== NULL
)
324 str
= build_int_cst (ptr_type_node
, 0);
330 /* Fill in the values from LOC. */
331 size_t len
= strlen (xloc
.file
);
332 str
= build_string (len
+ 1, xloc
.file
);
333 TREE_TYPE (str
) = build_array_type (char_type_node
,
334 build_index_type (size_int (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. */
508 static unsigned int type_var_id_num
;
509 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
510 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
512 TREE_STATIC (decl
) = 1;
513 TREE_PUBLIC (decl
) = 0;
514 DECL_ARTIFICIAL (decl
) = 1;
515 DECL_IGNORED_P (decl
) = 1;
516 DECL_EXTERNAL (decl
) = 0;
518 const char *tmp
= pp_formatted_text (&pretty_name
);
519 size_t len
= strlen (tmp
);
520 tree str
= build_string (len
+ 1, tmp
);
521 TREE_TYPE (str
) = build_array_type (char_type_node
,
522 build_index_type (size_int (len
)));
523 TREE_READONLY (str
) = 1;
524 TREE_STATIC (str
) = 1;
525 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
526 build_int_cst (short_unsigned_type_node
,
528 build_int_cst (short_unsigned_type_node
,
529 tinfo
), NULL_TREE
, str
);
530 TREE_CONSTANT (ctor
) = 1;
531 TREE_STATIC (ctor
) = 1;
532 DECL_INITIAL (decl
) = ctor
;
533 varpool_node::finalize_decl (decl
);
535 /* Save the VAR_DECL into the hash table. */
536 decl_for_type_insert (type
, decl
);
538 return build_fold_addr_expr (decl
);
541 /* Create a structure for the ubsan library. NAME is a name of the new
542 structure. LOCCNT is number of locations, PLOC points to array of
543 locations. The arguments in ... are of __ubsan_type_descriptor type
544 and there are at most two of them, followed by NULL_TREE, followed
545 by optional extra arguments and another NULL_TREE. */
548 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
553 vec
<tree
, va_gc
> *saved_args
= NULL
;
557 /* Firstly, create a pointer to type descriptor type. */
558 tree td_type
= ubsan_get_type_descriptor_type ();
559 td_type
= build_pointer_type (td_type
);
561 /* Create the structure type. */
562 ret
= make_node (RECORD_TYPE
);
563 for (j
= 0; j
< loccnt
; j
++)
565 gcc_checking_assert (i
< 2);
566 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
567 ubsan_get_source_location_type ());
568 DECL_CONTEXT (fields
[i
]) = ret
;
570 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
574 va_start (args
, ploc
);
575 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
576 i
++, t
= va_arg (args
, tree
))
578 gcc_checking_assert (i
< 4);
579 /* Save the tree arguments for later use. */
580 vec_safe_push (saved_args
, t
);
581 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
583 DECL_CONTEXT (fields
[i
]) = ret
;
585 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
588 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
589 i
++, t
= va_arg (args
, tree
))
591 gcc_checking_assert (i
< 6);
592 /* Save the tree arguments for later use. */
593 vec_safe_push (saved_args
, t
);
594 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
596 DECL_CONTEXT (fields
[i
]) = ret
;
598 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
602 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
603 get_identifier (name
), ret
);
604 DECL_IGNORED_P (type_decl
) = 1;
605 DECL_ARTIFICIAL (type_decl
) = 1;
606 TYPE_FIELDS (ret
) = fields
[0];
607 TYPE_NAME (ret
) = type_decl
;
608 TYPE_STUB_DECL (ret
) = type_decl
;
611 /* Now, fill in the type. */
613 static unsigned int ubsan_var_id_num
;
614 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
615 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
617 TREE_STATIC (var
) = 1;
618 TREE_PUBLIC (var
) = 0;
619 DECL_ARTIFICIAL (var
) = 1;
620 DECL_IGNORED_P (var
) = 1;
621 DECL_EXTERNAL (var
) = 0;
623 vec
<constructor_elt
, va_gc
> *v
;
625 tree ctor
= build_constructor (ret
, v
);
627 /* If desirable, set the __ubsan_source_location element. */
628 for (j
= 0; j
< loccnt
; j
++)
630 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
631 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
634 size_t nelts
= vec_safe_length (saved_args
);
635 for (i
= 0; i
< nelts
; i
++)
637 t
= (*saved_args
)[i
];
638 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
641 TREE_CONSTANT (ctor
) = 1;
642 TREE_STATIC (ctor
) = 1;
643 DECL_INITIAL (var
) = ctor
;
644 varpool_node::finalize_decl (var
);
649 /* Instrument the __builtin_unreachable call. We just call the libubsan
653 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
656 location_t loc
= gimple_location (gsi_stmt (*gsi
));
658 if (flag_sanitize_undefined_trap_on_error
)
659 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
662 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
663 NULL_TREE
, NULL_TREE
);
664 data
= build_fold_addr_expr_loc (loc
, data
);
666 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
667 g
= gimple_build_call (fn
, 1, data
);
669 gimple_set_location (g
, loc
);
670 gsi_replace (gsi
, g
, false);
674 /* Return true if T is a call to a libubsan routine. */
677 is_ubsan_builtin_p (tree t
)
679 return TREE_CODE (t
) == FUNCTION_DECL
680 && DECL_BUILT_IN_CLASS (t
) == BUILT_IN_NORMAL
681 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
682 "__builtin___ubsan_", 18) == 0;
685 /* Expand the UBSAN_BOUNDS special builtin function. */
688 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
690 gimple stmt
= gsi_stmt (*gsi
);
691 location_t loc
= gimple_location (stmt
);
692 gcc_assert (gimple_call_num_args (stmt
) == 3);
694 /* Pick up the arguments of the UBSAN_BOUNDS call. */
695 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
696 tree index
= gimple_call_arg (stmt
, 1);
697 tree orig_index_type
= TREE_TYPE (index
);
698 tree bound
= gimple_call_arg (stmt
, 2);
700 gimple_stmt_iterator gsi_orig
= *gsi
;
702 /* Create condition "if (index > bound)". */
703 basic_block then_bb
, fallthru_bb
;
704 gimple_stmt_iterator cond_insert_point
705 = create_cond_insert_point (gsi
, false, false, true,
706 &then_bb
, &fallthru_bb
);
707 index
= fold_convert (TREE_TYPE (bound
), index
);
708 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
710 false, GSI_NEW_STMT
);
711 gimple g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
712 gimple_set_location (g
, loc
);
713 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
715 /* Generate __ubsan_handle_out_of_bounds call. */
716 *gsi
= gsi_after_labels (then_bb
);
717 if (flag_sanitize_undefined_trap_on_error
)
718 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
722 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
723 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
724 ubsan_type_descriptor (orig_index_type
),
725 NULL_TREE
, NULL_TREE
);
726 data
= build_fold_addr_expr_loc (loc
, data
);
727 enum built_in_function bcode
728 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
729 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
730 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
731 tree fn
= builtin_decl_explicit (bcode
);
732 tree val
= force_gimple_operand_gsi (gsi
, ubsan_encode_value (index
),
733 true, NULL_TREE
, true,
735 g
= gimple_build_call (fn
, 2, data
, val
);
737 gimple_set_location (g
, loc
);
738 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
740 /* Get rid of the UBSAN_BOUNDS call from the IR. */
741 unlink_stmt_vdef (stmt
);
742 gsi_remove (&gsi_orig
, true);
744 /* Point GSI to next logical statement. */
745 *gsi
= gsi_start_bb (fallthru_bb
);
749 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
750 argument which is a constant, because the middle-end treats pointer
751 conversions as useless and therefore the type of the first argument
752 could be changed to any other pointer type. */
755 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
757 gimple_stmt_iterator gsi
= *gsip
;
758 gimple stmt
= gsi_stmt (gsi
);
759 location_t loc
= gimple_location (stmt
);
760 gcc_assert (gimple_call_num_args (stmt
) == 3);
761 tree ptr
= gimple_call_arg (stmt
, 0);
762 tree ckind
= gimple_call_arg (stmt
, 1);
763 tree align
= gimple_call_arg (stmt
, 2);
764 tree check_align
= NULL_TREE
;
767 basic_block cur_bb
= gsi_bb (gsi
);
770 if (!integer_zerop (align
))
772 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
773 if (compare_tree_int (align
, ptralign
) == 1)
775 check_align
= make_ssa_name (pointer_sized_int_node
);
776 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
777 gimple_set_location (g
, loc
);
778 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
781 check_null
= (flag_sanitize
& SANITIZE_NULL
) != 0;
783 if (check_align
== NULL_TREE
&& !check_null
)
785 gsi_remove (gsip
, true);
786 /* Unlink the UBSAN_NULLs vops before replacing it. */
787 unlink_stmt_vdef (stmt
);
791 /* Split the original block holding the pointer dereference. */
792 edge e
= split_block (cur_bb
, stmt
);
794 /* Get a hold on the 'condition block', the 'then block' and the
796 basic_block cond_bb
= e
->src
;
797 basic_block fallthru_bb
= e
->dest
;
798 basic_block then_bb
= create_empty_bb (cond_bb
);
799 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
800 loops_state_set (LOOPS_NEED_FIXUP
);
802 /* Make an edge coming from the 'cond block' into the 'then block';
803 this edge is unlikely taken, so set up the probability accordingly. */
804 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
805 e
->probability
= PROB_VERY_UNLIKELY
;
807 /* Connect 'then block' with the 'else block'. This is needed
808 as the ubsan routines we call in the 'then block' are not noreturn.
809 The 'then block' only has one outcoming edge. */
810 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
812 /* Set up the fallthrough basic block. */
813 e
= find_edge (cond_bb
, fallthru_bb
);
814 e
->flags
= EDGE_FALSE_VALUE
;
815 e
->count
= cond_bb
->count
;
816 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
818 /* Update dominance info for the newly created then_bb; note that
819 fallthru_bb's dominance info has already been updated by
821 if (dom_info_available_p (CDI_DOMINATORS
))
822 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
824 /* Put the ubsan builtin call into the newly created BB. */
825 if (flag_sanitize_undefined_trap_on_error
)
826 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
829 enum built_in_function bcode
830 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
831 | (check_null
? SANITIZE_NULL
: 0)))
832 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
833 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
834 tree fn
= builtin_decl_implicit (bcode
);
836 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
837 ubsan_type_descriptor (TREE_TYPE (ckind
),
838 UBSAN_PRINT_POINTER
),
841 fold_convert (unsigned_char_type_node
, ckind
),
843 data
= build_fold_addr_expr_loc (loc
, data
);
844 g
= gimple_build_call (fn
, 2, data
,
845 check_align
? check_align
846 : build_zero_cst (pointer_sized_int_node
));
848 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
849 gimple_set_location (g
, loc
);
850 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
852 /* Unlink the UBSAN_NULLs vops before replacing it. */
853 unlink_stmt_vdef (stmt
);
857 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
858 NULL_TREE
, NULL_TREE
);
859 gimple_set_location (g
, loc
);
861 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
862 gsi_replace (&gsi
, g
, false);
869 /* Split the block with the condition again. */
870 e
= split_block (cond_bb
, stmt
);
871 basic_block cond1_bb
= e
->src
;
872 basic_block cond2_bb
= e
->dest
;
874 /* Make an edge coming from the 'cond1 block' into the 'then block';
875 this edge is unlikely taken, so set up the probability
877 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
878 e
->probability
= PROB_VERY_UNLIKELY
;
880 /* Set up the fallthrough basic block. */
881 e
= find_edge (cond1_bb
, cond2_bb
);
882 e
->flags
= EDGE_FALSE_VALUE
;
883 e
->count
= cond1_bb
->count
;
884 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
886 /* Update dominance info. */
887 if (dom_info_available_p (CDI_DOMINATORS
))
889 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
890 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
893 gsi2
= gsi_start_bb (cond2_bb
);
896 tree mask
= build_int_cst (pointer_sized_int_node
,
897 tree_to_uhwi (align
) - 1);
898 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
899 BIT_AND_EXPR
, check_align
, mask
);
900 gimple_set_location (g
, loc
);
902 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
904 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
906 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
907 build_int_cst (pointer_sized_int_node
, 0),
908 NULL_TREE
, NULL_TREE
);
909 gimple_set_location (g
, loc
);
911 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
913 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
914 gsi_replace (&gsi
, g
, false);
919 /* Expand UBSAN_OBJECT_SIZE internal call. */
922 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
924 gimple stmt
= gsi_stmt (*gsi
);
925 location_t loc
= gimple_location (stmt
);
926 gcc_assert (gimple_call_num_args (stmt
) == 4);
928 tree ptr
= gimple_call_arg (stmt
, 0);
929 tree offset
= gimple_call_arg (stmt
, 1);
930 tree size
= gimple_call_arg (stmt
, 2);
931 tree ckind
= gimple_call_arg (stmt
, 3);
932 gimple_stmt_iterator gsi_orig
= *gsi
;
935 /* See if we can discard the check. */
936 if (TREE_CODE (size
) != INTEGER_CST
937 || integer_all_onesp (size
))
938 /* Yes, __builtin_object_size couldn't determine the
942 /* if (offset > objsize) */
943 basic_block then_bb
, fallthru_bb
;
944 gimple_stmt_iterator cond_insert_point
945 = create_cond_insert_point (gsi
, false, false, true,
946 &then_bb
, &fallthru_bb
);
947 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
948 gimple_set_location (g
, loc
);
949 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
951 /* Generate __ubsan_handle_type_mismatch call. */
952 *gsi
= gsi_after_labels (then_bb
);
953 if (flag_sanitize_undefined_trap_on_error
)
954 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
958 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
959 ubsan_type_descriptor (TREE_TYPE (ptr
),
960 UBSAN_PRINT_POINTER
),
962 build_zero_cst (pointer_sized_int_node
),
965 data
= build_fold_addr_expr_loc (loc
, data
);
966 enum built_in_function bcode
967 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
968 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
969 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
970 tree p
= make_ssa_name (pointer_sized_int_node
);
971 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
972 gimple_set_location (g
, loc
);
973 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
974 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
976 gimple_set_location (g
, loc
);
977 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
979 /* Point GSI to next logical statement. */
980 *gsi
= gsi_start_bb (fallthru_bb
);
983 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
984 unlink_stmt_vdef (stmt
);
985 gsi_remove (&gsi_orig
, true);
986 return gsi_end_p (*gsi
);
989 /* Cached __ubsan_vptr_type_cache decl. */
990 static GTY(()) tree ubsan_vptr_type_cache_decl
;
992 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
993 argument which is a constant, because the middle-end treats pointer
994 conversions as useless and therefore the type of the first argument
995 could be changed to any other pointer type. */
998 ubsan_expand_vptr_ifn (gimple_stmt_iterator
*gsip
)
1000 gimple_stmt_iterator gsi
= *gsip
;
1001 gimple stmt
= gsi_stmt (gsi
);
1002 location_t loc
= gimple_location (stmt
);
1003 gcc_assert (gimple_call_num_args (stmt
) == 5);
1004 tree op
= gimple_call_arg (stmt
, 0);
1005 tree vptr
= gimple_call_arg (stmt
, 1);
1006 tree str_hash
= gimple_call_arg (stmt
, 2);
1007 tree ti_decl_addr
= gimple_call_arg (stmt
, 3);
1008 tree ckind_tree
= gimple_call_arg (stmt
, 4);
1009 ubsan_null_ckind ckind
= (ubsan_null_ckind
) tree_to_uhwi (ckind_tree
);
1010 tree type
= TREE_TYPE (TREE_TYPE (ckind_tree
));
1012 basic_block fallthru_bb
= NULL
;
1014 if (ckind
== UBSAN_DOWNCAST_POINTER
)
1016 /* Guard everything with if (op != NULL) { ... }. */
1017 basic_block then_bb
;
1018 gimple_stmt_iterator cond_insert_point
1019 = create_cond_insert_point (gsip
, false, false, true,
1020 &then_bb
, &fallthru_bb
);
1021 g
= gimple_build_cond (NE_EXPR
, op
, build_zero_cst (TREE_TYPE (op
)),
1022 NULL_TREE
, NULL_TREE
);
1023 gimple_set_location (g
, loc
);
1024 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1025 *gsip
= gsi_after_labels (then_bb
);
1026 gsi_remove (&gsi
, false);
1027 gsi_insert_before (gsip
, stmt
, GSI_NEW_STMT
);
1031 tree htype
= TREE_TYPE (str_hash
);
1032 tree cst
= wide_int_to_tree (htype
,
1033 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1035 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1037 gimple_set_location (g
, loc
);
1038 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1039 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1040 gimple_assign_lhs (g
), cst
);
1041 gimple_set_location (g
, loc
);
1042 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1043 tree t1
= gimple_assign_lhs (g
);
1044 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1045 t1
, build_int_cst (integer_type_node
, 47));
1046 gimple_set_location (g
, loc
);
1047 tree t2
= gimple_assign_lhs (g
);
1048 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1049 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1051 gimple_set_location (g
, loc
);
1052 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1053 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1054 t2
, gimple_assign_lhs (g
));
1055 gimple_set_location (g
, loc
);
1056 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1057 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1058 gimple_assign_lhs (g
), cst
);
1059 gimple_set_location (g
, loc
);
1060 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1061 tree t3
= gimple_assign_lhs (g
);
1062 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1063 t3
, build_int_cst (integer_type_node
, 47));
1064 gimple_set_location (g
, loc
);
1065 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1066 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1067 t3
, gimple_assign_lhs (g
));
1068 gimple_set_location (g
, loc
);
1069 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1070 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1071 gimple_assign_lhs (g
), cst
);
1072 gimple_set_location (g
, loc
);
1073 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1074 if (!useless_type_conversion_p (pointer_sized_int_node
, htype
))
1076 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1077 NOP_EXPR
, gimple_assign_lhs (g
));
1078 gimple_set_location (g
, loc
);
1079 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1081 tree hash
= gimple_assign_lhs (g
);
1083 if (ubsan_vptr_type_cache_decl
== NULL_TREE
)
1085 tree atype
= build_array_type_nelts (pointer_sized_int_node
, 128);
1086 tree array
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1087 get_identifier ("__ubsan_vptr_type_cache"),
1089 DECL_ARTIFICIAL (array
) = 1;
1090 DECL_IGNORED_P (array
) = 1;
1091 TREE_PUBLIC (array
) = 1;
1092 TREE_STATIC (array
) = 1;
1093 DECL_EXTERNAL (array
) = 1;
1094 DECL_VISIBILITY (array
) = VISIBILITY_DEFAULT
;
1095 DECL_VISIBILITY_SPECIFIED (array
) = 1;
1096 varpool_node::finalize_decl (array
);
1097 ubsan_vptr_type_cache_decl
= array
;
1100 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1102 build_int_cst (pointer_sized_int_node
, 127));
1103 gimple_set_location (g
, loc
);
1104 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1106 tree c
= build4_loc (loc
, ARRAY_REF
, pointer_sized_int_node
,
1107 ubsan_vptr_type_cache_decl
, gimple_assign_lhs (g
),
1108 NULL_TREE
, NULL_TREE
);
1109 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1111 gimple_set_location (g
, loc
);
1112 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1114 basic_block then_bb
, fallthru2_bb
;
1115 gimple_stmt_iterator cond_insert_point
1116 = create_cond_insert_point (gsip
, false, false, true,
1117 &then_bb
, &fallthru2_bb
);
1118 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
), hash
,
1119 NULL_TREE
, NULL_TREE
);
1120 gimple_set_location (g
, loc
);
1121 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1122 *gsip
= gsi_after_labels (then_bb
);
1123 if (fallthru_bb
== NULL
)
1124 fallthru_bb
= fallthru2_bb
;
1127 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc
,
1128 ubsan_type_descriptor (type
), NULL_TREE
, ti_decl_addr
,
1129 build_int_cst (unsigned_char_type_node
, ckind
),
1131 data
= build_fold_addr_expr_loc (loc
, data
);
1132 enum built_in_function bcode
1133 = (flag_sanitize_recover
& SANITIZE_VPTR
)
1134 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1135 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT
;
1137 g
= gimple_build_call (builtin_decl_explicit (bcode
), 3, data
, op
, hash
);
1138 gimple_set_location (g
, loc
);
1139 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1141 /* Point GSI to next logical statement. */
1142 *gsip
= gsi_start_bb (fallthru_bb
);
1144 /* Get rid of the UBSAN_VPTR call from the IR. */
1145 unlink_stmt_vdef (stmt
);
1146 gsi_remove (&gsi
, true);
1147 return gsi_end_p (*gsip
);
1150 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1151 whether the pointer is on the left hand side of the assignment. */
1154 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
1157 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
1158 unsigned int align
= 0;
1159 if (flag_sanitize
& SANITIZE_ALIGNMENT
)
1161 align
= min_align_of_type (TREE_TYPE (base
));
1165 if (align
== 0 && (flag_sanitize
& SANITIZE_NULL
) == 0)
1167 tree t
= TREE_OPERAND (base
, 0);
1168 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
1170 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t
))) && mem
!= base
)
1171 ikind
= UBSAN_MEMBER_ACCESS
;
1172 tree kind
= build_int_cst (TREE_TYPE (t
), ikind
);
1173 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
1174 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
1175 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
1176 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
1179 /* Perform the pointer instrumentation. */
1182 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
1184 gimple stmt
= gsi_stmt (gsi
);
1185 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1186 tree base
= get_base_address (t
);
1187 const enum tree_code code
= TREE_CODE (base
);
1189 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1190 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1193 /* Build an ubsan builtin call for the signed-integer-overflow
1194 sanitization. CODE says what kind of builtin are we building,
1195 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1196 are operands of the binary operation. */
1199 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1202 if (flag_sanitize_undefined_trap_on_error
)
1203 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1205 tree data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1206 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1208 enum built_in_function fn_code
;
1213 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1214 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1215 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1218 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1219 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1220 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1223 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1224 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1225 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1228 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1229 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1230 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1235 tree fn
= builtin_decl_explicit (fn_code
);
1236 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1237 build_fold_addr_expr_loc (loc
, data
),
1238 ubsan_encode_value (op0
, true),
1239 op1
? ubsan_encode_value (op1
, true)
1243 /* Perform the signed integer instrumentation. GSI is the iterator
1244 pointing at statement we are trying to instrument. */
1247 instrument_si_overflow (gimple_stmt_iterator gsi
)
1249 gimple stmt
= gsi_stmt (gsi
);
1250 tree_code code
= gimple_assign_rhs_code (stmt
);
1251 tree lhs
= gimple_assign_lhs (stmt
);
1252 tree lhstype
= TREE_TYPE (lhs
);
1256 /* If this is not a signed operation, don't instrument anything here.
1257 Also punt on bit-fields. */
1258 if (!INTEGRAL_TYPE_P (lhstype
)
1259 || TYPE_OVERFLOW_WRAPS (lhstype
)
1260 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
1271 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1272 a
= gimple_assign_rhs1 (stmt
);
1273 b
= gimple_assign_rhs2 (stmt
);
1274 g
= gimple_build_call_internal (code
== PLUS_EXPR
1275 ? IFN_UBSAN_CHECK_ADD
1276 : code
== MINUS_EXPR
1277 ? IFN_UBSAN_CHECK_SUB
1278 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1279 gimple_call_set_lhs (g
, lhs
);
1280 gsi_replace (&gsi
, g
, false);
1283 /* Represent i = -u;
1285 i = UBSAN_CHECK_SUB (0, u); */
1286 a
= build_int_cst (lhstype
, 0);
1287 b
= gimple_assign_rhs1 (stmt
);
1288 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1289 gimple_call_set_lhs (g
, lhs
);
1290 gsi_replace (&gsi
, g
, false);
1293 /* Transform i = ABS_EXPR<u>;
1295 _N = UBSAN_CHECK_SUB (0, u);
1296 i = ABS_EXPR<_N>; */
1297 a
= build_int_cst (lhstype
, 0);
1298 b
= gimple_assign_rhs1 (stmt
);
1299 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1300 a
= make_ssa_name (lhstype
);
1301 gimple_call_set_lhs (g
, a
);
1302 gimple_set_location (g
, gimple_location (stmt
));
1303 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1304 gimple_assign_set_rhs1 (stmt
, a
);
1312 /* Instrument loads from (non-bitfield) bool and C++ enum values
1313 to check if the memory value is outside of the range of the valid
1317 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1319 gimple stmt
= gsi_stmt (*gsi
);
1320 tree rhs
= gimple_assign_rhs1 (stmt
);
1321 tree type
= TREE_TYPE (rhs
);
1322 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1324 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
1326 minv
= boolean_false_node
;
1327 maxv
= boolean_true_node
;
1329 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1330 && (flag_sanitize
& SANITIZE_ENUM
)
1331 && TREE_TYPE (type
) != NULL_TREE
1332 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1333 && (TYPE_PRECISION (TREE_TYPE (type
))
1334 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1336 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1337 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1342 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1343 HOST_WIDE_INT bitsize
, bitpos
;
1346 int volatilep
= 0, unsignedp
= 0;
1347 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1348 &unsignedp
, &volatilep
, false);
1349 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1351 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
1352 || (bitpos
% modebitsize
) != 0
1353 || bitsize
!= modebitsize
1354 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1355 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1358 bool can_throw
= stmt_could_throw_p (stmt
);
1359 location_t loc
= gimple_location (stmt
);
1360 tree lhs
= gimple_assign_lhs (stmt
);
1361 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1362 tree atype
= reference_alias_ptr_type (rhs
);
1363 gimple g
= gimple_build_assign (make_ssa_name (ptype
),
1364 build_fold_addr_expr (rhs
));
1365 gimple_set_location (g
, loc
);
1366 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1367 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1368 build_int_cst (atype
, 0));
1369 tree urhs
= make_ssa_name (utype
);
1372 gimple_assign_set_lhs (stmt
, urhs
);
1373 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1374 gimple_set_location (g
, loc
);
1375 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1376 gsi_insert_on_edge_immediate (e
, g
);
1377 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1379 *gsi
= gsi_for_stmt (g
);
1384 g
= gimple_build_assign (urhs
, mem
);
1385 gimple_set_location (g
, loc
);
1386 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1388 minv
= fold_convert (utype
, minv
);
1389 maxv
= fold_convert (utype
, maxv
);
1390 if (!integer_zerop (minv
))
1392 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1393 gimple_set_location (g
, loc
);
1394 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1397 gimple_stmt_iterator gsi2
= *gsi
;
1398 basic_block then_bb
, fallthru_bb
;
1399 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1400 &then_bb
, &fallthru_bb
);
1401 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1402 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1403 NULL_TREE
, NULL_TREE
);
1404 gimple_set_location (g
, loc
);
1405 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1409 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1413 gsi2
= gsi_after_labels (then_bb
);
1414 if (flag_sanitize_undefined_trap_on_error
)
1415 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1418 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1419 ubsan_type_descriptor (type
), NULL_TREE
,
1421 data
= build_fold_addr_expr_loc (loc
, data
);
1422 enum built_in_function bcode
1423 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1424 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1425 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1426 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1427 tree fn
= builtin_decl_explicit (bcode
);
1429 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
1430 true, NULL_TREE
, true,
1432 g
= gimple_build_call (fn
, 2, data
, val
);
1434 gimple_set_location (g
, loc
);
1435 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1436 *gsi
= gsi_for_stmt (stmt
);
1439 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1440 destination, EXPR is floating-point expression. ARG is what to pass
1441 the libubsan call as value, often EXPR itself. */
1444 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
, tree arg
)
1446 tree expr_type
= TREE_TYPE (expr
);
1447 tree t
, tt
, fn
, min
, max
;
1448 machine_mode mode
= TYPE_MODE (expr_type
);
1449 int prec
= TYPE_PRECISION (type
);
1450 bool uns_p
= TYPE_UNSIGNED (type
);
1452 /* Float to integer conversion first truncates toward zero, so
1453 even signed char c = 127.875f; is not problematic.
1454 Therefore, we should complain only if EXPR is unordered or smaller
1455 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1456 TYPE_MAX_VALUE + 1.0. */
1457 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1459 /* For maximum, TYPE_MAX_VALUE might not be representable
1460 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1461 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1462 either representable or infinity. */
1463 REAL_VALUE_TYPE maxval
= dconst1
;
1464 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1465 real_convert (&maxval
, mode
, &maxval
);
1466 max
= build_real (expr_type
, maxval
);
1468 /* For unsigned, assume -1.0 is always representable. */
1470 min
= build_minus_one_cst (expr_type
);
1473 /* TYPE_MIN_VALUE is generally representable (or -inf),
1474 but TYPE_MIN_VALUE - 1.0 might not be. */
1475 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1476 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1477 real_convert (&minval
, mode
, &minval
);
1478 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1479 real_convert (&minval2
, mode
, &minval2
);
1480 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1481 && !real_isinf (&minval
))
1483 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1484 rounds to TYPE_MIN_VALUE, we need to subtract
1485 more. As REAL_MODE_FORMAT (mode)->p is the number
1486 of base digits, we want to subtract a number that
1487 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1488 times smaller than minval. */
1490 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1491 SET_REAL_EXP (&minval2
,
1492 REAL_EXP (&minval2
) + prec
- 1
1493 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1494 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1495 real_convert (&minval2
, mode
, &minval2
);
1497 min
= build_real (expr_type
, minval2
);
1500 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1502 /* For _Decimal128 up to 34 decimal digits, - sign,
1503 dot, e, exponent. */
1506 int p
= REAL_MODE_FORMAT (mode
)->p
;
1507 REAL_VALUE_TYPE maxval
, minval
;
1509 /* Use mpfr_snprintf rounding to compute the smallest
1510 representable decimal number greater or equal than
1511 1 << (prec - !uns_p). */
1512 mpfr_init2 (m
, prec
+ 2);
1513 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1514 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1515 decimal_real_from_string (&maxval
, buf
);
1516 max
= build_real (expr_type
, maxval
);
1518 /* For unsigned, assume -1.0 is always representable. */
1520 min
= build_minus_one_cst (expr_type
);
1523 /* Use mpfr_snprintf rounding to compute the largest
1524 representable decimal number less or equal than
1525 (-1 << (prec - 1)) - 1. */
1526 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1527 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1528 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1529 decimal_real_from_string (&minval
, buf
);
1530 min
= build_real (expr_type
, minval
);
1537 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1538 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1539 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
);
1540 if (integer_zerop (t
))
1543 if (flag_sanitize_undefined_trap_on_error
)
1544 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1547 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1548 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1549 NULL
, ubsan_type_descriptor (expr_type
),
1550 ubsan_type_descriptor (type
), NULL_TREE
,
1552 enum built_in_function bcode
1553 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1554 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1555 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1556 fn
= builtin_decl_explicit (bcode
);
1557 fn
= build_call_expr_loc (loc
, fn
, 2,
1558 build_fold_addr_expr_loc (loc
, data
),
1559 ubsan_encode_value (arg
, false));
1562 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1565 /* Instrument values passed to function arguments with nonnull attribute. */
1568 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1570 gimple stmt
= gsi_stmt (*gsi
);
1572 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1573 while for nonnull sanitization it is clear. */
1574 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1575 flag_delete_null_pointer_checks
= 1;
1576 loc
[0] = gimple_location (stmt
);
1577 loc
[1] = UNKNOWN_LOCATION
;
1578 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1580 tree arg
= gimple_call_arg (stmt
, i
);
1581 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1582 && infer_nonnull_range (stmt
, arg
, false, true))
1585 if (!is_gimple_val (arg
))
1587 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1588 gimple_set_location (g
, loc
[0]);
1589 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1590 arg
= gimple_assign_lhs (g
);
1593 basic_block then_bb
, fallthru_bb
;
1594 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1595 &then_bb
, &fallthru_bb
);
1596 g
= gimple_build_cond (EQ_EXPR
, arg
,
1597 build_zero_cst (TREE_TYPE (arg
)),
1598 NULL_TREE
, NULL_TREE
);
1599 gimple_set_location (g
, loc
[0]);
1600 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1602 *gsi
= gsi_after_labels (then_bb
);
1603 if (flag_sanitize_undefined_trap_on_error
)
1604 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1607 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1609 build_int_cst (integer_type_node
,
1612 data
= build_fold_addr_expr_loc (loc
[0], data
);
1613 enum built_in_function bcode
1614 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1615 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1616 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1617 tree fn
= builtin_decl_explicit (bcode
);
1619 g
= gimple_build_call (fn
, 1, data
);
1621 gimple_set_location (g
, loc
[0]);
1622 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1624 *gsi
= gsi_for_stmt (stmt
);
1626 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1629 /* Instrument returns in functions with returns_nonnull attribute. */
1632 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1634 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
1636 tree arg
= gimple_return_retval (stmt
);
1637 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1638 while for nonnull return sanitization it is clear. */
1639 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1640 flag_delete_null_pointer_checks
= 1;
1641 loc
[0] = gimple_location (stmt
);
1642 loc
[1] = UNKNOWN_LOCATION
;
1644 && POINTER_TYPE_P (TREE_TYPE (arg
))
1645 && is_gimple_val (arg
)
1646 && infer_nonnull_range (stmt
, arg
, false, true))
1648 basic_block then_bb
, fallthru_bb
;
1649 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1650 &then_bb
, &fallthru_bb
);
1651 gimple g
= gimple_build_cond (EQ_EXPR
, arg
,
1652 build_zero_cst (TREE_TYPE (arg
)),
1653 NULL_TREE
, NULL_TREE
);
1654 gimple_set_location (g
, loc
[0]);
1655 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1657 *gsi
= gsi_after_labels (then_bb
);
1658 if (flag_sanitize_undefined_trap_on_error
)
1659 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1662 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
1663 2, loc
, NULL_TREE
, NULL_TREE
);
1664 data
= build_fold_addr_expr_loc (loc
[0], data
);
1665 enum built_in_function bcode
1666 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1667 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1668 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
1669 tree fn
= builtin_decl_explicit (bcode
);
1671 g
= gimple_build_call (fn
, 1, data
);
1673 gimple_set_location (g
, loc
[0]);
1674 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1675 *gsi
= gsi_for_stmt (stmt
);
1677 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1680 /* Instrument memory references. Here we check whether the pointer
1681 points to an out-of-bounds location. */
1684 instrument_object_size (gimple_stmt_iterator
*gsi
, bool is_lhs
)
1686 gimple stmt
= gsi_stmt (*gsi
);
1687 location_t loc
= gimple_location (stmt
);
1688 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1690 tree index
= NULL_TREE
;
1691 HOST_WIDE_INT size_in_bytes
;
1693 type
= TREE_TYPE (t
);
1694 if (VOID_TYPE_P (type
))
1697 switch (TREE_CODE (t
))
1700 if (TREE_CODE (t
) == COMPONENT_REF
1701 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
1703 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
1704 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
1709 index
= TREE_OPERAND (t
, 1);
1721 size_in_bytes
= int_size_in_bytes (type
);
1722 if (size_in_bytes
<= 0)
1725 HOST_WIDE_INT bitsize
, bitpos
;
1728 int volatilep
= 0, unsignedp
= 0;
1729 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1730 &unsignedp
, &volatilep
, false);
1732 if (bitpos
% BITS_PER_UNIT
!= 0
1733 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
1736 bool decl_p
= DECL_P (inner
);
1740 else if (TREE_CODE (inner
) == MEM_REF
)
1741 base
= TREE_OPERAND (inner
, 0);
1744 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
1746 while (TREE_CODE (base
) == SSA_NAME
)
1748 gimple def_stmt
= SSA_NAME_DEF_STMT (base
);
1749 if (gimple_assign_ssa_name_copy_p (def_stmt
)
1750 || (gimple_assign_cast_p (def_stmt
)
1751 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
1752 || (is_gimple_assign (def_stmt
)
1753 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
1755 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
1756 if (TREE_CODE (rhs1
) == SSA_NAME
1757 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
1766 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1770 tree base_addr
= base
;
1772 base_addr
= build1 (ADDR_EXPR
,
1773 build_pointer_type (TREE_TYPE (base
)), base
);
1774 unsigned HOST_WIDE_INT size
= compute_builtin_object_size (base_addr
, 0);
1775 if (size
!= (unsigned HOST_WIDE_INT
) -1)
1776 sizet
= build_int_cst (sizetype
, size
);
1779 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
1780 loc
= input_location
;
1781 /* Generate __builtin_object_size call. */
1782 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
1783 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
1785 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
1791 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1793 /* ptr + sizeof (*ptr) - base */
1794 t
= fold_build2 (MINUS_EXPR
, sizetype
,
1795 fold_convert (pointer_sized_int_node
, ptr
),
1796 fold_convert (pointer_sized_int_node
, base_addr
));
1797 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
1799 /* Perhaps we can omit the check. */
1800 if (TREE_CODE (t
) == INTEGER_CST
1801 && TREE_CODE (sizet
) == INTEGER_CST
1802 && tree_int_cst_le (t
, sizet
))
1805 if (index
!= NULL_TREE
1806 && TREE_CODE (index
) == SSA_NAME
1807 && TREE_CODE (sizet
) == INTEGER_CST
)
1809 gimple def
= SSA_NAME_DEF_STMT (index
);
1810 if (is_gimple_assign (def
)
1811 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
1812 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
1814 tree cst
= gimple_assign_rhs2 (def
);
1815 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
1816 TYPE_SIZE_UNIT (type
));
1817 if (tree_int_cst_sgn (cst
) >= 0
1818 && tree_int_cst_lt (cst
, sz
))
1823 /* Nope. Emit the check. */
1824 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1826 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
1828 tree ckind
= build_int_cst (unsigned_char_type_node
,
1829 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
1830 gimple g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
1831 ptr
, t
, sizet
, ckind
);
1832 gimple_set_location (g
, loc
);
1833 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1836 /* True if we want to play UBSan games in the current function. */
1839 do_ubsan_in_current_function ()
1841 return (current_function_decl
!= NULL_TREE
1842 && !lookup_attribute ("no_sanitize_undefined",
1843 DECL_ATTRIBUTES (current_function_decl
)));
1848 const pass_data pass_data_ubsan
=
1850 GIMPLE_PASS
, /* type */
1852 OPTGROUP_NONE
, /* optinfo_flags */
1853 TV_TREE_UBSAN
, /* tv_id */
1854 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1855 0, /* properties_provided */
1856 0, /* properties_destroyed */
1857 0, /* todo_flags_start */
1858 TODO_update_ssa
, /* todo_flags_finish */
1861 class pass_ubsan
: public gimple_opt_pass
1864 pass_ubsan (gcc::context
*ctxt
)
1865 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1868 /* opt_pass methods: */
1869 virtual bool gate (function
*)
1871 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1872 | SANITIZE_BOOL
| SANITIZE_ENUM
1873 | SANITIZE_ALIGNMENT
1874 | SANITIZE_NONNULL_ATTRIBUTE
1875 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1876 | SANITIZE_OBJECT_SIZE
)
1877 && do_ubsan_in_current_function ();
1880 virtual unsigned int execute (function
*);
1882 }; // class pass_ubsan
1885 pass_ubsan::execute (function
*fun
)
1888 gimple_stmt_iterator gsi
;
1890 initialize_sanitizer_builtins ();
1892 FOR_EACH_BB_FN (bb
, fun
)
1894 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1896 gimple stmt
= gsi_stmt (gsi
);
1897 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
1903 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
1904 && is_gimple_assign (stmt
))
1905 instrument_si_overflow (gsi
);
1907 if (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1909 if (gimple_store_p (stmt
))
1910 instrument_null (gsi
, true);
1911 if (gimple_assign_load_p (stmt
))
1912 instrument_null (gsi
, false);
1915 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
1916 && gimple_assign_load_p (stmt
))
1918 instrument_bool_enum_load (&gsi
);
1919 bb
= gimple_bb (stmt
);
1922 if ((flag_sanitize
& SANITIZE_NONNULL_ATTRIBUTE
)
1923 && is_gimple_call (stmt
)
1924 && !gimple_call_internal_p (stmt
))
1926 instrument_nonnull_arg (&gsi
);
1927 bb
= gimple_bb (stmt
);
1930 if ((flag_sanitize
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1931 && gimple_code (stmt
) == GIMPLE_RETURN
)
1933 instrument_nonnull_return (&gsi
);
1934 bb
= gimple_bb (stmt
);
1937 if (flag_sanitize
& SANITIZE_OBJECT_SIZE
)
1939 if (gimple_store_p (stmt
))
1940 instrument_object_size (&gsi
, true);
1941 if (gimple_assign_load_p (stmt
))
1942 instrument_object_size (&gsi
, false);
1954 make_pass_ubsan (gcc::context
*ctxt
)
1956 return new pass_ubsan (ctxt
);
1959 #include "gt-ubsan.h"