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
) + 1;
332 str
= build_string (len
, xloc
.file
);
333 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
334 TREE_READONLY (str
) = 1;
335 TREE_STATIC (str
) = 1;
336 str
= build_fold_addr_expr (str
);
338 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
339 build_int_cst (unsigned_type_node
,
340 xloc
.line
), NULL_TREE
,
341 build_int_cst (unsigned_type_node
,
343 TREE_CONSTANT (ctor
) = 1;
344 TREE_STATIC (ctor
) = 1;
349 /* This routine returns a magic number for TYPE. */
351 static unsigned short
352 get_ubsan_type_info_for_type (tree type
)
354 gcc_assert (TYPE_SIZE (type
) && tree_fits_uhwi_p (TYPE_SIZE (type
)));
355 if (TREE_CODE (type
) == REAL_TYPE
)
356 return tree_to_uhwi (TYPE_SIZE (type
));
357 else if (INTEGRAL_TYPE_P (type
))
359 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
360 gcc_assert (prec
!= -1);
361 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
367 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
368 descriptor. It first looks into the hash table; if not found,
369 create the VAR_DECL, put it into the hash table and return the
370 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
371 an enum controlling how we want to print the type. */
374 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
376 /* See through any typedefs. */
377 type
= TYPE_MAIN_VARIANT (type
);
379 tree decl
= decl_for_type_lookup (type
);
380 /* It is possible that some of the earlier created DECLs were found
381 unused, in that case they weren't emitted and varpool_node::get
382 returns NULL node on them. But now we really need them. Thus,
384 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
385 return build_fold_addr_expr (decl
);
387 tree dtype
= ubsan_get_type_descriptor_type ();
389 const char *tname
= NULL
;
390 pretty_printer pretty_name
;
391 unsigned char deref_depth
= 0;
392 unsigned short tkind
, tinfo
;
394 /* Get the name of the type, or the name of the pointer type. */
395 if (pstyle
== UBSAN_PRINT_POINTER
)
397 gcc_assert (POINTER_TYPE_P (type
));
398 type2
= TREE_TYPE (type
);
400 /* Remove any '*' operators from TYPE. */
401 while (POINTER_TYPE_P (type2
))
402 deref_depth
++, type2
= TREE_TYPE (type2
);
404 if (TREE_CODE (type2
) == METHOD_TYPE
)
405 type2
= TYPE_METHOD_BASETYPE (type2
);
408 /* If an array, get its type. */
409 type2
= strip_array_types (type2
);
411 if (pstyle
== UBSAN_PRINT_ARRAY
)
413 while (POINTER_TYPE_P (type2
))
414 deref_depth
++, type2
= TREE_TYPE (type2
);
417 if (TYPE_NAME (type2
) != NULL
)
419 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
420 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
421 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
422 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
426 /* We weren't able to determine the type name. */
429 if (pstyle
== UBSAN_PRINT_POINTER
)
431 pp_printf (&pretty_name
, "'%s%s%s%s%s%s%s",
432 TYPE_VOLATILE (type2
) ? "volatile " : "",
433 TYPE_READONLY (type2
) ? "const " : "",
434 TYPE_RESTRICT (type2
) ? "restrict " : "",
435 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
436 TREE_CODE (type2
) == RECORD_TYPE
438 : TREE_CODE (type2
) == UNION_TYPE
439 ? "union " : "", tname
,
440 deref_depth
== 0 ? "" : " ");
441 while (deref_depth
-- > 0)
442 pp_star (&pretty_name
);
443 pp_quote (&pretty_name
);
445 else if (pstyle
== UBSAN_PRINT_ARRAY
)
447 /* Pretty print the array dimensions. */
448 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
450 pp_printf (&pretty_name
, "'%s ", tname
);
451 while (deref_depth
-- > 0)
452 pp_star (&pretty_name
);
453 while (TREE_CODE (t
) == ARRAY_TYPE
)
455 pp_left_bracket (&pretty_name
);
456 tree dom
= TYPE_DOMAIN (t
);
457 if (dom
&& TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
459 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom
))
460 && tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1 != 0)
461 pp_printf (&pretty_name
, HOST_WIDE_INT_PRINT_DEC
,
462 tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1);
464 pp_wide_int (&pretty_name
,
465 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom
)), 1),
466 TYPE_SIGN (TREE_TYPE (dom
)));
469 /* ??? We can't determine the variable name; print VLA unspec. */
470 pp_star (&pretty_name
);
471 pp_right_bracket (&pretty_name
);
474 pp_quote (&pretty_name
);
476 /* Save the tree with stripped types. */
480 pp_printf (&pretty_name
, "'%s'", tname
);
482 switch (TREE_CODE (type
))
490 /* FIXME: libubsan right now only supports float, double and
491 long double type formats. */
492 if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
)
493 || TYPE_MODE (type
) == TYPE_MODE (double_type_node
)
494 || TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
503 tinfo
= get_ubsan_type_info_for_type (type
);
505 /* Create a new VAR_DECL of type descriptor. */
506 const char *tmp
= pp_formatted_text (&pretty_name
);
507 size_t len
= strlen (tmp
) + 1;
508 tree str
= build_string (len
, tmp
);
509 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
510 TREE_READONLY (str
) = 1;
511 TREE_STATIC (str
) = 1;
514 static unsigned int type_var_id_num
;
515 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
516 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
518 TREE_STATIC (decl
) = 1;
519 TREE_PUBLIC (decl
) = 0;
520 DECL_ARTIFICIAL (decl
) = 1;
521 DECL_IGNORED_P (decl
) = 1;
522 DECL_EXTERNAL (decl
) = 0;
524 = size_binop (PLUS_EXPR
, DECL_SIZE (decl
), TYPE_SIZE (TREE_TYPE (str
)));
525 DECL_SIZE_UNIT (decl
)
526 = size_binop (PLUS_EXPR
, DECL_SIZE_UNIT (decl
),
527 TYPE_SIZE_UNIT (TREE_TYPE (str
)));
529 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
530 build_int_cst (short_unsigned_type_node
,
532 build_int_cst (short_unsigned_type_node
,
533 tinfo
), NULL_TREE
, str
);
534 TREE_CONSTANT (ctor
) = 1;
535 TREE_STATIC (ctor
) = 1;
536 DECL_INITIAL (decl
) = ctor
;
537 varpool_node::finalize_decl (decl
);
539 /* Save the VAR_DECL into the hash table. */
540 decl_for_type_insert (type
, decl
);
542 return build_fold_addr_expr (decl
);
545 /* Create a structure for the ubsan library. NAME is a name of the new
546 structure. LOCCNT is number of locations, PLOC points to array of
547 locations. The arguments in ... are of __ubsan_type_descriptor type
548 and there are at most two of them, followed by NULL_TREE, followed
549 by optional extra arguments and another NULL_TREE. */
552 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
557 vec
<tree
, va_gc
> *saved_args
= NULL
;
561 /* Firstly, create a pointer to type descriptor type. */
562 tree td_type
= ubsan_get_type_descriptor_type ();
563 td_type
= build_pointer_type (td_type
);
565 /* Create the structure type. */
566 ret
= make_node (RECORD_TYPE
);
567 for (j
= 0; j
< loccnt
; j
++)
569 gcc_checking_assert (i
< 2);
570 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
571 ubsan_get_source_location_type ());
572 DECL_CONTEXT (fields
[i
]) = ret
;
574 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
578 va_start (args
, ploc
);
579 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
580 i
++, t
= va_arg (args
, tree
))
582 gcc_checking_assert (i
< 4);
583 /* Save the tree arguments for later use. */
584 vec_safe_push (saved_args
, t
);
585 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
587 DECL_CONTEXT (fields
[i
]) = ret
;
589 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
592 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
593 i
++, t
= va_arg (args
, tree
))
595 gcc_checking_assert (i
< 6);
596 /* Save the tree arguments for later use. */
597 vec_safe_push (saved_args
, t
);
598 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
600 DECL_CONTEXT (fields
[i
]) = ret
;
602 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
606 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
607 get_identifier (name
), ret
);
608 DECL_IGNORED_P (type_decl
) = 1;
609 DECL_ARTIFICIAL (type_decl
) = 1;
610 TYPE_FIELDS (ret
) = fields
[0];
611 TYPE_NAME (ret
) = type_decl
;
612 TYPE_STUB_DECL (ret
) = type_decl
;
615 /* Now, fill in the type. */
617 static unsigned int ubsan_var_id_num
;
618 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
619 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
621 TREE_STATIC (var
) = 1;
622 TREE_PUBLIC (var
) = 0;
623 DECL_ARTIFICIAL (var
) = 1;
624 DECL_IGNORED_P (var
) = 1;
625 DECL_EXTERNAL (var
) = 0;
627 vec
<constructor_elt
, va_gc
> *v
;
629 tree ctor
= build_constructor (ret
, v
);
631 /* If desirable, set the __ubsan_source_location element. */
632 for (j
= 0; j
< loccnt
; j
++)
634 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
635 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
638 size_t nelts
= vec_safe_length (saved_args
);
639 for (i
= 0; i
< nelts
; i
++)
641 t
= (*saved_args
)[i
];
642 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
645 TREE_CONSTANT (ctor
) = 1;
646 TREE_STATIC (ctor
) = 1;
647 DECL_INITIAL (var
) = ctor
;
648 varpool_node::finalize_decl (var
);
653 /* Instrument the __builtin_unreachable call. We just call the libubsan
657 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
660 location_t loc
= gimple_location (gsi_stmt (*gsi
));
662 if (flag_sanitize_undefined_trap_on_error
)
663 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
666 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
667 NULL_TREE
, NULL_TREE
);
668 data
= build_fold_addr_expr_loc (loc
, data
);
670 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
671 g
= gimple_build_call (fn
, 1, data
);
673 gimple_set_location (g
, loc
);
674 gsi_replace (gsi
, g
, false);
678 /* Return true if T is a call to a libubsan routine. */
681 is_ubsan_builtin_p (tree t
)
683 return TREE_CODE (t
) == FUNCTION_DECL
684 && DECL_BUILT_IN_CLASS (t
) == BUILT_IN_NORMAL
685 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
686 "__builtin___ubsan_", 18) == 0;
689 /* Expand the UBSAN_BOUNDS special builtin function. */
692 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
694 gimple stmt
= gsi_stmt (*gsi
);
695 location_t loc
= gimple_location (stmt
);
696 gcc_assert (gimple_call_num_args (stmt
) == 3);
698 /* Pick up the arguments of the UBSAN_BOUNDS call. */
699 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
700 tree index
= gimple_call_arg (stmt
, 1);
701 tree orig_index_type
= TREE_TYPE (index
);
702 tree bound
= gimple_call_arg (stmt
, 2);
704 gimple_stmt_iterator gsi_orig
= *gsi
;
706 /* Create condition "if (index > bound)". */
707 basic_block then_bb
, fallthru_bb
;
708 gimple_stmt_iterator cond_insert_point
709 = create_cond_insert_point (gsi
, false, false, true,
710 &then_bb
, &fallthru_bb
);
711 index
= fold_convert (TREE_TYPE (bound
), index
);
712 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
714 false, GSI_NEW_STMT
);
715 gimple g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
716 gimple_set_location (g
, loc
);
717 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
719 /* Generate __ubsan_handle_out_of_bounds call. */
720 *gsi
= gsi_after_labels (then_bb
);
721 if (flag_sanitize_undefined_trap_on_error
)
722 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
726 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
727 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
728 ubsan_type_descriptor (orig_index_type
),
729 NULL_TREE
, NULL_TREE
);
730 data
= build_fold_addr_expr_loc (loc
, data
);
731 enum built_in_function bcode
732 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
733 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
734 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
735 tree fn
= builtin_decl_explicit (bcode
);
736 tree val
= force_gimple_operand_gsi (gsi
, ubsan_encode_value (index
),
737 true, NULL_TREE
, true,
739 g
= gimple_build_call (fn
, 2, data
, val
);
741 gimple_set_location (g
, loc
);
742 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
744 /* Get rid of the UBSAN_BOUNDS call from the IR. */
745 unlink_stmt_vdef (stmt
);
746 gsi_remove (&gsi_orig
, true);
748 /* Point GSI to next logical statement. */
749 *gsi
= gsi_start_bb (fallthru_bb
);
753 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
754 argument which is a constant, because the middle-end treats pointer
755 conversions as useless and therefore the type of the first argument
756 could be changed to any other pointer type. */
759 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
761 gimple_stmt_iterator gsi
= *gsip
;
762 gimple stmt
= gsi_stmt (gsi
);
763 location_t loc
= gimple_location (stmt
);
764 gcc_assert (gimple_call_num_args (stmt
) == 3);
765 tree ptr
= gimple_call_arg (stmt
, 0);
766 tree ckind
= gimple_call_arg (stmt
, 1);
767 tree align
= gimple_call_arg (stmt
, 2);
768 tree check_align
= NULL_TREE
;
771 basic_block cur_bb
= gsi_bb (gsi
);
774 if (!integer_zerop (align
))
776 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
777 if (compare_tree_int (align
, ptralign
) == 1)
779 check_align
= make_ssa_name (pointer_sized_int_node
);
780 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
781 gimple_set_location (g
, loc
);
782 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
785 check_null
= (flag_sanitize
& SANITIZE_NULL
) != 0;
787 if (check_align
== NULL_TREE
&& !check_null
)
789 gsi_remove (gsip
, true);
790 /* Unlink the UBSAN_NULLs vops before replacing it. */
791 unlink_stmt_vdef (stmt
);
795 /* Split the original block holding the pointer dereference. */
796 edge e
= split_block (cur_bb
, stmt
);
798 /* Get a hold on the 'condition block', the 'then block' and the
800 basic_block cond_bb
= e
->src
;
801 basic_block fallthru_bb
= e
->dest
;
802 basic_block then_bb
= create_empty_bb (cond_bb
);
803 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
804 loops_state_set (LOOPS_NEED_FIXUP
);
806 /* Make an edge coming from the 'cond block' into the 'then block';
807 this edge is unlikely taken, so set up the probability accordingly. */
808 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
809 e
->probability
= PROB_VERY_UNLIKELY
;
811 /* Connect 'then block' with the 'else block'. This is needed
812 as the ubsan routines we call in the 'then block' are not noreturn.
813 The 'then block' only has one outcoming edge. */
814 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
816 /* Set up the fallthrough basic block. */
817 e
= find_edge (cond_bb
, fallthru_bb
);
818 e
->flags
= EDGE_FALSE_VALUE
;
819 e
->count
= cond_bb
->count
;
820 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
822 /* Update dominance info for the newly created then_bb; note that
823 fallthru_bb's dominance info has already been updated by
825 if (dom_info_available_p (CDI_DOMINATORS
))
826 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
828 /* Put the ubsan builtin call into the newly created BB. */
829 if (flag_sanitize_undefined_trap_on_error
)
830 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
833 enum built_in_function bcode
834 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
835 | (check_null
? SANITIZE_NULL
: 0)))
836 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
837 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
838 tree fn
= builtin_decl_implicit (bcode
);
840 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
841 ubsan_type_descriptor (TREE_TYPE (ckind
),
842 UBSAN_PRINT_POINTER
),
845 fold_convert (unsigned_char_type_node
, ckind
),
847 data
= build_fold_addr_expr_loc (loc
, data
);
848 g
= gimple_build_call (fn
, 2, data
,
849 check_align
? check_align
850 : build_zero_cst (pointer_sized_int_node
));
852 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
853 gimple_set_location (g
, loc
);
854 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
856 /* Unlink the UBSAN_NULLs vops before replacing it. */
857 unlink_stmt_vdef (stmt
);
861 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
862 NULL_TREE
, NULL_TREE
);
863 gimple_set_location (g
, loc
);
865 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
866 gsi_replace (&gsi
, g
, false);
873 /* Split the block with the condition again. */
874 e
= split_block (cond_bb
, stmt
);
875 basic_block cond1_bb
= e
->src
;
876 basic_block cond2_bb
= e
->dest
;
878 /* Make an edge coming from the 'cond1 block' into the 'then block';
879 this edge is unlikely taken, so set up the probability
881 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
882 e
->probability
= PROB_VERY_UNLIKELY
;
884 /* Set up the fallthrough basic block. */
885 e
= find_edge (cond1_bb
, cond2_bb
);
886 e
->flags
= EDGE_FALSE_VALUE
;
887 e
->count
= cond1_bb
->count
;
888 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
890 /* Update dominance info. */
891 if (dom_info_available_p (CDI_DOMINATORS
))
893 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
894 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
897 gsi2
= gsi_start_bb (cond2_bb
);
900 tree mask
= build_int_cst (pointer_sized_int_node
,
901 tree_to_uhwi (align
) - 1);
902 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
903 BIT_AND_EXPR
, check_align
, mask
);
904 gimple_set_location (g
, loc
);
906 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
908 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
910 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
911 build_int_cst (pointer_sized_int_node
, 0),
912 NULL_TREE
, NULL_TREE
);
913 gimple_set_location (g
, loc
);
915 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
917 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
918 gsi_replace (&gsi
, g
, false);
923 #define OBJSZ_MAX_OFFSET (1024 * 16)
925 /* Expand UBSAN_OBJECT_SIZE internal call. */
928 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
930 gimple stmt
= gsi_stmt (*gsi
);
931 location_t loc
= gimple_location (stmt
);
932 gcc_assert (gimple_call_num_args (stmt
) == 4);
934 tree ptr
= gimple_call_arg (stmt
, 0);
935 tree offset
= gimple_call_arg (stmt
, 1);
936 tree size
= gimple_call_arg (stmt
, 2);
937 tree ckind
= gimple_call_arg (stmt
, 3);
938 gimple_stmt_iterator gsi_orig
= *gsi
;
941 /* See if we can discard the check. */
942 if (TREE_CODE (size
) != INTEGER_CST
943 || integer_all_onesp (size
))
944 /* Yes, __builtin_object_size couldn't determine the
946 else if (TREE_CODE (offset
) == INTEGER_CST
947 && wi::ges_p (wi::to_widest (offset
), -OBJSZ_MAX_OFFSET
)
948 && wi::les_p (wi::to_widest (offset
), -1))
949 /* The offset is in range [-16K, -1]. */;
952 /* if (offset > objsize) */
953 basic_block then_bb
, fallthru_bb
;
954 gimple_stmt_iterator cond_insert_point
955 = create_cond_insert_point (gsi
, false, false, true,
956 &then_bb
, &fallthru_bb
);
957 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
958 gimple_set_location (g
, loc
);
959 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
961 /* If the offset is small enough, we don't need the second
963 if (TREE_CODE (offset
) == INTEGER_CST
964 && wi::ges_p (wi::to_widest (offset
), 0)
965 && wi::les_p (wi::to_widest (offset
), OBJSZ_MAX_OFFSET
))
966 *gsi
= gsi_after_labels (then_bb
);
969 /* Don't issue run-time error if (ptr > ptr + offset). That
970 may happen when computing a POINTER_PLUS_EXPR. */
971 basic_block then2_bb
, fallthru2_bb
;
973 gimple_stmt_iterator gsi2
= gsi_after_labels (then_bb
);
974 cond_insert_point
= create_cond_insert_point (&gsi2
, false, false,
977 /* Convert the pointer to an integer type. */
978 tree p
= make_ssa_name (pointer_sized_int_node
);
979 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
980 gimple_set_location (g
, loc
);
981 gsi_insert_before (&cond_insert_point
, g
, GSI_NEW_STMT
);
982 p
= gimple_assign_lhs (g
);
983 /* Compute ptr + offset. */
984 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
985 PLUS_EXPR
, p
, offset
);
986 gimple_set_location (g
, loc
);
987 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
988 /* Now build the conditional and put it into the IR. */
989 g
= gimple_build_cond (LE_EXPR
, p
, gimple_assign_lhs (g
),
990 NULL_TREE
, NULL_TREE
);
991 gimple_set_location (g
, loc
);
992 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
993 *gsi
= gsi_after_labels (then2_bb
);
996 /* Generate __ubsan_handle_type_mismatch call. */
997 if (flag_sanitize_undefined_trap_on_error
)
998 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1002 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
1003 ubsan_type_descriptor (TREE_TYPE (ptr
),
1004 UBSAN_PRINT_POINTER
),
1006 build_zero_cst (pointer_sized_int_node
),
1009 data
= build_fold_addr_expr_loc (loc
, data
);
1010 enum built_in_function bcode
1011 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
1012 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1013 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
1014 tree p
= make_ssa_name (pointer_sized_int_node
);
1015 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
1016 gimple_set_location (g
, loc
);
1017 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1018 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
1020 gimple_set_location (g
, loc
);
1021 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1023 /* Point GSI to next logical statement. */
1024 *gsi
= gsi_start_bb (fallthru_bb
);
1027 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1028 unlink_stmt_vdef (stmt
);
1029 gsi_remove (&gsi_orig
, true);
1033 /* Cached __ubsan_vptr_type_cache decl. */
1034 static GTY(()) tree ubsan_vptr_type_cache_decl
;
1036 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1037 argument which is a constant, because the middle-end treats pointer
1038 conversions as useless and therefore the type of the first argument
1039 could be changed to any other pointer type. */
1042 ubsan_expand_vptr_ifn (gimple_stmt_iterator
*gsip
)
1044 gimple_stmt_iterator gsi
= *gsip
;
1045 gimple stmt
= gsi_stmt (gsi
);
1046 location_t loc
= gimple_location (stmt
);
1047 gcc_assert (gimple_call_num_args (stmt
) == 5);
1048 tree op
= gimple_call_arg (stmt
, 0);
1049 tree vptr
= gimple_call_arg (stmt
, 1);
1050 tree str_hash
= gimple_call_arg (stmt
, 2);
1051 tree ti_decl_addr
= gimple_call_arg (stmt
, 3);
1052 tree ckind_tree
= gimple_call_arg (stmt
, 4);
1053 ubsan_null_ckind ckind
= (ubsan_null_ckind
) tree_to_uhwi (ckind_tree
);
1054 tree type
= TREE_TYPE (TREE_TYPE (ckind_tree
));
1056 basic_block fallthru_bb
= NULL
;
1058 if (ckind
== UBSAN_DOWNCAST_POINTER
)
1060 /* Guard everything with if (op != NULL) { ... }. */
1061 basic_block then_bb
;
1062 gimple_stmt_iterator cond_insert_point
1063 = create_cond_insert_point (gsip
, false, false, true,
1064 &then_bb
, &fallthru_bb
);
1065 g
= gimple_build_cond (NE_EXPR
, op
, build_zero_cst (TREE_TYPE (op
)),
1066 NULL_TREE
, NULL_TREE
);
1067 gimple_set_location (g
, loc
);
1068 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1069 *gsip
= gsi_after_labels (then_bb
);
1070 gsi_remove (&gsi
, false);
1071 gsi_insert_before (gsip
, stmt
, GSI_NEW_STMT
);
1075 tree htype
= TREE_TYPE (str_hash
);
1076 tree cst
= wide_int_to_tree (htype
,
1077 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1079 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1081 gimple_set_location (g
, loc
);
1082 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1083 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1084 gimple_assign_lhs (g
), cst
);
1085 gimple_set_location (g
, loc
);
1086 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1087 tree t1
= gimple_assign_lhs (g
);
1088 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1089 t1
, build_int_cst (integer_type_node
, 47));
1090 gimple_set_location (g
, loc
);
1091 tree t2
= gimple_assign_lhs (g
);
1092 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1093 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1095 gimple_set_location (g
, loc
);
1096 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1097 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1098 t2
, gimple_assign_lhs (g
));
1099 gimple_set_location (g
, loc
);
1100 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1101 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1102 gimple_assign_lhs (g
), cst
);
1103 gimple_set_location (g
, loc
);
1104 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1105 tree t3
= gimple_assign_lhs (g
);
1106 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1107 t3
, build_int_cst (integer_type_node
, 47));
1108 gimple_set_location (g
, loc
);
1109 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1110 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1111 t3
, gimple_assign_lhs (g
));
1112 gimple_set_location (g
, loc
);
1113 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1114 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1115 gimple_assign_lhs (g
), cst
);
1116 gimple_set_location (g
, loc
);
1117 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1118 if (!useless_type_conversion_p (pointer_sized_int_node
, htype
))
1120 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1121 NOP_EXPR
, gimple_assign_lhs (g
));
1122 gimple_set_location (g
, loc
);
1123 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1125 tree hash
= gimple_assign_lhs (g
);
1127 if (ubsan_vptr_type_cache_decl
== NULL_TREE
)
1129 tree atype
= build_array_type_nelts (pointer_sized_int_node
, 128);
1130 tree array
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1131 get_identifier ("__ubsan_vptr_type_cache"),
1133 DECL_ARTIFICIAL (array
) = 1;
1134 DECL_IGNORED_P (array
) = 1;
1135 TREE_PUBLIC (array
) = 1;
1136 TREE_STATIC (array
) = 1;
1137 DECL_EXTERNAL (array
) = 1;
1138 DECL_VISIBILITY (array
) = VISIBILITY_DEFAULT
;
1139 DECL_VISIBILITY_SPECIFIED (array
) = 1;
1140 varpool_node::finalize_decl (array
);
1141 ubsan_vptr_type_cache_decl
= array
;
1144 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1146 build_int_cst (pointer_sized_int_node
, 127));
1147 gimple_set_location (g
, loc
);
1148 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1150 tree c
= build4_loc (loc
, ARRAY_REF
, pointer_sized_int_node
,
1151 ubsan_vptr_type_cache_decl
, gimple_assign_lhs (g
),
1152 NULL_TREE
, NULL_TREE
);
1153 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1155 gimple_set_location (g
, loc
);
1156 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1158 basic_block then_bb
, fallthru2_bb
;
1159 gimple_stmt_iterator cond_insert_point
1160 = create_cond_insert_point (gsip
, false, false, true,
1161 &then_bb
, &fallthru2_bb
);
1162 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
), hash
,
1163 NULL_TREE
, NULL_TREE
);
1164 gimple_set_location (g
, loc
);
1165 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1166 *gsip
= gsi_after_labels (then_bb
);
1167 if (fallthru_bb
== NULL
)
1168 fallthru_bb
= fallthru2_bb
;
1171 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc
,
1172 ubsan_type_descriptor (type
), NULL_TREE
, ti_decl_addr
,
1173 build_int_cst (unsigned_char_type_node
, ckind
),
1175 data
= build_fold_addr_expr_loc (loc
, data
);
1176 enum built_in_function bcode
1177 = (flag_sanitize_recover
& SANITIZE_VPTR
)
1178 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1179 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT
;
1181 g
= gimple_build_call (builtin_decl_explicit (bcode
), 3, data
, op
, hash
);
1182 gimple_set_location (g
, loc
);
1183 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1185 /* Point GSI to next logical statement. */
1186 *gsip
= gsi_start_bb (fallthru_bb
);
1188 /* Get rid of the UBSAN_VPTR call from the IR. */
1189 unlink_stmt_vdef (stmt
);
1190 gsi_remove (&gsi
, true);
1194 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1195 whether the pointer is on the left hand side of the assignment. */
1198 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
1201 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
1202 unsigned int align
= 0;
1203 if (flag_sanitize
& SANITIZE_ALIGNMENT
)
1205 align
= min_align_of_type (TREE_TYPE (base
));
1209 if (align
== 0 && (flag_sanitize
& SANITIZE_NULL
) == 0)
1211 tree t
= TREE_OPERAND (base
, 0);
1212 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
1214 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t
))) && mem
!= base
)
1215 ikind
= UBSAN_MEMBER_ACCESS
;
1216 tree kind
= build_int_cst (TREE_TYPE (t
), ikind
);
1217 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
1218 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
1219 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
1220 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
1223 /* Perform the pointer instrumentation. */
1226 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
1228 gimple stmt
= gsi_stmt (gsi
);
1229 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1230 tree base
= get_base_address (t
);
1231 const enum tree_code code
= TREE_CODE (base
);
1233 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1234 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1237 /* Build an ubsan builtin call for the signed-integer-overflow
1238 sanitization. CODE says what kind of builtin are we building,
1239 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1240 are operands of the binary operation. */
1243 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1246 if (flag_sanitize_undefined_trap_on_error
)
1247 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1249 tree data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1250 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1252 enum built_in_function fn_code
;
1257 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1258 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1259 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1262 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1263 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1264 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1267 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1268 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1269 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1272 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1273 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1274 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1279 tree fn
= builtin_decl_explicit (fn_code
);
1280 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1281 build_fold_addr_expr_loc (loc
, data
),
1282 ubsan_encode_value (op0
, true),
1283 op1
? ubsan_encode_value (op1
, true)
1287 /* Perform the signed integer instrumentation. GSI is the iterator
1288 pointing at statement we are trying to instrument. */
1291 instrument_si_overflow (gimple_stmt_iterator gsi
)
1293 gimple stmt
= gsi_stmt (gsi
);
1294 tree_code code
= gimple_assign_rhs_code (stmt
);
1295 tree lhs
= gimple_assign_lhs (stmt
);
1296 tree lhstype
= TREE_TYPE (lhs
);
1300 /* If this is not a signed operation, don't instrument anything here.
1301 Also punt on bit-fields. */
1302 if (!INTEGRAL_TYPE_P (lhstype
)
1303 || TYPE_OVERFLOW_WRAPS (lhstype
)
1304 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
1315 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1316 a
= gimple_assign_rhs1 (stmt
);
1317 b
= gimple_assign_rhs2 (stmt
);
1318 g
= gimple_build_call_internal (code
== PLUS_EXPR
1319 ? IFN_UBSAN_CHECK_ADD
1320 : code
== MINUS_EXPR
1321 ? IFN_UBSAN_CHECK_SUB
1322 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1323 gimple_call_set_lhs (g
, lhs
);
1324 gsi_replace (&gsi
, g
, false);
1327 /* Represent i = -u;
1329 i = UBSAN_CHECK_SUB (0, u); */
1330 a
= build_int_cst (lhstype
, 0);
1331 b
= gimple_assign_rhs1 (stmt
);
1332 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1333 gimple_call_set_lhs (g
, lhs
);
1334 gsi_replace (&gsi
, g
, false);
1337 /* Transform i = ABS_EXPR<u>;
1339 _N = UBSAN_CHECK_SUB (0, u);
1340 i = ABS_EXPR<_N>; */
1341 a
= build_int_cst (lhstype
, 0);
1342 b
= gimple_assign_rhs1 (stmt
);
1343 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1344 a
= make_ssa_name (lhstype
);
1345 gimple_call_set_lhs (g
, a
);
1346 gimple_set_location (g
, gimple_location (stmt
));
1347 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1348 gimple_assign_set_rhs1 (stmt
, a
);
1356 /* Instrument loads from (non-bitfield) bool and C++ enum values
1357 to check if the memory value is outside of the range of the valid
1361 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1363 gimple stmt
= gsi_stmt (*gsi
);
1364 tree rhs
= gimple_assign_rhs1 (stmt
);
1365 tree type
= TREE_TYPE (rhs
);
1366 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1368 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
1370 minv
= boolean_false_node
;
1371 maxv
= boolean_true_node
;
1373 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1374 && (flag_sanitize
& SANITIZE_ENUM
)
1375 && TREE_TYPE (type
) != NULL_TREE
1376 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1377 && (TYPE_PRECISION (TREE_TYPE (type
))
1378 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1380 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1381 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1386 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1387 HOST_WIDE_INT bitsize
, bitpos
;
1390 int volatilep
= 0, unsignedp
= 0;
1391 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1392 &unsignedp
, &volatilep
, false);
1393 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1395 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
1396 || (bitpos
% modebitsize
) != 0
1397 || bitsize
!= modebitsize
1398 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1399 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1402 bool can_throw
= stmt_could_throw_p (stmt
);
1403 location_t loc
= gimple_location (stmt
);
1404 tree lhs
= gimple_assign_lhs (stmt
);
1405 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1406 tree atype
= reference_alias_ptr_type (rhs
);
1407 gimple g
= gimple_build_assign (make_ssa_name (ptype
),
1408 build_fold_addr_expr (rhs
));
1409 gimple_set_location (g
, loc
);
1410 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1411 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1412 build_int_cst (atype
, 0));
1413 tree urhs
= make_ssa_name (utype
);
1416 gimple_assign_set_lhs (stmt
, urhs
);
1417 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1418 gimple_set_location (g
, loc
);
1419 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1420 gsi_insert_on_edge_immediate (e
, g
);
1421 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1423 *gsi
= gsi_for_stmt (g
);
1428 g
= gimple_build_assign (urhs
, mem
);
1429 gimple_set_location (g
, loc
);
1430 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1432 minv
= fold_convert (utype
, minv
);
1433 maxv
= fold_convert (utype
, maxv
);
1434 if (!integer_zerop (minv
))
1436 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1437 gimple_set_location (g
, loc
);
1438 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1441 gimple_stmt_iterator gsi2
= *gsi
;
1442 basic_block then_bb
, fallthru_bb
;
1443 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1444 &then_bb
, &fallthru_bb
);
1445 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1446 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1447 NULL_TREE
, NULL_TREE
);
1448 gimple_set_location (g
, loc
);
1449 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1453 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1457 gsi2
= gsi_after_labels (then_bb
);
1458 if (flag_sanitize_undefined_trap_on_error
)
1459 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1462 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1463 ubsan_type_descriptor (type
), NULL_TREE
,
1465 data
= build_fold_addr_expr_loc (loc
, data
);
1466 enum built_in_function bcode
1467 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1468 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1469 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1470 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1471 tree fn
= builtin_decl_explicit (bcode
);
1473 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
1474 true, NULL_TREE
, true,
1476 g
= gimple_build_call (fn
, 2, data
, val
);
1478 gimple_set_location (g
, loc
);
1479 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1480 *gsi
= gsi_for_stmt (stmt
);
1483 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1484 destination, EXPR is floating-point expression. ARG is what to pass
1485 the libubsan call as value, often EXPR itself. */
1488 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
, tree arg
)
1490 tree expr_type
= TREE_TYPE (expr
);
1491 tree t
, tt
, fn
, min
, max
;
1492 machine_mode mode
= TYPE_MODE (expr_type
);
1493 int prec
= TYPE_PRECISION (type
);
1494 bool uns_p
= TYPE_UNSIGNED (type
);
1496 /* Float to integer conversion first truncates toward zero, so
1497 even signed char c = 127.875f; is not problematic.
1498 Therefore, we should complain only if EXPR is unordered or smaller
1499 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1500 TYPE_MAX_VALUE + 1.0. */
1501 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1503 /* For maximum, TYPE_MAX_VALUE might not be representable
1504 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1505 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1506 either representable or infinity. */
1507 REAL_VALUE_TYPE maxval
= dconst1
;
1508 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1509 real_convert (&maxval
, mode
, &maxval
);
1510 max
= build_real (expr_type
, maxval
);
1512 /* For unsigned, assume -1.0 is always representable. */
1514 min
= build_minus_one_cst (expr_type
);
1517 /* TYPE_MIN_VALUE is generally representable (or -inf),
1518 but TYPE_MIN_VALUE - 1.0 might not be. */
1519 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1520 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1521 real_convert (&minval
, mode
, &minval
);
1522 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1523 real_convert (&minval2
, mode
, &minval2
);
1524 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1525 && !real_isinf (&minval
))
1527 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1528 rounds to TYPE_MIN_VALUE, we need to subtract
1529 more. As REAL_MODE_FORMAT (mode)->p is the number
1530 of base digits, we want to subtract a number that
1531 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1532 times smaller than minval. */
1534 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1535 SET_REAL_EXP (&minval2
,
1536 REAL_EXP (&minval2
) + prec
- 1
1537 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1538 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1539 real_convert (&minval2
, mode
, &minval2
);
1541 min
= build_real (expr_type
, minval2
);
1544 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1546 /* For _Decimal128 up to 34 decimal digits, - sign,
1547 dot, e, exponent. */
1550 int p
= REAL_MODE_FORMAT (mode
)->p
;
1551 REAL_VALUE_TYPE maxval
, minval
;
1553 /* Use mpfr_snprintf rounding to compute the smallest
1554 representable decimal number greater or equal than
1555 1 << (prec - !uns_p). */
1556 mpfr_init2 (m
, prec
+ 2);
1557 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1558 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1559 decimal_real_from_string (&maxval
, buf
);
1560 max
= build_real (expr_type
, maxval
);
1562 /* For unsigned, assume -1.0 is always representable. */
1564 min
= build_minus_one_cst (expr_type
);
1567 /* Use mpfr_snprintf rounding to compute the largest
1568 representable decimal number less or equal than
1569 (-1 << (prec - 1)) - 1. */
1570 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1571 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1572 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1573 decimal_real_from_string (&minval
, buf
);
1574 min
= build_real (expr_type
, minval
);
1581 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1582 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1583 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
);
1584 if (integer_zerop (t
))
1587 if (flag_sanitize_undefined_trap_on_error
)
1588 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1591 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1592 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1593 NULL
, ubsan_type_descriptor (expr_type
),
1594 ubsan_type_descriptor (type
), NULL_TREE
,
1596 enum built_in_function bcode
1597 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1598 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1599 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1600 fn
= builtin_decl_explicit (bcode
);
1601 fn
= build_call_expr_loc (loc
, fn
, 2,
1602 build_fold_addr_expr_loc (loc
, data
),
1603 ubsan_encode_value (arg
, false));
1606 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1609 /* Instrument values passed to function arguments with nonnull attribute. */
1612 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1614 gimple stmt
= gsi_stmt (*gsi
);
1616 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1617 while for nonnull sanitization it is clear. */
1618 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1619 flag_delete_null_pointer_checks
= 1;
1620 loc
[0] = gimple_location (stmt
);
1621 loc
[1] = UNKNOWN_LOCATION
;
1622 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1624 tree arg
= gimple_call_arg (stmt
, i
);
1625 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1626 && infer_nonnull_range (stmt
, arg
, false, true))
1629 if (!is_gimple_val (arg
))
1631 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1632 gimple_set_location (g
, loc
[0]);
1633 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1634 arg
= gimple_assign_lhs (g
);
1637 basic_block then_bb
, fallthru_bb
;
1638 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1639 &then_bb
, &fallthru_bb
);
1640 g
= gimple_build_cond (EQ_EXPR
, arg
,
1641 build_zero_cst (TREE_TYPE (arg
)),
1642 NULL_TREE
, NULL_TREE
);
1643 gimple_set_location (g
, loc
[0]);
1644 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1646 *gsi
= gsi_after_labels (then_bb
);
1647 if (flag_sanitize_undefined_trap_on_error
)
1648 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1651 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1653 build_int_cst (integer_type_node
,
1656 data
= build_fold_addr_expr_loc (loc
[0], data
);
1657 enum built_in_function bcode
1658 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1659 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1660 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1661 tree fn
= builtin_decl_explicit (bcode
);
1663 g
= gimple_build_call (fn
, 1, data
);
1665 gimple_set_location (g
, loc
[0]);
1666 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1668 *gsi
= gsi_for_stmt (stmt
);
1670 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1673 /* Instrument returns in functions with returns_nonnull attribute. */
1676 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1678 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
1680 tree arg
= gimple_return_retval (stmt
);
1681 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1682 while for nonnull return sanitization it is clear. */
1683 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1684 flag_delete_null_pointer_checks
= 1;
1685 loc
[0] = gimple_location (stmt
);
1686 loc
[1] = UNKNOWN_LOCATION
;
1688 && POINTER_TYPE_P (TREE_TYPE (arg
))
1689 && is_gimple_val (arg
)
1690 && infer_nonnull_range (stmt
, arg
, false, true))
1692 basic_block then_bb
, fallthru_bb
;
1693 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1694 &then_bb
, &fallthru_bb
);
1695 gimple g
= gimple_build_cond (EQ_EXPR
, arg
,
1696 build_zero_cst (TREE_TYPE (arg
)),
1697 NULL_TREE
, NULL_TREE
);
1698 gimple_set_location (g
, loc
[0]);
1699 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1701 *gsi
= gsi_after_labels (then_bb
);
1702 if (flag_sanitize_undefined_trap_on_error
)
1703 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1706 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
1707 2, loc
, NULL_TREE
, NULL_TREE
);
1708 data
= build_fold_addr_expr_loc (loc
[0], data
);
1709 enum built_in_function bcode
1710 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1711 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1712 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
1713 tree fn
= builtin_decl_explicit (bcode
);
1715 g
= gimple_build_call (fn
, 1, data
);
1717 gimple_set_location (g
, loc
[0]);
1718 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1719 *gsi
= gsi_for_stmt (stmt
);
1721 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1724 /* Instrument memory references. Here we check whether the pointer
1725 points to an out-of-bounds location. */
1728 instrument_object_size (gimple_stmt_iterator
*gsi
, bool is_lhs
)
1730 gimple stmt
= gsi_stmt (*gsi
);
1731 location_t loc
= gimple_location (stmt
);
1732 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1734 tree index
= NULL_TREE
;
1735 HOST_WIDE_INT size_in_bytes
;
1737 type
= TREE_TYPE (t
);
1738 if (VOID_TYPE_P (type
))
1741 switch (TREE_CODE (t
))
1744 if (TREE_CODE (t
) == COMPONENT_REF
1745 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
1747 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
1748 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
1753 index
= TREE_OPERAND (t
, 1);
1765 size_in_bytes
= int_size_in_bytes (type
);
1766 if (size_in_bytes
<= 0)
1769 HOST_WIDE_INT bitsize
, bitpos
;
1772 int volatilep
= 0, unsignedp
= 0;
1773 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1774 &unsignedp
, &volatilep
, false);
1776 if (bitpos
% BITS_PER_UNIT
!= 0
1777 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
1780 bool decl_p
= DECL_P (inner
);
1784 else if (TREE_CODE (inner
) == MEM_REF
)
1785 base
= TREE_OPERAND (inner
, 0);
1788 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
1790 while (TREE_CODE (base
) == SSA_NAME
)
1792 gimple def_stmt
= SSA_NAME_DEF_STMT (base
);
1793 if (gimple_assign_ssa_name_copy_p (def_stmt
)
1794 || (gimple_assign_cast_p (def_stmt
)
1795 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
1796 || (is_gimple_assign (def_stmt
)
1797 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
1799 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
1800 if (TREE_CODE (rhs1
) == SSA_NAME
1801 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
1810 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1814 tree base_addr
= base
;
1816 base_addr
= build1 (ADDR_EXPR
,
1817 build_pointer_type (TREE_TYPE (base
)), base
);
1818 unsigned HOST_WIDE_INT size
= compute_builtin_object_size (base_addr
, 0);
1819 if (size
!= (unsigned HOST_WIDE_INT
) -1)
1820 sizet
= build_int_cst (sizetype
, size
);
1823 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
1824 loc
= input_location
;
1825 /* Generate __builtin_object_size call. */
1826 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
1827 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
1829 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
1835 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1837 /* ptr + sizeof (*ptr) - base */
1838 t
= fold_build2 (MINUS_EXPR
, sizetype
,
1839 fold_convert (pointer_sized_int_node
, ptr
),
1840 fold_convert (pointer_sized_int_node
, base_addr
));
1841 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
1843 /* Perhaps we can omit the check. */
1844 if (TREE_CODE (t
) == INTEGER_CST
1845 && TREE_CODE (sizet
) == INTEGER_CST
1846 && tree_int_cst_le (t
, sizet
))
1849 if (index
!= NULL_TREE
1850 && TREE_CODE (index
) == SSA_NAME
1851 && TREE_CODE (sizet
) == INTEGER_CST
)
1853 gimple def
= SSA_NAME_DEF_STMT (index
);
1854 if (is_gimple_assign (def
)
1855 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
1856 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
1858 tree cst
= gimple_assign_rhs2 (def
);
1859 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
1860 TYPE_SIZE_UNIT (type
));
1861 if (tree_int_cst_sgn (cst
) >= 0
1862 && tree_int_cst_lt (cst
, sz
))
1867 /* Nope. Emit the check. */
1868 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1870 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
1872 tree ckind
= build_int_cst (unsigned_char_type_node
,
1873 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
1874 gimple g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
1875 ptr
, t
, sizet
, ckind
);
1876 gimple_set_location (g
, loc
);
1877 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1880 /* True if we want to play UBSan games in the current function. */
1883 do_ubsan_in_current_function ()
1885 return (current_function_decl
!= NULL_TREE
1886 && !lookup_attribute ("no_sanitize_undefined",
1887 DECL_ATTRIBUTES (current_function_decl
)));
1892 const pass_data pass_data_ubsan
=
1894 GIMPLE_PASS
, /* type */
1896 OPTGROUP_NONE
, /* optinfo_flags */
1897 TV_TREE_UBSAN
, /* tv_id */
1898 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1899 0, /* properties_provided */
1900 0, /* properties_destroyed */
1901 0, /* todo_flags_start */
1902 TODO_update_ssa
, /* todo_flags_finish */
1905 class pass_ubsan
: public gimple_opt_pass
1908 pass_ubsan (gcc::context
*ctxt
)
1909 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1912 /* opt_pass methods: */
1913 virtual bool gate (function
*)
1915 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1916 | SANITIZE_BOOL
| SANITIZE_ENUM
1917 | SANITIZE_ALIGNMENT
1918 | SANITIZE_NONNULL_ATTRIBUTE
1919 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1920 | SANITIZE_OBJECT_SIZE
)
1921 && do_ubsan_in_current_function ();
1924 virtual unsigned int execute (function
*);
1926 }; // class pass_ubsan
1929 pass_ubsan::execute (function
*fun
)
1932 gimple_stmt_iterator gsi
;
1934 initialize_sanitizer_builtins ();
1936 FOR_EACH_BB_FN (bb
, fun
)
1938 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1940 gimple stmt
= gsi_stmt (gsi
);
1941 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
1947 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
1948 && is_gimple_assign (stmt
))
1949 instrument_si_overflow (gsi
);
1951 if (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1953 if (gimple_store_p (stmt
))
1954 instrument_null (gsi
, true);
1955 if (gimple_assign_load_p (stmt
))
1956 instrument_null (gsi
, false);
1959 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
1960 && gimple_assign_load_p (stmt
))
1962 instrument_bool_enum_load (&gsi
);
1963 bb
= gimple_bb (stmt
);
1966 if ((flag_sanitize
& SANITIZE_NONNULL_ATTRIBUTE
)
1967 && is_gimple_call (stmt
)
1968 && !gimple_call_internal_p (stmt
))
1970 instrument_nonnull_arg (&gsi
);
1971 bb
= gimple_bb (stmt
);
1974 if ((flag_sanitize
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1975 && gimple_code (stmt
) == GIMPLE_RETURN
)
1977 instrument_nonnull_return (&gsi
);
1978 bb
= gimple_bb (stmt
);
1981 if (flag_sanitize
& SANITIZE_OBJECT_SIZE
)
1983 if (gimple_store_p (stmt
))
1984 instrument_object_size (&gsi
, true);
1985 if (gimple_assign_load_p (stmt
))
1986 instrument_object_size (&gsi
, false);
1998 make_pass_ubsan (gcc::context
*ctxt
)
2000 return new pass_ubsan (ctxt
);
2003 #include "gt-ubsan.h"