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"
28 #include "fold-const.h"
29 #include "stor-layout.h"
30 #include "stringpool.h"
32 #include "dominance.h"
35 #include "basic-block.h"
37 #include "hard-reg-set.h"
40 #include "tree-pass.h"
41 #include "tree-ssa-alias.h"
42 #include "tree-pretty-print.h"
43 #include "internal-fn.h"
44 #include "gimple-expr.h"
46 #include "gimple-iterator.h"
47 #include "gimple-ssa.h"
48 #include "gimple-walk.h"
54 #include "c-family/c-common.h"
57 #include "insn-config.h"
66 #include "tree-ssanames.h"
68 #include "gimplify-me.h"
73 #include "tree-object-size.h"
77 /* Map from a tree to a VAR_DECL tree. */
79 struct GTY((for_user
)) tree_type_map
{
80 struct tree_map_base type
;
84 struct tree_type_map_cache_hasher
: ggc_cache_ptr_hash
<tree_type_map
>
86 static inline hashval_t
87 hash (tree_type_map
*t
)
89 return TYPE_UID (t
->type
.from
);
93 equal (tree_type_map
*a
, tree_type_map
*b
)
95 return a
->type
.from
== b
->type
.from
;
99 keep_cache_entry (tree_type_map
*&m
)
101 return ggc_marked_p (m
->type
.from
);
106 hash_table
<tree_type_map_cache_hasher
> *decl_tree_for_type
;
108 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
111 decl_for_type_lookup (tree type
)
113 /* If the hash table is not initialized yet, create it now. */
114 if (decl_tree_for_type
== NULL
)
117 = hash_table
<tree_type_map_cache_hasher
>::create_ggc (10);
118 /* That also means we don't have to bother with the lookup. */
122 struct tree_type_map
*h
, in
;
125 h
= decl_tree_for_type
->find_with_hash (&in
, TYPE_UID (type
));
126 return h
? h
->decl
: NULL_TREE
;
129 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
132 decl_for_type_insert (tree type
, tree decl
)
134 struct tree_type_map
*h
;
136 h
= ggc_alloc
<tree_type_map
> ();
139 *decl_tree_for_type
->find_slot_with_hash (h
, TYPE_UID (type
), INSERT
) = h
;
142 /* Helper routine, which encodes a value in the pointer_sized_int_node.
143 Arguments with precision <= POINTER_SIZE are passed directly,
144 the rest is passed by reference. T is a value we are to encode.
145 IN_EXPAND_P is true if this function is called during expansion. */
148 ubsan_encode_value (tree t
, bool in_expand_p
)
150 tree type
= TREE_TYPE (t
);
151 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
152 if (bitsize
<= POINTER_SIZE
)
153 switch (TREE_CODE (type
))
158 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
161 tree itype
= build_nonstandard_integer_type (bitsize
, true);
162 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
163 return fold_convert (pointer_sized_int_node
, t
);
170 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
172 /* The reason for this is that we don't want to pessimize
173 code by making vars unnecessarily addressable. */
174 tree var
= create_tmp_var (type
);
175 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
179 = assign_stack_temp_for_type (TYPE_MODE (type
),
180 GET_MODE_SIZE (TYPE_MODE (type
)),
182 SET_DECL_RTL (var
, mem
);
183 expand_assignment (var
, t
, false);
184 return build_fold_addr_expr (var
);
186 t
= build_fold_addr_expr (var
);
187 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
190 return build_fold_addr_expr (t
);
194 /* Cached ubsan_get_type_descriptor_type () return value. */
195 static GTY(()) tree ubsan_type_descriptor_type
;
198 struct __ubsan_type_descriptor
200 unsigned short __typekind;
201 unsigned short __typeinfo;
207 ubsan_get_type_descriptor_type (void)
209 static const char *field_names
[3]
210 = { "__typekind", "__typeinfo", "__typename" };
213 if (ubsan_type_descriptor_type
)
214 return ubsan_type_descriptor_type
;
216 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
217 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
219 ret
= make_node (RECORD_TYPE
);
220 for (int i
= 0; i
< 3; i
++)
222 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
223 get_identifier (field_names
[i
]),
224 (i
== 2) ? flex_arr_type
225 : short_unsigned_type_node
);
226 DECL_CONTEXT (fields
[i
]) = ret
;
228 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
230 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
231 get_identifier ("__ubsan_type_descriptor"),
233 DECL_IGNORED_P (type_decl
) = 1;
234 DECL_ARTIFICIAL (type_decl
) = 1;
235 TYPE_FIELDS (ret
) = fields
[0];
236 TYPE_NAME (ret
) = type_decl
;
237 TYPE_STUB_DECL (ret
) = type_decl
;
239 ubsan_type_descriptor_type
= ret
;
243 /* Cached ubsan_get_source_location_type () return value. */
244 static GTY(()) tree ubsan_source_location_type
;
247 struct __ubsan_source_location
249 const char *__filename;
251 unsigned int __column;
256 ubsan_get_source_location_type (void)
258 static const char *field_names
[3]
259 = { "__filename", "__line", "__column" };
261 if (ubsan_source_location_type
)
262 return ubsan_source_location_type
;
264 tree const_char_type
= build_qualified_type (char_type_node
,
267 ret
= make_node (RECORD_TYPE
);
268 for (int i
= 0; i
< 3; i
++)
270 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
271 get_identifier (field_names
[i
]),
272 (i
== 0) ? build_pointer_type (const_char_type
)
273 : unsigned_type_node
);
274 DECL_CONTEXT (fields
[i
]) = ret
;
276 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
278 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
279 get_identifier ("__ubsan_source_location"),
281 DECL_IGNORED_P (type_decl
) = 1;
282 DECL_ARTIFICIAL (type_decl
) = 1;
283 TYPE_FIELDS (ret
) = fields
[0];
284 TYPE_NAME (ret
) = type_decl
;
285 TYPE_STUB_DECL (ret
) = type_decl
;
287 ubsan_source_location_type
= ret
;
291 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
292 type with its fields filled from a location_t LOC. */
295 ubsan_source_location (location_t loc
)
297 expanded_location xloc
;
298 tree type
= ubsan_get_source_location_type ();
300 xloc
= expand_location (loc
);
302 if (xloc
.file
== NULL
)
304 str
= build_int_cst (ptr_type_node
, 0);
310 /* Fill in the values from LOC. */
311 size_t len
= strlen (xloc
.file
) + 1;
312 str
= build_string (len
, xloc
.file
);
313 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
314 TREE_READONLY (str
) = 1;
315 TREE_STATIC (str
) = 1;
316 str
= build_fold_addr_expr (str
);
318 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
319 build_int_cst (unsigned_type_node
,
320 xloc
.line
), NULL_TREE
,
321 build_int_cst (unsigned_type_node
,
323 TREE_CONSTANT (ctor
) = 1;
324 TREE_STATIC (ctor
) = 1;
329 /* This routine returns a magic number for TYPE. */
331 static unsigned short
332 get_ubsan_type_info_for_type (tree type
)
334 gcc_assert (TYPE_SIZE (type
) && tree_fits_uhwi_p (TYPE_SIZE (type
)));
335 if (TREE_CODE (type
) == REAL_TYPE
)
336 return tree_to_uhwi (TYPE_SIZE (type
));
337 else if (INTEGRAL_TYPE_P (type
))
339 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
340 gcc_assert (prec
!= -1);
341 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
347 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
348 descriptor. It first looks into the hash table; if not found,
349 create the VAR_DECL, put it into the hash table and return the
350 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
351 an enum controlling how we want to print the type. */
354 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
356 /* See through any typedefs. */
357 type
= TYPE_MAIN_VARIANT (type
);
359 tree decl
= decl_for_type_lookup (type
);
360 /* It is possible that some of the earlier created DECLs were found
361 unused, in that case they weren't emitted and varpool_node::get
362 returns NULL node on them. But now we really need them. Thus,
364 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
365 return build_fold_addr_expr (decl
);
367 tree dtype
= ubsan_get_type_descriptor_type ();
369 const char *tname
= NULL
;
370 pretty_printer pretty_name
;
371 unsigned char deref_depth
= 0;
372 unsigned short tkind
, tinfo
;
374 /* Get the name of the type, or the name of the pointer type. */
375 if (pstyle
== UBSAN_PRINT_POINTER
)
377 gcc_assert (POINTER_TYPE_P (type
));
378 type2
= TREE_TYPE (type
);
380 /* Remove any '*' operators from TYPE. */
381 while (POINTER_TYPE_P (type2
))
382 deref_depth
++, type2
= TREE_TYPE (type2
);
384 if (TREE_CODE (type2
) == METHOD_TYPE
)
385 type2
= TYPE_METHOD_BASETYPE (type2
);
388 /* If an array, get its type. */
389 type2
= strip_array_types (type2
);
391 if (pstyle
== UBSAN_PRINT_ARRAY
)
393 while (POINTER_TYPE_P (type2
))
394 deref_depth
++, type2
= TREE_TYPE (type2
);
397 if (TYPE_NAME (type2
) != NULL
)
399 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
400 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
401 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
402 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
406 /* We weren't able to determine the type name. */
409 if (pstyle
== UBSAN_PRINT_POINTER
)
411 pp_printf (&pretty_name
, "'%s%s%s%s%s%s%s",
412 TYPE_VOLATILE (type2
) ? "volatile " : "",
413 TYPE_READONLY (type2
) ? "const " : "",
414 TYPE_RESTRICT (type2
) ? "restrict " : "",
415 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
416 TREE_CODE (type2
) == RECORD_TYPE
418 : TREE_CODE (type2
) == UNION_TYPE
419 ? "union " : "", tname
,
420 deref_depth
== 0 ? "" : " ");
421 while (deref_depth
-- > 0)
422 pp_star (&pretty_name
);
423 pp_quote (&pretty_name
);
425 else if (pstyle
== UBSAN_PRINT_ARRAY
)
427 /* Pretty print the array dimensions. */
428 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
430 pp_printf (&pretty_name
, "'%s ", tname
);
431 while (deref_depth
-- > 0)
432 pp_star (&pretty_name
);
433 while (TREE_CODE (t
) == ARRAY_TYPE
)
435 pp_left_bracket (&pretty_name
);
436 tree dom
= TYPE_DOMAIN (t
);
437 if (dom
&& TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
439 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom
))
440 && tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1 != 0)
441 pp_printf (&pretty_name
, HOST_WIDE_INT_PRINT_DEC
,
442 tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1);
444 pp_wide_int (&pretty_name
,
445 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom
)), 1),
446 TYPE_SIGN (TREE_TYPE (dom
)));
449 /* ??? We can't determine the variable name; print VLA unspec. */
450 pp_star (&pretty_name
);
451 pp_right_bracket (&pretty_name
);
454 pp_quote (&pretty_name
);
456 /* Save the tree with stripped types. */
460 pp_printf (&pretty_name
, "'%s'", tname
);
462 switch (TREE_CODE (type
))
470 /* FIXME: libubsan right now only supports float, double and
471 long double type formats. */
472 if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
)
473 || TYPE_MODE (type
) == TYPE_MODE (double_type_node
)
474 || TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
483 tinfo
= get_ubsan_type_info_for_type (type
);
485 /* Create a new VAR_DECL of type descriptor. */
486 const char *tmp
= pp_formatted_text (&pretty_name
);
487 size_t len
= strlen (tmp
) + 1;
488 tree str
= build_string (len
, tmp
);
489 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
490 TREE_READONLY (str
) = 1;
491 TREE_STATIC (str
) = 1;
494 static unsigned int type_var_id_num
;
495 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
496 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
498 TREE_STATIC (decl
) = 1;
499 TREE_PUBLIC (decl
) = 0;
500 DECL_ARTIFICIAL (decl
) = 1;
501 DECL_IGNORED_P (decl
) = 1;
502 DECL_EXTERNAL (decl
) = 0;
504 = size_binop (PLUS_EXPR
, DECL_SIZE (decl
), TYPE_SIZE (TREE_TYPE (str
)));
505 DECL_SIZE_UNIT (decl
)
506 = size_binop (PLUS_EXPR
, DECL_SIZE_UNIT (decl
),
507 TYPE_SIZE_UNIT (TREE_TYPE (str
)));
509 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
510 build_int_cst (short_unsigned_type_node
,
512 build_int_cst (short_unsigned_type_node
,
513 tinfo
), NULL_TREE
, str
);
514 TREE_CONSTANT (ctor
) = 1;
515 TREE_STATIC (ctor
) = 1;
516 DECL_INITIAL (decl
) = ctor
;
517 varpool_node::finalize_decl (decl
);
519 /* Save the VAR_DECL into the hash table. */
520 decl_for_type_insert (type
, decl
);
522 return build_fold_addr_expr (decl
);
525 /* Create a structure for the ubsan library. NAME is a name of the new
526 structure. LOCCNT is number of locations, PLOC points to array of
527 locations. The arguments in ... are of __ubsan_type_descriptor type
528 and there are at most two of them, followed by NULL_TREE, followed
529 by optional extra arguments and another NULL_TREE. */
532 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
537 vec
<tree
, va_gc
> *saved_args
= NULL
;
541 /* Firstly, create a pointer to type descriptor type. */
542 tree td_type
= ubsan_get_type_descriptor_type ();
543 td_type
= build_pointer_type (td_type
);
545 /* Create the structure type. */
546 ret
= make_node (RECORD_TYPE
);
547 for (j
= 0; j
< loccnt
; j
++)
549 gcc_checking_assert (i
< 2);
550 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
551 ubsan_get_source_location_type ());
552 DECL_CONTEXT (fields
[i
]) = ret
;
554 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
558 va_start (args
, ploc
);
559 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
560 i
++, t
= va_arg (args
, tree
))
562 gcc_checking_assert (i
< 4);
563 /* Save the tree arguments for later use. */
564 vec_safe_push (saved_args
, t
);
565 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
567 DECL_CONTEXT (fields
[i
]) = ret
;
569 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
572 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
573 i
++, t
= va_arg (args
, tree
))
575 gcc_checking_assert (i
< 6);
576 /* Save the tree arguments for later use. */
577 vec_safe_push (saved_args
, t
);
578 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
580 DECL_CONTEXT (fields
[i
]) = ret
;
582 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
586 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
587 get_identifier (name
), ret
);
588 DECL_IGNORED_P (type_decl
) = 1;
589 DECL_ARTIFICIAL (type_decl
) = 1;
590 TYPE_FIELDS (ret
) = fields
[0];
591 TYPE_NAME (ret
) = type_decl
;
592 TYPE_STUB_DECL (ret
) = type_decl
;
595 /* Now, fill in the type. */
597 static unsigned int ubsan_var_id_num
;
598 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
599 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
601 TREE_STATIC (var
) = 1;
602 TREE_PUBLIC (var
) = 0;
603 DECL_ARTIFICIAL (var
) = 1;
604 DECL_IGNORED_P (var
) = 1;
605 DECL_EXTERNAL (var
) = 0;
607 vec
<constructor_elt
, va_gc
> *v
;
609 tree ctor
= build_constructor (ret
, v
);
611 /* If desirable, set the __ubsan_source_location element. */
612 for (j
= 0; j
< loccnt
; j
++)
614 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
615 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
618 size_t nelts
= vec_safe_length (saved_args
);
619 for (i
= 0; i
< nelts
; i
++)
621 t
= (*saved_args
)[i
];
622 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
625 TREE_CONSTANT (ctor
) = 1;
626 TREE_STATIC (ctor
) = 1;
627 DECL_INITIAL (var
) = ctor
;
628 varpool_node::finalize_decl (var
);
633 /* Instrument the __builtin_unreachable call. We just call the libubsan
637 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
640 location_t loc
= gimple_location (gsi_stmt (*gsi
));
642 if (flag_sanitize_undefined_trap_on_error
)
643 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
646 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
647 NULL_TREE
, NULL_TREE
);
648 data
= build_fold_addr_expr_loc (loc
, data
);
650 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
651 g
= gimple_build_call (fn
, 1, data
);
653 gimple_set_location (g
, loc
);
654 gsi_replace (gsi
, g
, false);
658 /* Return true if T is a call to a libubsan routine. */
661 is_ubsan_builtin_p (tree t
)
663 return TREE_CODE (t
) == FUNCTION_DECL
664 && DECL_BUILT_IN_CLASS (t
) == BUILT_IN_NORMAL
665 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
666 "__builtin___ubsan_", 18) == 0;
669 /* Create a callgraph edge for statement STMT. */
672 ubsan_create_edge (gimple stmt
)
674 gcall
*call_stmt
= dyn_cast
<gcall
*> (stmt
);
675 basic_block bb
= gimple_bb (stmt
);
676 int freq
= compute_call_stmt_bb_frequency (current_function_decl
, bb
);
677 cgraph_node
*node
= cgraph_node::get (current_function_decl
);
678 tree decl
= gimple_call_fndecl (call_stmt
);
680 node
->create_edge (cgraph_node::get_create (decl
), call_stmt
, bb
->count
,
684 /* Expand the UBSAN_BOUNDS special builtin function. */
687 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
689 gimple stmt
= gsi_stmt (*gsi
);
690 location_t loc
= gimple_location (stmt
);
691 gcc_assert (gimple_call_num_args (stmt
) == 3);
693 /* Pick up the arguments of the UBSAN_BOUNDS call. */
694 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
695 tree index
= gimple_call_arg (stmt
, 1);
696 tree orig_index_type
= TREE_TYPE (index
);
697 tree bound
= gimple_call_arg (stmt
, 2);
699 gimple_stmt_iterator gsi_orig
= *gsi
;
701 /* Create condition "if (index > bound)". */
702 basic_block then_bb
, fallthru_bb
;
703 gimple_stmt_iterator cond_insert_point
704 = create_cond_insert_point (gsi
, false, false, true,
705 &then_bb
, &fallthru_bb
);
706 index
= fold_convert (TREE_TYPE (bound
), index
);
707 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
709 false, GSI_NEW_STMT
);
710 gimple g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
711 gimple_set_location (g
, loc
);
712 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
714 /* Generate __ubsan_handle_out_of_bounds call. */
715 *gsi
= gsi_after_labels (then_bb
);
716 if (flag_sanitize_undefined_trap_on_error
)
717 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
721 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
722 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
723 ubsan_type_descriptor (orig_index_type
),
724 NULL_TREE
, NULL_TREE
);
725 data
= build_fold_addr_expr_loc (loc
, data
);
726 enum built_in_function bcode
727 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
728 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
729 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
730 tree fn
= builtin_decl_explicit (bcode
);
731 tree val
= force_gimple_operand_gsi (gsi
, ubsan_encode_value (index
),
732 true, NULL_TREE
, true,
734 g
= gimple_build_call (fn
, 2, data
, val
);
736 gimple_set_location (g
, loc
);
737 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
739 /* Get rid of the UBSAN_BOUNDS call from the IR. */
740 unlink_stmt_vdef (stmt
);
741 gsi_remove (&gsi_orig
, true);
743 /* Point GSI to next logical statement. */
744 *gsi
= gsi_start_bb (fallthru_bb
);
748 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
749 argument which is a constant, because the middle-end treats pointer
750 conversions as useless and therefore the type of the first argument
751 could be changed to any other pointer type. */
754 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
756 gimple_stmt_iterator gsi
= *gsip
;
757 gimple stmt
= gsi_stmt (gsi
);
758 location_t loc
= gimple_location (stmt
);
759 gcc_assert (gimple_call_num_args (stmt
) == 3);
760 tree ptr
= gimple_call_arg (stmt
, 0);
761 tree ckind
= gimple_call_arg (stmt
, 1);
762 tree align
= gimple_call_arg (stmt
, 2);
763 tree check_align
= NULL_TREE
;
766 basic_block cur_bb
= gsi_bb (gsi
);
769 if (!integer_zerop (align
))
771 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
772 if (compare_tree_int (align
, ptralign
) == 1)
774 check_align
= make_ssa_name (pointer_sized_int_node
);
775 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
776 gimple_set_location (g
, loc
);
777 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
780 check_null
= (flag_sanitize
& SANITIZE_NULL
) != 0;
782 if (check_align
== NULL_TREE
&& !check_null
)
784 gsi_remove (gsip
, true);
785 /* Unlink the UBSAN_NULLs vops before replacing it. */
786 unlink_stmt_vdef (stmt
);
790 /* Split the original block holding the pointer dereference. */
791 edge e
= split_block (cur_bb
, stmt
);
793 /* Get a hold on the 'condition block', the 'then block' and the
795 basic_block cond_bb
= e
->src
;
796 basic_block fallthru_bb
= e
->dest
;
797 basic_block then_bb
= create_empty_bb (cond_bb
);
798 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
799 loops_state_set (LOOPS_NEED_FIXUP
);
801 /* Make an edge coming from the 'cond block' into the 'then block';
802 this edge is unlikely taken, so set up the probability accordingly. */
803 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
804 e
->probability
= PROB_VERY_UNLIKELY
;
806 /* Connect 'then block' with the 'else block'. This is needed
807 as the ubsan routines we call in the 'then block' are not noreturn.
808 The 'then block' only has one outcoming edge. */
809 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
811 /* Set up the fallthrough basic block. */
812 e
= find_edge (cond_bb
, fallthru_bb
);
813 e
->flags
= EDGE_FALSE_VALUE
;
814 e
->count
= cond_bb
->count
;
815 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
817 /* Update dominance info for the newly created then_bb; note that
818 fallthru_bb's dominance info has already been updated by
820 if (dom_info_available_p (CDI_DOMINATORS
))
821 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
823 /* Put the ubsan builtin call into the newly created BB. */
824 if (flag_sanitize_undefined_trap_on_error
)
825 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
828 enum built_in_function bcode
829 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
830 | (check_null
? SANITIZE_NULL
: 0)))
831 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
832 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
833 tree fn
= builtin_decl_implicit (bcode
);
835 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
836 ubsan_type_descriptor (TREE_TYPE (ckind
),
837 UBSAN_PRINT_POINTER
),
840 fold_convert (unsigned_char_type_node
, ckind
),
842 data
= build_fold_addr_expr_loc (loc
, data
);
843 g
= gimple_build_call (fn
, 2, data
,
844 check_align
? check_align
845 : build_zero_cst (pointer_sized_int_node
));
847 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
848 gimple_set_location (g
, loc
);
849 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
851 /* Unlink the UBSAN_NULLs vops before replacing it. */
852 unlink_stmt_vdef (stmt
);
856 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
857 NULL_TREE
, NULL_TREE
);
858 gimple_set_location (g
, loc
);
860 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
861 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 #define OBJSZ_MAX_OFFSET (1024 * 16)
921 /* Expand UBSAN_OBJECT_SIZE internal call. */
924 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
926 gimple stmt
= gsi_stmt (*gsi
);
927 location_t loc
= gimple_location (stmt
);
928 gcc_assert (gimple_call_num_args (stmt
) == 4);
930 tree ptr
= gimple_call_arg (stmt
, 0);
931 tree offset
= gimple_call_arg (stmt
, 1);
932 tree size
= gimple_call_arg (stmt
, 2);
933 tree ckind
= gimple_call_arg (stmt
, 3);
934 gimple_stmt_iterator gsi_orig
= *gsi
;
937 /* See if we can discard the check. */
938 if (TREE_CODE (size
) != INTEGER_CST
939 || integer_all_onesp (size
))
940 /* Yes, __builtin_object_size couldn't determine the
942 else if (TREE_CODE (offset
) == INTEGER_CST
943 && wi::ges_p (wi::to_widest (offset
), -OBJSZ_MAX_OFFSET
)
944 && wi::les_p (wi::to_widest (offset
), -1))
945 /* The offset is in range [-16K, -1]. */;
948 /* if (offset > objsize) */
949 basic_block then_bb
, fallthru_bb
;
950 gimple_stmt_iterator cond_insert_point
951 = create_cond_insert_point (gsi
, false, false, true,
952 &then_bb
, &fallthru_bb
);
953 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
954 gimple_set_location (g
, loc
);
955 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
957 /* If the offset is small enough, we don't need the second
959 if (TREE_CODE (offset
) == INTEGER_CST
960 && wi::ges_p (wi::to_widest (offset
), 0)
961 && wi::les_p (wi::to_widest (offset
), OBJSZ_MAX_OFFSET
))
962 *gsi
= gsi_after_labels (then_bb
);
965 /* Don't issue run-time error if (ptr > ptr + offset). That
966 may happen when computing a POINTER_PLUS_EXPR. */
967 basic_block then2_bb
, fallthru2_bb
;
969 gimple_stmt_iterator gsi2
= gsi_after_labels (then_bb
);
970 cond_insert_point
= create_cond_insert_point (&gsi2
, false, false,
973 /* Convert the pointer to an integer type. */
974 tree p
= make_ssa_name (pointer_sized_int_node
);
975 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
976 gimple_set_location (g
, loc
);
977 gsi_insert_before (&cond_insert_point
, g
, GSI_NEW_STMT
);
978 p
= gimple_assign_lhs (g
);
979 /* Compute ptr + offset. */
980 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
981 PLUS_EXPR
, p
, offset
);
982 gimple_set_location (g
, loc
);
983 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
984 /* Now build the conditional and put it into the IR. */
985 g
= gimple_build_cond (LE_EXPR
, p
, gimple_assign_lhs (g
),
986 NULL_TREE
, NULL_TREE
);
987 gimple_set_location (g
, loc
);
988 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
989 *gsi
= gsi_after_labels (then2_bb
);
992 /* Generate __ubsan_handle_type_mismatch call. */
993 if (flag_sanitize_undefined_trap_on_error
)
994 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
998 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
999 ubsan_type_descriptor (TREE_TYPE (ptr
),
1000 UBSAN_PRINT_POINTER
),
1002 build_zero_cst (pointer_sized_int_node
),
1005 data
= build_fold_addr_expr_loc (loc
, data
);
1006 enum built_in_function bcode
1007 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
1008 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1009 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
1010 tree p
= make_ssa_name (pointer_sized_int_node
);
1011 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
1012 gimple_set_location (g
, loc
);
1013 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1014 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
1016 gimple_set_location (g
, loc
);
1017 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1019 /* Point GSI to next logical statement. */
1020 *gsi
= gsi_start_bb (fallthru_bb
);
1022 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1023 unlink_stmt_vdef (stmt
);
1024 gsi_remove (&gsi_orig
, true);
1028 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1029 unlink_stmt_vdef (stmt
);
1030 gsi_remove (gsi
, true);
1034 /* Cached __ubsan_vptr_type_cache decl. */
1035 static GTY(()) tree ubsan_vptr_type_cache_decl
;
1037 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1038 argument which is a constant, because the middle-end treats pointer
1039 conversions as useless and therefore the type of the first argument
1040 could be changed to any other pointer type. */
1043 ubsan_expand_vptr_ifn (gimple_stmt_iterator
*gsip
)
1045 gimple_stmt_iterator gsi
= *gsip
;
1046 gimple stmt
= gsi_stmt (gsi
);
1047 location_t loc
= gimple_location (stmt
);
1048 gcc_assert (gimple_call_num_args (stmt
) == 5);
1049 tree op
= gimple_call_arg (stmt
, 0);
1050 tree vptr
= gimple_call_arg (stmt
, 1);
1051 tree str_hash
= gimple_call_arg (stmt
, 2);
1052 tree ti_decl_addr
= gimple_call_arg (stmt
, 3);
1053 tree ckind_tree
= gimple_call_arg (stmt
, 4);
1054 ubsan_null_ckind ckind
= (ubsan_null_ckind
) tree_to_uhwi (ckind_tree
);
1055 tree type
= TREE_TYPE (TREE_TYPE (ckind_tree
));
1057 basic_block fallthru_bb
= NULL
;
1059 if (ckind
== UBSAN_DOWNCAST_POINTER
)
1061 /* Guard everything with if (op != NULL) { ... }. */
1062 basic_block then_bb
;
1063 gimple_stmt_iterator cond_insert_point
1064 = create_cond_insert_point (gsip
, false, false, true,
1065 &then_bb
, &fallthru_bb
);
1066 g
= gimple_build_cond (NE_EXPR
, op
, build_zero_cst (TREE_TYPE (op
)),
1067 NULL_TREE
, NULL_TREE
);
1068 gimple_set_location (g
, loc
);
1069 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1070 *gsip
= gsi_after_labels (then_bb
);
1071 gsi_remove (&gsi
, false);
1072 gsi_insert_before (gsip
, stmt
, GSI_NEW_STMT
);
1076 tree htype
= TREE_TYPE (str_hash
);
1077 tree cst
= wide_int_to_tree (htype
,
1078 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1080 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1082 gimple_set_location (g
, loc
);
1083 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1084 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1085 gimple_assign_lhs (g
), cst
);
1086 gimple_set_location (g
, loc
);
1087 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1088 tree t1
= gimple_assign_lhs (g
);
1089 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1090 t1
, build_int_cst (integer_type_node
, 47));
1091 gimple_set_location (g
, loc
);
1092 tree t2
= gimple_assign_lhs (g
);
1093 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1094 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1096 gimple_set_location (g
, loc
);
1097 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1098 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1099 t2
, gimple_assign_lhs (g
));
1100 gimple_set_location (g
, loc
);
1101 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1102 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1103 gimple_assign_lhs (g
), cst
);
1104 gimple_set_location (g
, loc
);
1105 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1106 tree t3
= gimple_assign_lhs (g
);
1107 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1108 t3
, build_int_cst (integer_type_node
, 47));
1109 gimple_set_location (g
, loc
);
1110 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1111 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1112 t3
, gimple_assign_lhs (g
));
1113 gimple_set_location (g
, loc
);
1114 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1115 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1116 gimple_assign_lhs (g
), cst
);
1117 gimple_set_location (g
, loc
);
1118 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1119 if (!useless_type_conversion_p (pointer_sized_int_node
, htype
))
1121 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1122 NOP_EXPR
, gimple_assign_lhs (g
));
1123 gimple_set_location (g
, loc
);
1124 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1126 tree hash
= gimple_assign_lhs (g
);
1128 if (ubsan_vptr_type_cache_decl
== NULL_TREE
)
1130 tree atype
= build_array_type_nelts (pointer_sized_int_node
, 128);
1131 tree array
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1132 get_identifier ("__ubsan_vptr_type_cache"),
1134 DECL_ARTIFICIAL (array
) = 1;
1135 DECL_IGNORED_P (array
) = 1;
1136 TREE_PUBLIC (array
) = 1;
1137 TREE_STATIC (array
) = 1;
1138 DECL_EXTERNAL (array
) = 1;
1139 DECL_VISIBILITY (array
) = VISIBILITY_DEFAULT
;
1140 DECL_VISIBILITY_SPECIFIED (array
) = 1;
1141 varpool_node::finalize_decl (array
);
1142 ubsan_vptr_type_cache_decl
= array
;
1145 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1147 build_int_cst (pointer_sized_int_node
, 127));
1148 gimple_set_location (g
, loc
);
1149 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1151 tree c
= build4_loc (loc
, ARRAY_REF
, pointer_sized_int_node
,
1152 ubsan_vptr_type_cache_decl
, gimple_assign_lhs (g
),
1153 NULL_TREE
, NULL_TREE
);
1154 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1156 gimple_set_location (g
, loc
);
1157 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1159 basic_block then_bb
, fallthru2_bb
;
1160 gimple_stmt_iterator cond_insert_point
1161 = create_cond_insert_point (gsip
, false, false, true,
1162 &then_bb
, &fallthru2_bb
);
1163 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
), hash
,
1164 NULL_TREE
, NULL_TREE
);
1165 gimple_set_location (g
, loc
);
1166 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1167 *gsip
= gsi_after_labels (then_bb
);
1168 if (fallthru_bb
== NULL
)
1169 fallthru_bb
= fallthru2_bb
;
1172 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc
,
1173 ubsan_type_descriptor (type
), NULL_TREE
, ti_decl_addr
,
1174 build_int_cst (unsigned_char_type_node
, ckind
),
1176 data
= build_fold_addr_expr_loc (loc
, data
);
1177 enum built_in_function bcode
1178 = (flag_sanitize_recover
& SANITIZE_VPTR
)
1179 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1180 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT
;
1182 g
= gimple_build_call (builtin_decl_explicit (bcode
), 3, data
, op
, hash
);
1183 gimple_set_location (g
, loc
);
1184 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1186 /* Point GSI to next logical statement. */
1187 *gsip
= gsi_start_bb (fallthru_bb
);
1189 /* Get rid of the UBSAN_VPTR call from the IR. */
1190 unlink_stmt_vdef (stmt
);
1191 gsi_remove (&gsi
, true);
1195 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1196 whether the pointer is on the left hand side of the assignment. */
1199 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
1202 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
1203 unsigned int align
= 0;
1204 if (flag_sanitize
& SANITIZE_ALIGNMENT
)
1206 align
= min_align_of_type (TREE_TYPE (base
));
1210 if (align
== 0 && (flag_sanitize
& SANITIZE_NULL
) == 0)
1212 tree t
= TREE_OPERAND (base
, 0);
1213 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
1215 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base
)) && mem
!= base
)
1216 ikind
= UBSAN_MEMBER_ACCESS
;
1217 tree kind
= build_int_cst (build_pointer_type (TREE_TYPE (base
)), ikind
);
1218 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
1219 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
1220 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
1221 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
1224 /* Perform the pointer instrumentation. */
1227 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
1229 gimple stmt
= gsi_stmt (gsi
);
1230 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1231 tree base
= get_base_address (t
);
1232 const enum tree_code code
= TREE_CODE (base
);
1234 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1235 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1238 /* Build an ubsan builtin call for the signed-integer-overflow
1239 sanitization. CODE says what kind of builtin are we building,
1240 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1241 are operands of the binary operation. */
1244 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1247 if (flag_sanitize_undefined_trap_on_error
)
1248 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1250 tree data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1251 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1253 enum built_in_function fn_code
;
1258 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1259 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1260 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1263 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1264 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1265 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1268 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1269 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1270 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1273 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1274 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1275 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1280 tree fn
= builtin_decl_explicit (fn_code
);
1281 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1282 build_fold_addr_expr_loc (loc
, data
),
1283 ubsan_encode_value (op0
, true),
1284 op1
? ubsan_encode_value (op1
, true)
1288 /* Perform the signed integer instrumentation. GSI is the iterator
1289 pointing at statement we are trying to instrument. */
1292 instrument_si_overflow (gimple_stmt_iterator gsi
)
1294 gimple stmt
= gsi_stmt (gsi
);
1295 tree_code code
= gimple_assign_rhs_code (stmt
);
1296 tree lhs
= gimple_assign_lhs (stmt
);
1297 tree lhstype
= TREE_TYPE (lhs
);
1301 /* If this is not a signed operation, don't instrument anything here.
1302 Also punt on bit-fields. */
1303 if (!INTEGRAL_TYPE_P (lhstype
)
1304 || TYPE_OVERFLOW_WRAPS (lhstype
)
1305 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
1316 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1317 a
= gimple_assign_rhs1 (stmt
);
1318 b
= gimple_assign_rhs2 (stmt
);
1319 g
= gimple_build_call_internal (code
== PLUS_EXPR
1320 ? IFN_UBSAN_CHECK_ADD
1321 : code
== MINUS_EXPR
1322 ? IFN_UBSAN_CHECK_SUB
1323 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1324 gimple_call_set_lhs (g
, lhs
);
1325 gsi_replace (&gsi
, g
, false);
1328 /* Represent i = -u;
1330 i = UBSAN_CHECK_SUB (0, u); */
1331 a
= build_int_cst (lhstype
, 0);
1332 b
= gimple_assign_rhs1 (stmt
);
1333 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1334 gimple_call_set_lhs (g
, lhs
);
1335 gsi_replace (&gsi
, g
, false);
1338 /* Transform i = ABS_EXPR<u>;
1340 _N = UBSAN_CHECK_SUB (0, u);
1341 i = ABS_EXPR<_N>; */
1342 a
= build_int_cst (lhstype
, 0);
1343 b
= gimple_assign_rhs1 (stmt
);
1344 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1345 a
= make_ssa_name (lhstype
);
1346 gimple_call_set_lhs (g
, a
);
1347 gimple_set_location (g
, gimple_location (stmt
));
1348 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1349 gimple_assign_set_rhs1 (stmt
, a
);
1357 /* Instrument loads from (non-bitfield) bool and C++ enum values
1358 to check if the memory value is outside of the range of the valid
1362 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1364 gimple stmt
= gsi_stmt (*gsi
);
1365 tree rhs
= gimple_assign_rhs1 (stmt
);
1366 tree type
= TREE_TYPE (rhs
);
1367 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1369 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
1371 minv
= boolean_false_node
;
1372 maxv
= boolean_true_node
;
1374 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1375 && (flag_sanitize
& SANITIZE_ENUM
)
1376 && TREE_TYPE (type
) != NULL_TREE
1377 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1378 && (TYPE_PRECISION (TREE_TYPE (type
))
1379 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1381 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1382 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1387 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1388 HOST_WIDE_INT bitsize
, bitpos
;
1391 int volatilep
= 0, unsignedp
= 0;
1392 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1393 &unsignedp
, &volatilep
, false);
1394 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1396 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
1397 || (bitpos
% modebitsize
) != 0
1398 || bitsize
!= modebitsize
1399 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1400 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1403 bool ends_bb
= stmt_ends_bb_p (stmt
);
1404 location_t loc
= gimple_location (stmt
);
1405 tree lhs
= gimple_assign_lhs (stmt
);
1406 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1407 tree atype
= reference_alias_ptr_type (rhs
);
1408 gimple g
= gimple_build_assign (make_ssa_name (ptype
),
1409 build_fold_addr_expr (rhs
));
1410 gimple_set_location (g
, loc
);
1411 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1412 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1413 build_int_cst (atype
, 0));
1414 tree urhs
= make_ssa_name (utype
);
1417 gimple_assign_set_lhs (stmt
, urhs
);
1418 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1419 gimple_set_location (g
, loc
);
1420 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1421 gsi_insert_on_edge_immediate (e
, g
);
1422 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1424 *gsi
= gsi_for_stmt (g
);
1429 g
= gimple_build_assign (urhs
, mem
);
1430 gimple_set_location (g
, loc
);
1431 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1433 minv
= fold_convert (utype
, minv
);
1434 maxv
= fold_convert (utype
, maxv
);
1435 if (!integer_zerop (minv
))
1437 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1438 gimple_set_location (g
, loc
);
1439 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1442 gimple_stmt_iterator gsi2
= *gsi
;
1443 basic_block then_bb
, fallthru_bb
;
1444 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1445 &then_bb
, &fallthru_bb
);
1446 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1447 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1448 NULL_TREE
, NULL_TREE
);
1449 gimple_set_location (g
, loc
);
1450 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1454 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1458 gsi2
= gsi_after_labels (then_bb
);
1459 if (flag_sanitize_undefined_trap_on_error
)
1460 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1463 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1464 ubsan_type_descriptor (type
), NULL_TREE
,
1466 data
= build_fold_addr_expr_loc (loc
, data
);
1467 enum built_in_function bcode
1468 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1469 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1470 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1471 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1472 tree fn
= builtin_decl_explicit (bcode
);
1474 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
1475 true, NULL_TREE
, true,
1477 g
= gimple_build_call (fn
, 2, data
, val
);
1479 gimple_set_location (g
, loc
);
1480 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1481 ubsan_create_edge (g
);
1482 *gsi
= gsi_for_stmt (stmt
);
1485 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1486 destination, EXPR is floating-point expression. ARG is what to pass
1487 the libubsan call as value, often EXPR itself. */
1490 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
, tree arg
)
1492 tree expr_type
= TREE_TYPE (expr
);
1493 tree t
, tt
, fn
, min
, max
;
1494 machine_mode mode
= TYPE_MODE (expr_type
);
1495 int prec
= TYPE_PRECISION (type
);
1496 bool uns_p
= TYPE_UNSIGNED (type
);
1498 /* Float to integer conversion first truncates toward zero, so
1499 even signed char c = 127.875f; is not problematic.
1500 Therefore, we should complain only if EXPR is unordered or smaller
1501 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1502 TYPE_MAX_VALUE + 1.0. */
1503 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1505 /* For maximum, TYPE_MAX_VALUE might not be representable
1506 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1507 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1508 either representable or infinity. */
1509 REAL_VALUE_TYPE maxval
= dconst1
;
1510 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1511 real_convert (&maxval
, mode
, &maxval
);
1512 max
= build_real (expr_type
, maxval
);
1514 /* For unsigned, assume -1.0 is always representable. */
1516 min
= build_minus_one_cst (expr_type
);
1519 /* TYPE_MIN_VALUE is generally representable (or -inf),
1520 but TYPE_MIN_VALUE - 1.0 might not be. */
1521 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1522 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1523 real_convert (&minval
, mode
, &minval
);
1524 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1525 real_convert (&minval2
, mode
, &minval2
);
1526 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1527 && !real_isinf (&minval
))
1529 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1530 rounds to TYPE_MIN_VALUE, we need to subtract
1531 more. As REAL_MODE_FORMAT (mode)->p is the number
1532 of base digits, we want to subtract a number that
1533 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1534 times smaller than minval. */
1536 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1537 SET_REAL_EXP (&minval2
,
1538 REAL_EXP (&minval2
) + prec
- 1
1539 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1540 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1541 real_convert (&minval2
, mode
, &minval2
);
1543 min
= build_real (expr_type
, minval2
);
1546 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1548 /* For _Decimal128 up to 34 decimal digits, - sign,
1549 dot, e, exponent. */
1552 int p
= REAL_MODE_FORMAT (mode
)->p
;
1553 REAL_VALUE_TYPE maxval
, minval
;
1555 /* Use mpfr_snprintf rounding to compute the smallest
1556 representable decimal number greater or equal than
1557 1 << (prec - !uns_p). */
1558 mpfr_init2 (m
, prec
+ 2);
1559 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1560 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1561 decimal_real_from_string (&maxval
, buf
);
1562 max
= build_real (expr_type
, maxval
);
1564 /* For unsigned, assume -1.0 is always representable. */
1566 min
= build_minus_one_cst (expr_type
);
1569 /* Use mpfr_snprintf rounding to compute the largest
1570 representable decimal number less or equal than
1571 (-1 << (prec - 1)) - 1. */
1572 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1573 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1574 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1575 decimal_real_from_string (&minval
, buf
);
1576 min
= build_real (expr_type
, minval
);
1583 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1584 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1585 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
);
1586 if (integer_zerop (t
))
1589 if (flag_sanitize_undefined_trap_on_error
)
1590 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1593 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1594 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1595 NULL
, ubsan_type_descriptor (expr_type
),
1596 ubsan_type_descriptor (type
), NULL_TREE
,
1598 enum built_in_function bcode
1599 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1600 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1601 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1602 fn
= builtin_decl_explicit (bcode
);
1603 fn
= build_call_expr_loc (loc
, fn
, 2,
1604 build_fold_addr_expr_loc (loc
, data
),
1605 ubsan_encode_value (arg
, false));
1608 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1611 /* Instrument values passed to function arguments with nonnull attribute. */
1614 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1616 gimple stmt
= gsi_stmt (*gsi
);
1618 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1619 while for nonnull sanitization it is clear. */
1620 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1621 flag_delete_null_pointer_checks
= 1;
1622 loc
[0] = gimple_location (stmt
);
1623 loc
[1] = UNKNOWN_LOCATION
;
1624 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1626 tree arg
= gimple_call_arg (stmt
, i
);
1627 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1628 && infer_nonnull_range (stmt
, arg
, false, true))
1631 if (!is_gimple_val (arg
))
1633 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1634 gimple_set_location (g
, loc
[0]);
1635 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1636 arg
= gimple_assign_lhs (g
);
1639 basic_block then_bb
, fallthru_bb
;
1640 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1641 &then_bb
, &fallthru_bb
);
1642 g
= gimple_build_cond (EQ_EXPR
, arg
,
1643 build_zero_cst (TREE_TYPE (arg
)),
1644 NULL_TREE
, NULL_TREE
);
1645 gimple_set_location (g
, loc
[0]);
1646 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1648 *gsi
= gsi_after_labels (then_bb
);
1649 if (flag_sanitize_undefined_trap_on_error
)
1650 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1653 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1655 build_int_cst (integer_type_node
,
1658 data
= build_fold_addr_expr_loc (loc
[0], data
);
1659 enum built_in_function bcode
1660 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1661 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1662 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1663 tree fn
= builtin_decl_explicit (bcode
);
1665 g
= gimple_build_call (fn
, 1, data
);
1667 gimple_set_location (g
, loc
[0]);
1668 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1669 ubsan_create_edge (g
);
1671 *gsi
= gsi_for_stmt (stmt
);
1673 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1676 /* Instrument returns in functions with returns_nonnull attribute. */
1679 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1681 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
1683 tree arg
= gimple_return_retval (stmt
);
1684 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1685 while for nonnull return sanitization it is clear. */
1686 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1687 flag_delete_null_pointer_checks
= 1;
1688 loc
[0] = gimple_location (stmt
);
1689 loc
[1] = UNKNOWN_LOCATION
;
1691 && POINTER_TYPE_P (TREE_TYPE (arg
))
1692 && is_gimple_val (arg
)
1693 && infer_nonnull_range (stmt
, arg
, false, true))
1695 basic_block then_bb
, fallthru_bb
;
1696 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1697 &then_bb
, &fallthru_bb
);
1698 gimple g
= gimple_build_cond (EQ_EXPR
, arg
,
1699 build_zero_cst (TREE_TYPE (arg
)),
1700 NULL_TREE
, NULL_TREE
);
1701 gimple_set_location (g
, loc
[0]);
1702 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1704 *gsi
= gsi_after_labels (then_bb
);
1705 if (flag_sanitize_undefined_trap_on_error
)
1706 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1709 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
1710 2, loc
, NULL_TREE
, NULL_TREE
);
1711 data
= build_fold_addr_expr_loc (loc
[0], data
);
1712 enum built_in_function bcode
1713 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1714 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1715 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
1716 tree fn
= builtin_decl_explicit (bcode
);
1718 g
= gimple_build_call (fn
, 1, data
);
1720 gimple_set_location (g
, loc
[0]);
1721 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1722 ubsan_create_edge (g
);
1723 *gsi
= gsi_for_stmt (stmt
);
1725 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1728 /* Instrument memory references. Here we check whether the pointer
1729 points to an out-of-bounds location. */
1732 instrument_object_size (gimple_stmt_iterator
*gsi
, bool is_lhs
)
1734 gimple stmt
= gsi_stmt (*gsi
);
1735 location_t loc
= gimple_location (stmt
);
1736 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1738 tree index
= NULL_TREE
;
1739 HOST_WIDE_INT size_in_bytes
;
1741 type
= TREE_TYPE (t
);
1742 if (VOID_TYPE_P (type
))
1745 switch (TREE_CODE (t
))
1748 if (TREE_CODE (t
) == COMPONENT_REF
1749 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
1751 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
1752 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
1757 index
= TREE_OPERAND (t
, 1);
1769 size_in_bytes
= int_size_in_bytes (type
);
1770 if (size_in_bytes
<= 0)
1773 HOST_WIDE_INT bitsize
, bitpos
;
1776 int volatilep
= 0, unsignedp
= 0;
1777 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1778 &unsignedp
, &volatilep
, false);
1780 if (bitpos
% BITS_PER_UNIT
!= 0
1781 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
1784 bool decl_p
= DECL_P (inner
);
1788 else if (TREE_CODE (inner
) == MEM_REF
)
1789 base
= TREE_OPERAND (inner
, 0);
1792 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
1794 while (TREE_CODE (base
) == SSA_NAME
)
1796 gimple def_stmt
= SSA_NAME_DEF_STMT (base
);
1797 if (gimple_assign_ssa_name_copy_p (def_stmt
)
1798 || (gimple_assign_cast_p (def_stmt
)
1799 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
1800 || (is_gimple_assign (def_stmt
)
1801 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
1803 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
1804 if (TREE_CODE (rhs1
) == SSA_NAME
1805 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
1814 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1818 tree base_addr
= base
;
1819 gimple bos_stmt
= NULL
;
1821 base_addr
= build1 (ADDR_EXPR
,
1822 build_pointer_type (TREE_TYPE (base
)), base
);
1823 unsigned HOST_WIDE_INT size
= compute_builtin_object_size (base_addr
, 0);
1824 if (size
!= (unsigned HOST_WIDE_INT
) -1)
1825 sizet
= build_int_cst (sizetype
, size
);
1828 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
1829 loc
= input_location
;
1830 /* Generate __builtin_object_size call. */
1831 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
1832 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
1834 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
1836 /* If the call above didn't end up being an integer constant, go one
1837 statement back and get the __builtin_object_size stmt. Save it,
1838 we might need it later. */
1839 if (SSA_VAR_P (sizet
))
1842 bos_stmt
= gsi_stmt (*gsi
);
1844 /* Move on to where we were. */
1851 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1853 /* ptr + sizeof (*ptr) - base */
1854 t
= fold_build2 (MINUS_EXPR
, sizetype
,
1855 fold_convert (pointer_sized_int_node
, ptr
),
1856 fold_convert (pointer_sized_int_node
, base_addr
));
1857 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
1859 /* Perhaps we can omit the check. */
1860 if (TREE_CODE (t
) == INTEGER_CST
1861 && TREE_CODE (sizet
) == INTEGER_CST
1862 && tree_int_cst_le (t
, sizet
))
1865 if (index
!= NULL_TREE
1866 && TREE_CODE (index
) == SSA_NAME
1867 && TREE_CODE (sizet
) == INTEGER_CST
)
1869 gimple def
= SSA_NAME_DEF_STMT (index
);
1870 if (is_gimple_assign (def
)
1871 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
1872 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
1874 tree cst
= gimple_assign_rhs2 (def
);
1875 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
1876 TYPE_SIZE_UNIT (type
));
1877 if (tree_int_cst_sgn (cst
) >= 0
1878 && tree_int_cst_lt (cst
, sz
))
1883 if (bos_stmt
&& gimple_call_builtin_p (bos_stmt
, BUILT_IN_OBJECT_SIZE
))
1884 ubsan_create_edge (bos_stmt
);
1886 /* We have to emit the check. */
1887 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1889 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
1891 tree ckind
= build_int_cst (unsigned_char_type_node
,
1892 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
1893 gimple g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
1894 ptr
, t
, sizet
, ckind
);
1895 gimple_set_location (g
, loc
);
1896 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1899 /* True if we want to play UBSan games in the current function. */
1902 do_ubsan_in_current_function ()
1904 return (current_function_decl
!= NULL_TREE
1905 && !lookup_attribute ("no_sanitize_undefined",
1906 DECL_ATTRIBUTES (current_function_decl
)));
1911 const pass_data pass_data_ubsan
=
1913 GIMPLE_PASS
, /* type */
1915 OPTGROUP_NONE
, /* optinfo_flags */
1916 TV_TREE_UBSAN
, /* tv_id */
1917 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1918 0, /* properties_provided */
1919 0, /* properties_destroyed */
1920 0, /* todo_flags_start */
1921 TODO_update_ssa
, /* todo_flags_finish */
1924 class pass_ubsan
: public gimple_opt_pass
1927 pass_ubsan (gcc::context
*ctxt
)
1928 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1931 /* opt_pass methods: */
1932 virtual bool gate (function
*)
1934 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1935 | SANITIZE_BOOL
| SANITIZE_ENUM
1936 | SANITIZE_ALIGNMENT
1937 | SANITIZE_NONNULL_ATTRIBUTE
1938 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1939 | SANITIZE_OBJECT_SIZE
)
1940 && do_ubsan_in_current_function ();
1943 virtual unsigned int execute (function
*);
1945 }; // class pass_ubsan
1948 pass_ubsan::execute (function
*fun
)
1951 gimple_stmt_iterator gsi
;
1953 initialize_sanitizer_builtins ();
1955 FOR_EACH_BB_FN (bb
, fun
)
1957 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1959 gimple stmt
= gsi_stmt (gsi
);
1960 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
1966 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
1967 && is_gimple_assign (stmt
))
1968 instrument_si_overflow (gsi
);
1970 if (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1972 if (gimple_store_p (stmt
))
1973 instrument_null (gsi
, true);
1974 if (gimple_assign_load_p (stmt
))
1975 instrument_null (gsi
, false);
1978 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
1979 && gimple_assign_load_p (stmt
))
1981 instrument_bool_enum_load (&gsi
);
1982 bb
= gimple_bb (stmt
);
1985 if ((flag_sanitize
& SANITIZE_NONNULL_ATTRIBUTE
)
1986 && is_gimple_call (stmt
)
1987 && !gimple_call_internal_p (stmt
))
1989 instrument_nonnull_arg (&gsi
);
1990 bb
= gimple_bb (stmt
);
1993 if ((flag_sanitize
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1994 && gimple_code (stmt
) == GIMPLE_RETURN
)
1996 instrument_nonnull_return (&gsi
);
1997 bb
= gimple_bb (stmt
);
2000 if (flag_sanitize
& SANITIZE_OBJECT_SIZE
)
2002 if (gimple_store_p (stmt
))
2003 instrument_object_size (&gsi
, true);
2004 if (gimple_assign_load_p (stmt
))
2005 instrument_object_size (&gsi
, false);
2017 make_pass_ubsan (gcc::context
*ctxt
)
2019 return new pass_ubsan (ctxt
);
2022 #include "gt-ubsan.h"