1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2020 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
26 #include "c-family/c-common.h"
29 #include "tree-pass.h"
34 #include "tree-pretty-print.h"
35 #include "stor-layout.h"
37 #include "gimple-iterator.h"
42 #include "stringpool.h"
45 #include "gimplify-me.h"
48 #include "tree-object-size.h"
50 #include "gimple-fold.h"
53 /* Map from a tree to a VAR_DECL tree. */
55 struct GTY((for_user
)) tree_type_map
{
56 struct tree_map_base type
;
60 struct tree_type_map_cache_hasher
: ggc_cache_ptr_hash
<tree_type_map
>
62 static inline hashval_t
63 hash (tree_type_map
*t
)
65 return TYPE_UID (t
->type
.from
);
69 equal (tree_type_map
*a
, tree_type_map
*b
)
71 return a
->type
.from
== b
->type
.from
;
75 keep_cache_entry (tree_type_map
*&m
)
77 return ggc_marked_p (m
->type
.from
);
82 hash_table
<tree_type_map_cache_hasher
> *decl_tree_for_type
;
84 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
87 decl_for_type_lookup (tree type
)
89 /* If the hash table is not initialized yet, create it now. */
90 if (decl_tree_for_type
== NULL
)
93 = hash_table
<tree_type_map_cache_hasher
>::create_ggc (10);
94 /* That also means we don't have to bother with the lookup. */
98 struct tree_type_map
*h
, in
;
101 h
= decl_tree_for_type
->find_with_hash (&in
, TYPE_UID (type
));
102 return h
? h
->decl
: NULL_TREE
;
105 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
108 decl_for_type_insert (tree type
, tree decl
)
110 struct tree_type_map
*h
;
112 h
= ggc_alloc
<tree_type_map
> ();
115 *decl_tree_for_type
->find_slot_with_hash (h
, TYPE_UID (type
), INSERT
) = h
;
118 /* Helper routine, which encodes a value in the pointer_sized_int_node.
119 Arguments with precision <= POINTER_SIZE are passed directly,
120 the rest is passed by reference. T is a value we are to encode.
121 PHASE determines when this function is called. */
124 ubsan_encode_value (tree t
, enum ubsan_encode_value_phase phase
)
126 tree type
= TREE_TYPE (t
);
127 scalar_mode mode
= SCALAR_TYPE_MODE (type
);
128 const unsigned int bitsize
= GET_MODE_BITSIZE (mode
);
129 if (bitsize
<= POINTER_SIZE
)
130 switch (TREE_CODE (type
))
135 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
138 tree itype
= build_nonstandard_integer_type (bitsize
, true);
139 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
140 return fold_convert (pointer_sized_int_node
, t
);
147 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
149 /* The reason for this is that we don't want to pessimize
150 code by making vars unnecessarily addressable. */
152 if (phase
!= UBSAN_ENCODE_VALUE_GENERIC
)
154 var
= create_tmp_var (type
);
155 mark_addressable (var
);
159 var
= create_tmp_var_raw (type
);
160 TREE_ADDRESSABLE (var
) = 1;
161 DECL_CONTEXT (var
) = current_function_decl
;
163 if (phase
== UBSAN_ENCODE_VALUE_RTL
)
165 rtx mem
= assign_stack_temp_for_type (mode
, GET_MODE_SIZE (mode
),
167 SET_DECL_RTL (var
, mem
);
168 expand_assignment (var
, t
, false);
169 return build_fold_addr_expr (var
);
171 if (phase
!= UBSAN_ENCODE_VALUE_GENERIC
)
173 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
174 t
= build_fold_addr_expr (var
);
175 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
179 var
= build4 (TARGET_EXPR
, type
, var
, t
, NULL_TREE
, NULL_TREE
);
180 return build_fold_addr_expr (var
);
184 return build_fold_addr_expr (t
);
188 /* Cached ubsan_get_type_descriptor_type () return value. */
189 static GTY(()) tree ubsan_type_descriptor_type
;
192 struct __ubsan_type_descriptor
194 unsigned short __typekind;
195 unsigned short __typeinfo;
201 ubsan_get_type_descriptor_type (void)
203 static const char *field_names
[3]
204 = { "__typekind", "__typeinfo", "__typename" };
207 if (ubsan_type_descriptor_type
)
208 return ubsan_type_descriptor_type
;
210 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
211 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
213 ret
= make_node (RECORD_TYPE
);
214 for (int i
= 0; i
< 3; i
++)
216 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
217 get_identifier (field_names
[i
]),
218 (i
== 2) ? flex_arr_type
219 : short_unsigned_type_node
);
220 DECL_CONTEXT (fields
[i
]) = ret
;
222 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
224 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
225 get_identifier ("__ubsan_type_descriptor"),
227 DECL_IGNORED_P (type_decl
) = 1;
228 DECL_ARTIFICIAL (type_decl
) = 1;
229 TYPE_FIELDS (ret
) = fields
[0];
230 TYPE_NAME (ret
) = type_decl
;
231 TYPE_STUB_DECL (ret
) = type_decl
;
232 TYPE_ARTIFICIAL (ret
) = 1;
234 ubsan_type_descriptor_type
= ret
;
238 /* Cached ubsan_get_source_location_type () return value. */
239 static GTY(()) tree ubsan_source_location_type
;
242 struct __ubsan_source_location
244 const char *__filename;
246 unsigned int __column;
251 ubsan_get_source_location_type (void)
253 static const char *field_names
[3]
254 = { "__filename", "__line", "__column" };
256 if (ubsan_source_location_type
)
257 return ubsan_source_location_type
;
259 tree const_char_type
= build_qualified_type (char_type_node
,
262 ret
= make_node (RECORD_TYPE
);
263 for (int i
= 0; i
< 3; i
++)
265 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
266 get_identifier (field_names
[i
]),
267 (i
== 0) ? build_pointer_type (const_char_type
)
268 : unsigned_type_node
);
269 DECL_CONTEXT (fields
[i
]) = ret
;
271 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
273 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
274 get_identifier ("__ubsan_source_location"),
276 DECL_IGNORED_P (type_decl
) = 1;
277 DECL_ARTIFICIAL (type_decl
) = 1;
278 TYPE_FIELDS (ret
) = fields
[0];
279 TYPE_NAME (ret
) = type_decl
;
280 TYPE_STUB_DECL (ret
) = type_decl
;
281 TYPE_ARTIFICIAL (ret
) = 1;
283 ubsan_source_location_type
= ret
;
287 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
288 type with its fields filled from a location_t LOC. */
291 ubsan_source_location (location_t loc
)
293 expanded_location xloc
;
294 tree type
= ubsan_get_source_location_type ();
296 xloc
= expand_location (loc
);
298 if (xloc
.file
== NULL
)
300 str
= build_int_cst (ptr_type_node
, 0);
306 /* Fill in the values from LOC. */
307 size_t len
= strlen (xloc
.file
) + 1;
308 str
= build_string (len
, xloc
.file
);
309 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
310 TREE_READONLY (str
) = 1;
311 TREE_STATIC (str
) = 1;
312 str
= build_fold_addr_expr (str
);
314 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
315 build_int_cst (unsigned_type_node
,
316 xloc
.line
), NULL_TREE
,
317 build_int_cst (unsigned_type_node
,
319 TREE_CONSTANT (ctor
) = 1;
320 TREE_STATIC (ctor
) = 1;
325 /* This routine returns a magic number for TYPE. */
327 static unsigned short
328 get_ubsan_type_info_for_type (tree type
)
330 if (TREE_CODE (type
) == REAL_TYPE
)
331 return tree_to_uhwi (TYPE_SIZE (type
));
332 else if (INTEGRAL_TYPE_P (type
))
334 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
335 gcc_assert (prec
!= -1);
336 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
342 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
343 ubsan_ids[1] for Lubsan_data labels. */
344 static GTY(()) unsigned int ubsan_ids
[2];
346 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
347 descriptor. It first looks into the hash table; if not found,
348 create the VAR_DECL, put it into the hash table and return the
349 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
350 an enum controlling how we want to print the type. */
353 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
355 /* See through any typedefs. */
356 type
= TYPE_MAIN_VARIANT (type
);
358 tree decl
= decl_for_type_lookup (type
);
359 /* It is possible that some of the earlier created DECLs were found
360 unused, in that case they weren't emitted and varpool_node::get
361 returns NULL node on them. But now we really need them. Thus,
363 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
364 return build_fold_addr_expr (decl
);
366 tree dtype
= ubsan_get_type_descriptor_type ();
368 const char *tname
= NULL
;
369 pretty_printer pretty_name
;
370 unsigned char deref_depth
= 0;
371 unsigned short tkind
, tinfo
;
373 /* Get the name of the type, or the name of the pointer type. */
374 if (pstyle
== UBSAN_PRINT_POINTER
)
376 gcc_assert (POINTER_TYPE_P (type
));
377 type2
= TREE_TYPE (type
);
379 /* Remove any '*' operators from TYPE. */
380 while (POINTER_TYPE_P (type2
))
381 deref_depth
++, type2
= TREE_TYPE (type2
);
383 if (TREE_CODE (type2
) == METHOD_TYPE
)
384 type2
= TYPE_METHOD_BASETYPE (type2
);
387 /* If an array, get its type. */
388 type2
= strip_array_types (type2
);
390 if (pstyle
== UBSAN_PRINT_ARRAY
)
392 while (POINTER_TYPE_P (type2
))
393 deref_depth
++, type2
= TREE_TYPE (type2
);
396 if (TYPE_NAME (type2
) != NULL
)
398 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
399 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
400 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
401 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
405 /* 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
);
438 && TYPE_MAX_VALUE (dom
) != NULL_TREE
439 && TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
441 unsigned HOST_WIDE_INT m
;
442 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom
))
443 && (m
= tree_to_uhwi (TYPE_MAX_VALUE (dom
))) + 1 != 0)
444 pp_unsigned_wide_integer (&pretty_name
, m
+ 1);
446 pp_wide_int (&pretty_name
,
447 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom
)), 1),
448 TYPE_SIGN (TREE_TYPE (dom
)));
451 /* ??? We can't determine the variable name; print VLA unspec. */
452 pp_star (&pretty_name
);
453 pp_right_bracket (&pretty_name
);
456 pp_quote (&pretty_name
);
458 /* Save the tree with stripped types. */
462 pp_printf (&pretty_name
, "'%s'", tname
);
464 switch (TREE_CODE (eltype
))
472 /* FIXME: libubsan right now only supports float, double and
473 long double type formats. */
474 if (TYPE_MODE (eltype
) == TYPE_MODE (float_type_node
)
475 || TYPE_MODE (eltype
) == TYPE_MODE (double_type_node
)
476 || TYPE_MODE (eltype
) == TYPE_MODE (long_double_type_node
))
485 tinfo
= get_ubsan_type_info_for_type (eltype
);
487 /* Create a new VAR_DECL of type descriptor. */
488 const char *tmp
= pp_formatted_text (&pretty_name
);
489 size_t len
= strlen (tmp
) + 1;
490 tree str
= build_string (len
, tmp
);
491 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
492 TREE_READONLY (str
) = 1;
493 TREE_STATIC (str
) = 1;
496 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", ubsan_ids
[0]++);
497 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
499 TREE_STATIC (decl
) = 1;
500 TREE_PUBLIC (decl
) = 0;
501 DECL_ARTIFICIAL (decl
) = 1;
502 DECL_IGNORED_P (decl
) = 1;
503 DECL_EXTERNAL (decl
) = 0;
505 = size_binop (PLUS_EXPR
, DECL_SIZE (decl
), TYPE_SIZE (TREE_TYPE (str
)));
506 DECL_SIZE_UNIT (decl
)
507 = size_binop (PLUS_EXPR
, DECL_SIZE_UNIT (decl
),
508 TYPE_SIZE_UNIT (TREE_TYPE (str
)));
510 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
511 build_int_cst (short_unsigned_type_node
,
513 build_int_cst (short_unsigned_type_node
,
514 tinfo
), NULL_TREE
, str
);
515 TREE_CONSTANT (ctor
) = 1;
516 TREE_STATIC (ctor
) = 1;
517 DECL_INITIAL (decl
) = ctor
;
518 varpool_node::finalize_decl (decl
);
520 /* Save the VAR_DECL into the hash table. */
521 decl_for_type_insert (type
, decl
);
523 return build_fold_addr_expr (decl
);
526 /* Create a structure for the ubsan library. NAME is a name of the new
527 structure. LOCCNT is number of locations, PLOC points to array of
528 locations. The arguments in ... are of __ubsan_type_descriptor type
529 and there are at most two of them, followed by NULL_TREE, followed
530 by optional extra arguments and another NULL_TREE. */
533 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
538 vec
<tree
, va_gc
> *saved_args
= NULL
;
542 /* It is possible that PCH zapped table with definitions of sanitizer
543 builtins. Reinitialize them if needed. */
544 initialize_sanitizer_builtins ();
546 /* Firstly, create a pointer to type descriptor type. */
547 tree td_type
= ubsan_get_type_descriptor_type ();
548 td_type
= build_pointer_type (td_type
);
550 /* Create the structure type. */
551 ret
= make_node (RECORD_TYPE
);
552 for (j
= 0; j
< loccnt
; j
++)
554 gcc_checking_assert (i
< 2);
555 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
556 ubsan_get_source_location_type ());
557 DECL_CONTEXT (fields
[i
]) = ret
;
559 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
563 va_start (args
, ploc
);
564 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
565 i
++, t
= va_arg (args
, tree
))
567 gcc_checking_assert (i
< 4);
568 /* Save the tree arguments for later use. */
569 vec_safe_push (saved_args
, t
);
570 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
572 DECL_CONTEXT (fields
[i
]) = ret
;
574 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
577 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
578 i
++, t
= va_arg (args
, tree
))
580 gcc_checking_assert (i
< 6);
581 /* Save the tree arguments for later use. */
582 vec_safe_push (saved_args
, t
);
583 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
585 DECL_CONTEXT (fields
[i
]) = ret
;
587 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
591 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
592 get_identifier (name
), ret
);
593 DECL_IGNORED_P (type_decl
) = 1;
594 DECL_ARTIFICIAL (type_decl
) = 1;
595 TYPE_FIELDS (ret
) = fields
[0];
596 TYPE_NAME (ret
) = type_decl
;
597 TYPE_STUB_DECL (ret
) = type_decl
;
598 TYPE_ARTIFICIAL (ret
) = 1;
601 /* Now, fill in the type. */
603 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_ids
[1]++);
604 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
606 TREE_STATIC (var
) = 1;
607 TREE_PUBLIC (var
) = 0;
608 DECL_ARTIFICIAL (var
) = 1;
609 DECL_IGNORED_P (var
) = 1;
610 DECL_EXTERNAL (var
) = 0;
612 vec
<constructor_elt
, va_gc
> *v
;
614 tree ctor
= build_constructor (ret
, v
);
616 /* If desirable, set the __ubsan_source_location element. */
617 for (j
= 0; j
< loccnt
; j
++)
619 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
620 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
623 size_t nelts
= vec_safe_length (saved_args
);
624 for (i
= 0; i
< nelts
; i
++)
626 t
= (*saved_args
)[i
];
627 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
630 TREE_CONSTANT (ctor
) = 1;
631 TREE_STATIC (ctor
) = 1;
632 DECL_INITIAL (var
) = ctor
;
633 varpool_node::finalize_decl (var
);
638 /* Instrument the __builtin_unreachable call. We just call the libubsan
642 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
645 location_t loc
= gimple_location (gsi_stmt (*gsi
));
647 if (flag_sanitize_undefined_trap_on_error
)
648 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
651 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
652 NULL_TREE
, NULL_TREE
);
653 data
= build_fold_addr_expr_loc (loc
, data
);
655 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
656 g
= gimple_build_call (fn
, 1, data
);
658 gimple_set_location (g
, loc
);
659 gsi_replace (gsi
, g
, false);
663 /* Return true if T is a call to a libubsan routine. */
666 is_ubsan_builtin_p (tree t
)
668 return TREE_CODE (t
) == FUNCTION_DECL
669 && fndecl_built_in_p (t
, BUILT_IN_NORMAL
)
670 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
671 "__builtin___ubsan_", 18) == 0;
674 /* Create a callgraph edge for statement STMT. */
677 ubsan_create_edge (gimple
*stmt
)
679 gcall
*call_stmt
= dyn_cast
<gcall
*> (stmt
);
680 basic_block bb
= gimple_bb (stmt
);
681 cgraph_node
*node
= cgraph_node::get (current_function_decl
);
682 tree decl
= gimple_call_fndecl (call_stmt
);
684 node
->create_edge (cgraph_node::get_create (decl
), call_stmt
, bb
->count
);
687 /* Expand the UBSAN_BOUNDS special builtin function. */
690 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
692 gimple
*stmt
= gsi_stmt (*gsi
);
693 location_t loc
= gimple_location (stmt
);
694 gcc_assert (gimple_call_num_args (stmt
) == 3);
696 /* Pick up the arguments of the UBSAN_BOUNDS call. */
697 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
698 tree index
= gimple_call_arg (stmt
, 1);
699 tree orig_index
= index
;
700 tree bound
= gimple_call_arg (stmt
, 2);
702 gimple_stmt_iterator gsi_orig
= *gsi
;
704 /* Create condition "if (index > bound)". */
705 basic_block then_bb
, fallthru_bb
;
706 gimple_stmt_iterator cond_insert_point
707 = create_cond_insert_point (gsi
, false, false, true,
708 &then_bb
, &fallthru_bb
);
709 index
= fold_convert (TREE_TYPE (bound
), index
);
710 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
712 false, GSI_NEW_STMT
);
713 gimple
*g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
714 gimple_set_location (g
, loc
);
715 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
717 /* Generate __ubsan_handle_out_of_bounds call. */
718 *gsi
= gsi_after_labels (then_bb
);
719 if (flag_sanitize_undefined_trap_on_error
)
720 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
724 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
725 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
726 ubsan_type_descriptor (TREE_TYPE (orig_index
)),
727 NULL_TREE
, NULL_TREE
);
728 data
= build_fold_addr_expr_loc (loc
, data
);
729 enum built_in_function bcode
730 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
731 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
732 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
733 tree fn
= builtin_decl_explicit (bcode
);
734 tree val
= ubsan_encode_value (orig_index
, UBSAN_ENCODE_VALUE_GIMPLE
);
735 val
= force_gimple_operand_gsi (gsi
, val
, true, NULL_TREE
, true,
737 g
= gimple_build_call (fn
, 2, data
, val
);
739 gimple_set_location (g
, loc
);
740 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
742 /* Get rid of the UBSAN_BOUNDS call from the IR. */
743 unlink_stmt_vdef (stmt
);
744 gsi_remove (&gsi_orig
, true);
746 /* Point GSI to next logical statement. */
747 *gsi
= gsi_start_bb (fallthru_bb
);
751 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
752 argument which is a constant, because the middle-end treats pointer
753 conversions as useless and therefore the type of the first argument
754 could be changed to any other pointer type. */
757 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
759 gimple_stmt_iterator gsi
= *gsip
;
760 gimple
*stmt
= gsi_stmt (gsi
);
761 location_t loc
= gimple_location (stmt
);
762 gcc_assert (gimple_call_num_args (stmt
) == 3);
763 tree ptr
= gimple_call_arg (stmt
, 0);
764 tree ckind
= gimple_call_arg (stmt
, 1);
765 tree align
= gimple_call_arg (stmt
, 2);
766 tree check_align
= NULL_TREE
;
769 basic_block cur_bb
= gsi_bb (gsi
);
772 if (!integer_zerop (align
))
774 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
775 if (compare_tree_int (align
, ptralign
) == 1)
777 check_align
= make_ssa_name (pointer_sized_int_node
);
778 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
779 gimple_set_location (g
, loc
);
780 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
783 check_null
= sanitize_flags_p (SANITIZE_NULL
);
785 if (check_align
== NULL_TREE
&& !check_null
)
787 gsi_remove (gsip
, true);
788 /* Unlink the UBSAN_NULLs vops before replacing it. */
789 unlink_stmt_vdef (stmt
);
793 /* Split the original block holding the pointer dereference. */
794 edge e
= split_block (cur_bb
, stmt
);
796 /* Get a hold on the 'condition block', the 'then block' and the
798 basic_block cond_bb
= e
->src
;
799 basic_block fallthru_bb
= e
->dest
;
800 basic_block then_bb
= create_empty_bb (cond_bb
);
801 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
802 loops_state_set (LOOPS_NEED_FIXUP
);
804 /* Make an edge coming from the 'cond block' into the 'then block';
805 this edge is unlikely taken, so set up the probability accordingly. */
806 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
807 e
->probability
= profile_probability::very_unlikely ();
808 then_bb
->count
= e
->count ();
810 /* Connect 'then block' with the 'else block'. This is needed
811 as the ubsan routines we call in the 'then block' are not noreturn.
812 The 'then block' only has one outcoming edge. */
813 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
815 /* Set up the fallthrough basic block. */
816 e
= find_edge (cond_bb
, fallthru_bb
);
817 e
->flags
= EDGE_FALSE_VALUE
;
818 e
->probability
= profile_probability::very_likely ();
820 /* Update dominance info for the newly created then_bb; note that
821 fallthru_bb's dominance info has already been updated by
823 if (dom_info_available_p (CDI_DOMINATORS
))
824 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
826 /* Put the ubsan builtin call into the newly created BB. */
827 if (flag_sanitize_undefined_trap_on_error
)
828 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
831 enum built_in_function bcode
832 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
833 | (check_null
? SANITIZE_NULL
: 0)))
834 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1
835 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_ABORT
;
836 tree fn
= builtin_decl_implicit (bcode
);
837 int align_log
= tree_log2 (align
);
839 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
840 ubsan_type_descriptor (TREE_TYPE (ckind
),
841 UBSAN_PRINT_POINTER
),
843 build_int_cst (unsigned_char_type_node
,
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);
874 /* Split the block with the condition again. */
875 e
= split_block (cond_bb
, stmt
);
876 basic_block cond1_bb
= e
->src
;
877 basic_block cond2_bb
= e
->dest
;
879 /* Make an edge coming from the 'cond1 block' into the 'then block';
880 this edge is unlikely taken, so set up the probability
882 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
883 e
->probability
= profile_probability::very_unlikely ();
885 /* Set up the fallthrough basic block. */
886 e
= find_edge (cond1_bb
, cond2_bb
);
887 e
->flags
= EDGE_FALSE_VALUE
;
888 e
->probability
= profile_probability::very_likely ();
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::to_widest (offset
) >= -OBJSZ_MAX_OFFSET
948 && 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::to_widest (offset
) >= 0
965 && 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 (unsigned_char_type_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_V1
1013 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_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
);
1026 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1027 unlink_stmt_vdef (stmt
);
1028 gsi_remove (&gsi_orig
, true);
1032 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1033 unlink_stmt_vdef (stmt
);
1034 gsi_remove (gsi
, true);
1038 /* Expand UBSAN_PTR internal call. */
1041 ubsan_expand_ptr_ifn (gimple_stmt_iterator
*gsip
)
1043 gimple_stmt_iterator gsi
= *gsip
;
1044 gimple
*stmt
= gsi_stmt (gsi
);
1045 location_t loc
= gimple_location (stmt
);
1046 gcc_assert (gimple_call_num_args (stmt
) == 2);
1047 tree ptr
= gimple_call_arg (stmt
, 0);
1048 tree off
= gimple_call_arg (stmt
, 1);
1050 if (integer_zerop (off
))
1052 gsi_remove (gsip
, true);
1053 unlink_stmt_vdef (stmt
);
1057 basic_block cur_bb
= gsi_bb (gsi
);
1058 tree ptrplusoff
= make_ssa_name (pointer_sized_int_node
);
1059 tree ptri
= make_ssa_name (pointer_sized_int_node
);
1060 int pos_neg
= get_range_pos_neg (off
);
1062 /* Split the original block holding the pointer dereference. */
1063 edge e
= split_block (cur_bb
, stmt
);
1065 /* Get a hold on the 'condition block', the 'then block' and the
1067 basic_block cond_bb
= e
->src
;
1068 basic_block fallthru_bb
= e
->dest
;
1069 basic_block then_bb
= create_empty_bb (cond_bb
);
1070 basic_block cond_pos_bb
= NULL
, cond_neg_bb
= NULL
;
1071 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
1072 loops_state_set (LOOPS_NEED_FIXUP
);
1074 /* Set up the fallthrough basic block. */
1075 e
->flags
= EDGE_FALSE_VALUE
;
1078 e
->probability
= profile_probability::very_likely ();
1080 /* Connect 'then block' with the 'else block'. This is needed
1081 as the ubsan routines we call in the 'then block' are not noreturn.
1082 The 'then block' only has one outcoming edge. */
1083 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
1085 /* Make an edge coming from the 'cond block' into the 'then block';
1086 this edge is unlikely taken, so set up the probability
1088 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
1089 e
->probability
= profile_probability::very_unlikely ();
1090 then_bb
->count
= e
->count ();
1094 e
->probability
= profile_probability::even ();
1096 e
= split_block (fallthru_bb
, (gimple
*) NULL
);
1097 cond_neg_bb
= e
->src
;
1098 fallthru_bb
= e
->dest
;
1099 e
->probability
= profile_probability::very_likely ();
1100 e
->flags
= EDGE_FALSE_VALUE
;
1102 e
= make_edge (cond_neg_bb
, then_bb
, EDGE_TRUE_VALUE
);
1103 e
->probability
= profile_probability::very_unlikely ();
1104 then_bb
->count
= e
->count ();
1106 cond_pos_bb
= create_empty_bb (cond_bb
);
1107 add_bb_to_loop (cond_pos_bb
, cond_bb
->loop_father
);
1109 e
= make_edge (cond_bb
, cond_pos_bb
, EDGE_TRUE_VALUE
);
1110 e
->probability
= profile_probability::even ();
1111 cond_pos_bb
->count
= e
->count ();
1113 e
= make_edge (cond_pos_bb
, then_bb
, EDGE_TRUE_VALUE
);
1114 e
->probability
= profile_probability::very_unlikely ();
1116 e
= make_edge (cond_pos_bb
, fallthru_bb
, EDGE_FALSE_VALUE
);
1117 e
->probability
= profile_probability::very_likely ();
1119 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
1122 gimple
*g
= gimple_build_assign (ptri
, NOP_EXPR
, ptr
);
1123 gimple_set_location (g
, loc
);
1124 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1125 g
= gimple_build_assign (ptrplusoff
, PLUS_EXPR
, ptri
, off
);
1126 gimple_set_location (g
, loc
);
1127 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1129 /* Update dominance info for the newly created then_bb; note that
1130 fallthru_bb's dominance info has already been updated by
1132 if (dom_info_available_p (CDI_DOMINATORS
))
1134 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
1137 set_immediate_dominator (CDI_DOMINATORS
, cond_pos_bb
, cond_bb
);
1138 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond_bb
);
1142 /* Put the ubsan builtin call into the newly created BB. */
1143 if (flag_sanitize_undefined_trap_on_error
)
1144 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
1147 enum built_in_function bcode
1148 = (flag_sanitize_recover
& SANITIZE_POINTER_OVERFLOW
)
1149 ? BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW
1150 : BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW_ABORT
;
1151 tree fn
= builtin_decl_implicit (bcode
);
1153 = ubsan_create_data ("__ubsan_ptrovf_data", 1, &loc
,
1154 NULL_TREE
, NULL_TREE
);
1155 data
= build_fold_addr_expr_loc (loc
, data
);
1156 g
= gimple_build_call (fn
, 3, data
, ptr
, ptrplusoff
);
1158 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
1159 gimple_set_location (g
, loc
);
1160 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
1162 /* Unlink the UBSAN_PTRs vops before replacing it. */
1163 unlink_stmt_vdef (stmt
);
1165 if (TREE_CODE (off
) == INTEGER_CST
)
1166 g
= gimple_build_cond (wi::neg_p (wi::to_wide (off
)) ? LT_EXPR
: GE_EXPR
,
1167 ptri
, fold_build1 (NEGATE_EXPR
, sizetype
, off
),
1168 NULL_TREE
, NULL_TREE
);
1169 else if (pos_neg
!= 3)
1170 g
= gimple_build_cond (pos_neg
== 1 ? LT_EXPR
: GT_EXPR
,
1171 ptrplusoff
, ptri
, NULL_TREE
, NULL_TREE
);
1174 gsi2
= gsi_start_bb (cond_pos_bb
);
1175 g
= gimple_build_cond (LT_EXPR
, ptrplusoff
, ptri
, NULL_TREE
, NULL_TREE
);
1176 gimple_set_location (g
, loc
);
1177 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
1179 gsi2
= gsi_start_bb (cond_neg_bb
);
1180 g
= gimple_build_cond (GT_EXPR
, ptrplusoff
, ptri
, NULL_TREE
, NULL_TREE
);
1181 gimple_set_location (g
, loc
);
1182 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
1184 gimple_seq seq
= NULL
;
1185 tree t
= gimple_build (&seq
, loc
, NOP_EXPR
, ssizetype
, off
);
1186 t
= gimple_build (&seq
, loc
, GE_EXPR
, boolean_type_node
,
1188 gsi_insert_seq_before (&gsi
, seq
, GSI_SAME_STMT
);
1189 g
= gimple_build_cond (NE_EXPR
, t
, boolean_false_node
,
1190 NULL_TREE
, NULL_TREE
);
1192 gimple_set_location (g
, loc
);
1193 /* Replace the UBSAN_PTR with a GIMPLE_COND stmt. */
1194 gsi_replace (&gsi
, g
, false);
1199 /* Cached __ubsan_vptr_type_cache decl. */
1200 static GTY(()) tree ubsan_vptr_type_cache_decl
;
1202 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1203 argument which is a constant, because the middle-end treats pointer
1204 conversions as useless and therefore the type of the first argument
1205 could be changed to any other pointer type. */
1208 ubsan_expand_vptr_ifn (gimple_stmt_iterator
*gsip
)
1210 gimple_stmt_iterator gsi
= *gsip
;
1211 gimple
*stmt
= gsi_stmt (gsi
);
1212 location_t loc
= gimple_location (stmt
);
1213 gcc_assert (gimple_call_num_args (stmt
) == 5);
1214 tree op
= gimple_call_arg (stmt
, 0);
1215 tree vptr
= gimple_call_arg (stmt
, 1);
1216 tree str_hash
= gimple_call_arg (stmt
, 2);
1217 tree ti_decl_addr
= gimple_call_arg (stmt
, 3);
1218 tree ckind_tree
= gimple_call_arg (stmt
, 4);
1219 ubsan_null_ckind ckind
= (ubsan_null_ckind
) tree_to_uhwi (ckind_tree
);
1220 tree type
= TREE_TYPE (TREE_TYPE (ckind_tree
));
1222 basic_block fallthru_bb
= NULL
;
1224 if (ckind
== UBSAN_DOWNCAST_POINTER
)
1226 /* Guard everything with if (op != NULL) { ... }. */
1227 basic_block then_bb
;
1228 gimple_stmt_iterator cond_insert_point
1229 = create_cond_insert_point (gsip
, false, false, true,
1230 &then_bb
, &fallthru_bb
);
1231 g
= gimple_build_cond (NE_EXPR
, op
, build_zero_cst (TREE_TYPE (op
)),
1232 NULL_TREE
, NULL_TREE
);
1233 gimple_set_location (g
, loc
);
1234 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1235 *gsip
= gsi_after_labels (then_bb
);
1236 gsi_remove (&gsi
, false);
1237 gsi_insert_before (gsip
, stmt
, GSI_NEW_STMT
);
1241 tree htype
= TREE_TYPE (str_hash
);
1242 tree cst
= wide_int_to_tree (htype
,
1243 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1245 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1247 gimple_set_location (g
, loc
);
1248 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1249 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1250 gimple_assign_lhs (g
), cst
);
1251 gimple_set_location (g
, loc
);
1252 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1253 tree t1
= gimple_assign_lhs (g
);
1254 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1255 t1
, build_int_cst (integer_type_node
, 47));
1256 gimple_set_location (g
, loc
);
1257 tree t2
= gimple_assign_lhs (g
);
1258 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1259 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1261 gimple_set_location (g
, loc
);
1262 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1263 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1264 t2
, gimple_assign_lhs (g
));
1265 gimple_set_location (g
, loc
);
1266 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1267 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1268 gimple_assign_lhs (g
), cst
);
1269 gimple_set_location (g
, loc
);
1270 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1271 tree t3
= gimple_assign_lhs (g
);
1272 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1273 t3
, build_int_cst (integer_type_node
, 47));
1274 gimple_set_location (g
, loc
);
1275 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1276 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1277 t3
, gimple_assign_lhs (g
));
1278 gimple_set_location (g
, loc
);
1279 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1280 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1281 gimple_assign_lhs (g
), cst
);
1282 gimple_set_location (g
, loc
);
1283 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1284 if (!useless_type_conversion_p (pointer_sized_int_node
, htype
))
1286 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1287 NOP_EXPR
, gimple_assign_lhs (g
));
1288 gimple_set_location (g
, loc
);
1289 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1291 tree hash
= gimple_assign_lhs (g
);
1293 if (ubsan_vptr_type_cache_decl
== NULL_TREE
)
1295 tree atype
= build_array_type_nelts (pointer_sized_int_node
, 128);
1296 tree array
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1297 get_identifier ("__ubsan_vptr_type_cache"),
1299 DECL_ARTIFICIAL (array
) = 1;
1300 DECL_IGNORED_P (array
) = 1;
1301 TREE_PUBLIC (array
) = 1;
1302 TREE_STATIC (array
) = 1;
1303 DECL_EXTERNAL (array
) = 1;
1304 DECL_VISIBILITY (array
) = VISIBILITY_DEFAULT
;
1305 DECL_VISIBILITY_SPECIFIED (array
) = 1;
1306 varpool_node::finalize_decl (array
);
1307 ubsan_vptr_type_cache_decl
= array
;
1310 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1312 build_int_cst (pointer_sized_int_node
, 127));
1313 gimple_set_location (g
, loc
);
1314 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1316 tree c
= build4_loc (loc
, ARRAY_REF
, pointer_sized_int_node
,
1317 ubsan_vptr_type_cache_decl
, gimple_assign_lhs (g
),
1318 NULL_TREE
, NULL_TREE
);
1319 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1321 gimple_set_location (g
, loc
);
1322 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1324 basic_block then_bb
, fallthru2_bb
;
1325 gimple_stmt_iterator cond_insert_point
1326 = create_cond_insert_point (gsip
, false, false, true,
1327 &then_bb
, &fallthru2_bb
);
1328 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
), hash
,
1329 NULL_TREE
, NULL_TREE
);
1330 gimple_set_location (g
, loc
);
1331 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1332 *gsip
= gsi_after_labels (then_bb
);
1333 if (fallthru_bb
== NULL
)
1334 fallthru_bb
= fallthru2_bb
;
1337 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc
,
1338 ubsan_type_descriptor (type
), NULL_TREE
, ti_decl_addr
,
1339 build_int_cst (unsigned_char_type_node
, ckind
),
1341 data
= build_fold_addr_expr_loc (loc
, data
);
1342 enum built_in_function bcode
1343 = (flag_sanitize_recover
& SANITIZE_VPTR
)
1344 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1345 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT
;
1347 g
= gimple_build_call (builtin_decl_explicit (bcode
), 3, data
, op
, hash
);
1348 gimple_set_location (g
, loc
);
1349 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1351 /* Point GSI to next logical statement. */
1352 *gsip
= gsi_start_bb (fallthru_bb
);
1354 /* Get rid of the UBSAN_VPTR call from the IR. */
1355 unlink_stmt_vdef (stmt
);
1356 gsi_remove (&gsi
, true);
1360 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1361 whether the pointer is on the left hand side of the assignment. */
1364 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
1367 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
1368 unsigned int align
= 0;
1369 if (sanitize_flags_p (SANITIZE_ALIGNMENT
))
1371 align
= min_align_of_type (TREE_TYPE (base
));
1375 if (align
== 0 && !sanitize_flags_p (SANITIZE_NULL
))
1377 tree t
= TREE_OPERAND (base
, 0);
1378 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
1380 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base
)) && mem
!= base
)
1381 ikind
= UBSAN_MEMBER_ACCESS
;
1382 tree kind
= build_int_cst (build_pointer_type (TREE_TYPE (base
)), ikind
);
1383 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
1384 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
1385 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
1386 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
1389 /* Perform the pointer instrumentation. */
1392 instrument_null (gimple_stmt_iterator gsi
, tree t
, bool is_lhs
)
1394 /* Handle also e.g. &s->i. */
1395 if (TREE_CODE (t
) == ADDR_EXPR
)
1396 t
= TREE_OPERAND (t
, 0);
1397 tree base
= get_base_address (t
);
1398 if (base
!= NULL_TREE
1399 && TREE_CODE (base
) == MEM_REF
1400 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1401 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1404 /* Instrument pointer arithmetics PTR p+ OFF. */
1407 instrument_pointer_overflow (gimple_stmt_iterator
*gsi
, tree ptr
, tree off
)
1409 if (TYPE_PRECISION (sizetype
) != POINTER_SIZE
)
1411 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_PTR
, 2, ptr
, off
);
1412 gimple_set_location (g
, gimple_location (gsi_stmt (*gsi
)));
1413 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1416 /* Instrument pointer arithmetics if any. */
1419 maybe_instrument_pointer_overflow (gimple_stmt_iterator
*gsi
, tree t
)
1421 if (TYPE_PRECISION (sizetype
) != POINTER_SIZE
)
1424 /* Handle also e.g. &s->i. */
1425 if (TREE_CODE (t
) == ADDR_EXPR
)
1426 t
= TREE_OPERAND (t
, 0);
1428 if (!handled_component_p (t
) && TREE_CODE (t
) != MEM_REF
)
1431 poly_int64 bitsize
, bitpos
, bytepos
;
1434 int volatilep
= 0, reversep
, unsignedp
= 0;
1435 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1436 &unsignedp
, &reversep
, &volatilep
);
1437 tree moff
= NULL_TREE
;
1439 bool decl_p
= DECL_P (inner
);
1443 if (DECL_REGISTER (inner
))
1446 /* If BASE is a fixed size automatic variable or
1447 global variable defined in the current TU and bitpos
1448 fits, don't instrument anything. */
1449 poly_int64 base_size
;
1450 if (offset
== NULL_TREE
1451 && maybe_ne (bitpos
, 0)
1453 || TREE_CODE (base
) == PARM_DECL
1454 || TREE_CODE (base
) == RESULT_DECL
)
1455 && poly_int_tree_p (DECL_SIZE (base
), &base_size
)
1456 && known_ge (base_size
, bitpos
)
1457 && (!is_global_var (base
) || decl_binds_to_current_def_p (base
)))
1460 else if (TREE_CODE (inner
) == MEM_REF
)
1462 base
= TREE_OPERAND (inner
, 0);
1463 if (TREE_CODE (base
) == ADDR_EXPR
1464 && DECL_P (TREE_OPERAND (base
, 0))
1465 && !TREE_ADDRESSABLE (TREE_OPERAND (base
, 0))
1466 && !is_global_var (TREE_OPERAND (base
, 0)))
1468 moff
= TREE_OPERAND (inner
, 1);
1469 if (integer_zerop (moff
))
1475 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1477 bytepos
= bits_to_bytes_round_down (bitpos
);
1478 if (offset
== NULL_TREE
&& known_eq (bytepos
, 0) && moff
== NULL_TREE
)
1481 tree base_addr
= base
;
1483 base_addr
= build1 (ADDR_EXPR
,
1484 build_pointer_type (TREE_TYPE (base
)), base
);
1486 if (maybe_ne (bytepos
, 0))
1489 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t
,
1490 build_int_cst (TREE_TYPE (t
), bytepos
));
1492 t
= size_int (bytepos
);
1497 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t
,
1498 fold_convert (TREE_TYPE (t
), moff
));
1500 t
= fold_convert (sizetype
, moff
);
1502 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1504 base_addr
= force_gimple_operand_gsi (gsi
, base_addr
, true, NULL_TREE
, true,
1506 instrument_pointer_overflow (gsi
, base_addr
, t
);
1509 /* Build an ubsan builtin call for the signed-integer-overflow
1510 sanitization. CODE says what kind of builtin are we building,
1511 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1512 are operands of the binary operation. */
1515 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1516 tree op0
, tree op1
, tree
*datap
)
1518 if (flag_sanitize_undefined_trap_on_error
)
1519 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1522 if (datap
&& *datap
)
1525 data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1526 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1530 enum built_in_function fn_code
;
1535 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1536 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1537 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1540 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1541 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1542 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1545 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1546 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1547 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1550 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1551 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1552 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1557 tree fn
= builtin_decl_explicit (fn_code
);
1558 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1559 build_fold_addr_expr_loc (loc
, data
),
1560 ubsan_encode_value (op0
, UBSAN_ENCODE_VALUE_RTL
),
1562 ? ubsan_encode_value (op1
,
1563 UBSAN_ENCODE_VALUE_RTL
)
1567 /* Perform the signed integer instrumentation. GSI is the iterator
1568 pointing at statement we are trying to instrument. */
1571 instrument_si_overflow (gimple_stmt_iterator gsi
)
1573 gimple
*stmt
= gsi_stmt (gsi
);
1574 tree_code code
= gimple_assign_rhs_code (stmt
);
1575 tree lhs
= gimple_assign_lhs (stmt
);
1576 tree lhstype
= TREE_TYPE (lhs
);
1577 tree lhsinner
= VECTOR_TYPE_P (lhstype
) ? TREE_TYPE (lhstype
) : lhstype
;
1581 /* If this is not a signed operation, don't instrument anything here.
1582 Also punt on bit-fields. */
1583 if (!INTEGRAL_TYPE_P (lhsinner
)
1584 || TYPE_OVERFLOW_WRAPS (lhsinner
)
1585 || maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (lhsinner
)),
1586 TYPE_PRECISION (lhsinner
)))
1597 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1598 a
= gimple_assign_rhs1 (stmt
);
1599 b
= gimple_assign_rhs2 (stmt
);
1600 g
= gimple_build_call_internal (code
== PLUS_EXPR
1601 ? IFN_UBSAN_CHECK_ADD
1602 : code
== MINUS_EXPR
1603 ? IFN_UBSAN_CHECK_SUB
1604 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1605 gimple_call_set_lhs (g
, lhs
);
1606 gsi_replace (&gsi
, g
, true);
1609 /* Represent i = -u;
1611 i = UBSAN_CHECK_SUB (0, u); */
1612 a
= build_zero_cst (lhstype
);
1613 b
= gimple_assign_rhs1 (stmt
);
1614 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1615 gimple_call_set_lhs (g
, lhs
);
1616 gsi_replace (&gsi
, g
, true);
1619 /* Transform i = ABS_EXPR<u>;
1621 _N = UBSAN_CHECK_SUB (0, u);
1622 i = ABS_EXPR<_N>; */
1623 a
= build_zero_cst (lhstype
);
1624 b
= gimple_assign_rhs1 (stmt
);
1625 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1626 a
= make_ssa_name (lhstype
);
1627 gimple_call_set_lhs (g
, a
);
1628 gimple_set_location (g
, gimple_location (stmt
));
1629 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1630 gimple_assign_set_rhs1 (stmt
, a
);
1638 /* Instrument loads from (non-bitfield) bool and C++ enum values
1639 to check if the memory value is outside of the range of the valid
1643 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1645 gimple
*stmt
= gsi_stmt (*gsi
);
1646 tree rhs
= gimple_assign_rhs1 (stmt
);
1647 tree type
= TREE_TYPE (rhs
);
1648 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1650 if (TREE_CODE (type
) == BOOLEAN_TYPE
1651 && sanitize_flags_p (SANITIZE_BOOL
))
1653 minv
= boolean_false_node
;
1654 maxv
= boolean_true_node
;
1656 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1657 && sanitize_flags_p (SANITIZE_ENUM
)
1658 && TREE_TYPE (type
) != NULL_TREE
1659 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1660 && (TYPE_PRECISION (TREE_TYPE (type
))
1661 < GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (type
))))
1663 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1664 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1669 int modebitsize
= GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type
));
1670 poly_int64 bitsize
, bitpos
;
1673 int volatilep
= 0, reversep
, unsignedp
= 0;
1674 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1675 &unsignedp
, &reversep
, &volatilep
);
1676 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1678 if ((VAR_P (base
) && DECL_HARD_REGISTER (base
))
1679 || !multiple_p (bitpos
, modebitsize
)
1680 || maybe_ne (bitsize
, modebitsize
)
1681 || GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (utype
)) != modebitsize
1682 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1685 bool ends_bb
= stmt_ends_bb_p (stmt
);
1686 location_t loc
= gimple_location (stmt
);
1687 tree lhs
= gimple_assign_lhs (stmt
);
1688 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1689 tree atype
= reference_alias_ptr_type (rhs
);
1690 gimple
*g
= gimple_build_assign (make_ssa_name (ptype
),
1691 build_fold_addr_expr (rhs
));
1692 gimple_set_location (g
, loc
);
1693 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1694 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1695 build_int_cst (atype
, 0));
1696 tree urhs
= make_ssa_name (utype
);
1699 gimple_assign_set_lhs (stmt
, urhs
);
1700 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1701 gimple_set_location (g
, loc
);
1702 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1703 gsi_insert_on_edge_immediate (e
, g
);
1704 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1706 *gsi
= gsi_for_stmt (g
);
1711 g
= gimple_build_assign (urhs
, mem
);
1712 gimple_set_location (g
, loc
);
1713 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1715 minv
= fold_convert (utype
, minv
);
1716 maxv
= fold_convert (utype
, maxv
);
1717 if (!integer_zerop (minv
))
1719 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1720 gimple_set_location (g
, loc
);
1721 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1724 gimple_stmt_iterator gsi2
= *gsi
;
1725 basic_block then_bb
, fallthru_bb
;
1726 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1727 &then_bb
, &fallthru_bb
);
1728 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1729 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1730 NULL_TREE
, NULL_TREE
);
1731 gimple_set_location (g
, loc
);
1732 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1736 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1740 gsi2
= gsi_after_labels (then_bb
);
1741 if (flag_sanitize_undefined_trap_on_error
)
1742 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1745 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1746 ubsan_type_descriptor (type
), NULL_TREE
,
1748 data
= build_fold_addr_expr_loc (loc
, data
);
1749 enum built_in_function bcode
1750 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1751 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1752 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1753 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1754 tree fn
= builtin_decl_explicit (bcode
);
1756 tree val
= ubsan_encode_value (urhs
, UBSAN_ENCODE_VALUE_GIMPLE
);
1757 val
= force_gimple_operand_gsi (&gsi2
, val
, true, NULL_TREE
, true,
1759 g
= gimple_build_call (fn
, 2, data
, val
);
1761 gimple_set_location (g
, loc
);
1762 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1763 ubsan_create_edge (g
);
1764 *gsi
= gsi_for_stmt (stmt
);
1767 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1768 new style handlers. Libubsan uses heuristics to destinguish between old and
1769 new styles and relies on these properties for filename:
1771 a) Location's filename must not be NULL.
1772 b) Location's filename must not be equal to "".
1773 c) Location's filename must not be equal to "\1".
1774 d) First two bytes of filename must not contain '\xff' symbol. */
1777 ubsan_use_new_style_p (location_t loc
)
1779 if (loc
== UNKNOWN_LOCATION
)
1782 expanded_location xloc
= expand_location (loc
);
1783 if (xloc
.file
== NULL
|| strncmp (xloc
.file
, "\1", 2) == 0
1784 || xloc
.file
[0] == '\0' || xloc
.file
[0] == '\xff'
1785 || xloc
.file
[1] == '\xff')
1791 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1792 destination, EXPR is floating-point expression. */
1795 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
)
1797 tree expr_type
= TREE_TYPE (expr
);
1798 tree t
, tt
, fn
, min
, max
;
1799 machine_mode mode
= TYPE_MODE (expr_type
);
1800 int prec
= TYPE_PRECISION (type
);
1801 bool uns_p
= TYPE_UNSIGNED (type
);
1802 if (loc
== UNKNOWN_LOCATION
)
1803 loc
= input_location
;
1805 /* Float to integer conversion first truncates toward zero, so
1806 even signed char c = 127.875f; is not problematic.
1807 Therefore, we should complain only if EXPR is unordered or smaller
1808 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1809 TYPE_MAX_VALUE + 1.0. */
1810 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1812 /* For maximum, TYPE_MAX_VALUE might not be representable
1813 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1814 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1815 either representable or infinity. */
1816 REAL_VALUE_TYPE maxval
= dconst1
;
1817 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1818 real_convert (&maxval
, mode
, &maxval
);
1819 max
= build_real (expr_type
, maxval
);
1821 /* For unsigned, assume -1.0 is always representable. */
1823 min
= build_minus_one_cst (expr_type
);
1826 /* TYPE_MIN_VALUE is generally representable (or -inf),
1827 but TYPE_MIN_VALUE - 1.0 might not be. */
1828 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1829 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1830 real_convert (&minval
, mode
, &minval
);
1831 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1832 real_convert (&minval2
, mode
, &minval2
);
1833 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1834 && !real_isinf (&minval
))
1836 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1837 rounds to TYPE_MIN_VALUE, we need to subtract
1838 more. As REAL_MODE_FORMAT (mode)->p is the number
1839 of base digits, we want to subtract a number that
1840 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1841 times smaller than minval. */
1843 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1844 SET_REAL_EXP (&minval2
,
1845 REAL_EXP (&minval2
) + prec
- 1
1846 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1847 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1848 real_convert (&minval2
, mode
, &minval2
);
1850 min
= build_real (expr_type
, minval2
);
1853 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1855 /* For _Decimal128 up to 34 decimal digits, - sign,
1856 dot, e, exponent. */
1859 int p
= REAL_MODE_FORMAT (mode
)->p
;
1860 REAL_VALUE_TYPE maxval
, minval
;
1862 /* Use mpfr_snprintf rounding to compute the smallest
1863 representable decimal number greater or equal than
1864 1 << (prec - !uns_p). */
1865 mpfr_init2 (m
, prec
+ 2);
1866 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, MPFR_RNDN
);
1867 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1868 decimal_real_from_string (&maxval
, buf
);
1869 max
= build_real (expr_type
, maxval
);
1871 /* For unsigned, assume -1.0 is always representable. */
1873 min
= build_minus_one_cst (expr_type
);
1876 /* Use mpfr_snprintf rounding to compute the largest
1877 representable decimal number less or equal than
1878 (-1 << (prec - 1)) - 1. */
1879 mpfr_set_si_2exp (m
, -1, prec
- 1, MPFR_RNDN
);
1880 mpfr_sub_ui (m
, m
, 1, MPFR_RNDN
);
1881 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1882 decimal_real_from_string (&minval
, buf
);
1883 min
= build_real (expr_type
, minval
);
1890 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1891 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1892 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
);
1893 if (integer_zerop (t
))
1896 if (flag_sanitize_undefined_trap_on_error
)
1897 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1900 location_t
*loc_ptr
= NULL
;
1901 unsigned num_locations
= 0;
1902 /* Figure out if we can propagate location to ubsan_data and use new
1903 style handlers in libubsan. */
1904 if (ubsan_use_new_style_p (loc
))
1909 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1910 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data",
1911 num_locations
, loc_ptr
,
1912 ubsan_type_descriptor (expr_type
),
1913 ubsan_type_descriptor (type
), NULL_TREE
,
1915 enum built_in_function bcode
1916 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1917 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1918 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1919 fn
= builtin_decl_explicit (bcode
);
1920 fn
= build_call_expr_loc (loc
, fn
, 2,
1921 build_fold_addr_expr_loc (loc
, data
),
1922 ubsan_encode_value (expr
));
1925 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1928 /* Instrument values passed to function arguments with nonnull attribute. */
1931 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1933 gimple
*stmt
= gsi_stmt (*gsi
);
1935 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1936 while for nonnull sanitization it is clear. */
1937 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1938 flag_delete_null_pointer_checks
= 1;
1939 loc
[0] = gimple_location (stmt
);
1940 loc
[1] = UNKNOWN_LOCATION
;
1941 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1943 tree arg
= gimple_call_arg (stmt
, i
);
1944 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1945 && infer_nonnull_range_by_attribute (stmt
, arg
))
1948 if (!is_gimple_val (arg
))
1950 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1951 gimple_set_location (g
, loc
[0]);
1952 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1953 arg
= gimple_assign_lhs (g
);
1956 basic_block then_bb
, fallthru_bb
;
1957 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1958 &then_bb
, &fallthru_bb
);
1959 g
= gimple_build_cond (EQ_EXPR
, arg
,
1960 build_zero_cst (TREE_TYPE (arg
)),
1961 NULL_TREE
, NULL_TREE
);
1962 gimple_set_location (g
, loc
[0]);
1963 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1965 *gsi
= gsi_after_labels (then_bb
);
1966 if (flag_sanitize_undefined_trap_on_error
)
1967 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1970 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1972 build_int_cst (integer_type_node
,
1975 data
= build_fold_addr_expr_loc (loc
[0], data
);
1976 enum built_in_function bcode
1977 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1978 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1979 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1980 tree fn
= builtin_decl_explicit (bcode
);
1982 g
= gimple_build_call (fn
, 1, data
);
1984 gimple_set_location (g
, loc
[0]);
1985 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1986 ubsan_create_edge (g
);
1988 *gsi
= gsi_for_stmt (stmt
);
1990 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1993 /* Instrument returns in functions with returns_nonnull attribute. */
1996 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1998 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
2000 tree arg
= gimple_return_retval (stmt
);
2001 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
2002 while for nonnull return sanitization it is clear. */
2003 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
2004 flag_delete_null_pointer_checks
= 1;
2005 loc
[0] = gimple_location (stmt
);
2006 loc
[1] = UNKNOWN_LOCATION
;
2008 && POINTER_TYPE_P (TREE_TYPE (arg
))
2009 && is_gimple_val (arg
)
2010 && infer_nonnull_range_by_attribute (stmt
, arg
))
2012 basic_block then_bb
, fallthru_bb
;
2013 *gsi
= create_cond_insert_point (gsi
, true, false, true,
2014 &then_bb
, &fallthru_bb
);
2015 gimple
*g
= gimple_build_cond (EQ_EXPR
, arg
,
2016 build_zero_cst (TREE_TYPE (arg
)),
2017 NULL_TREE
, NULL_TREE
);
2018 gimple_set_location (g
, loc
[0]);
2019 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
2021 *gsi
= gsi_after_labels (then_bb
);
2022 if (flag_sanitize_undefined_trap_on_error
)
2023 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
2026 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
2027 1, &loc
[1], NULL_TREE
, NULL_TREE
);
2028 data
= build_fold_addr_expr_loc (loc
[0], data
);
2029 tree data2
= ubsan_create_data ("__ubsan_nonnull_return_data",
2030 1, &loc
[0], NULL_TREE
, NULL_TREE
);
2031 data2
= build_fold_addr_expr_loc (loc
[0], data2
);
2032 enum built_in_function bcode
2033 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
2034 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1
2035 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1_ABORT
;
2036 tree fn
= builtin_decl_explicit (bcode
);
2038 g
= gimple_build_call (fn
, 2, data
, data2
);
2040 gimple_set_location (g
, loc
[0]);
2041 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
2042 ubsan_create_edge (g
);
2043 *gsi
= gsi_for_stmt (stmt
);
2045 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
2048 /* Instrument memory references. Here we check whether the pointer
2049 points to an out-of-bounds location. */
2052 instrument_object_size (gimple_stmt_iterator
*gsi
, tree t
, bool is_lhs
)
2054 gimple
*stmt
= gsi_stmt (*gsi
);
2055 location_t loc
= gimple_location (stmt
);
2057 tree index
= NULL_TREE
;
2058 HOST_WIDE_INT size_in_bytes
;
2060 type
= TREE_TYPE (t
);
2061 if (VOID_TYPE_P (type
))
2064 switch (TREE_CODE (t
))
2067 if (TREE_CODE (t
) == COMPONENT_REF
2068 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
2070 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
2071 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
2072 repr
, TREE_OPERAND (t
, 2));
2076 index
= TREE_OPERAND (t
, 1);
2088 size_in_bytes
= int_size_in_bytes (type
);
2089 if (size_in_bytes
<= 0)
2092 poly_int64 bitsize
, bitpos
;
2095 int volatilep
= 0, reversep
, unsignedp
= 0;
2096 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
2097 &unsignedp
, &reversep
, &volatilep
);
2099 if (!multiple_p (bitpos
, BITS_PER_UNIT
)
2100 || maybe_ne (bitsize
, size_in_bytes
* BITS_PER_UNIT
))
2103 bool decl_p
= DECL_P (inner
);
2107 if (DECL_REGISTER (inner
))
2111 else if (TREE_CODE (inner
) == MEM_REF
)
2112 base
= TREE_OPERAND (inner
, 0);
2115 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
2117 while (TREE_CODE (base
) == SSA_NAME
)
2119 gimple
*def_stmt
= SSA_NAME_DEF_STMT (base
);
2120 if (gimple_assign_ssa_name_copy_p (def_stmt
)
2121 || (gimple_assign_cast_p (def_stmt
)
2122 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
2123 || (is_gimple_assign (def_stmt
)
2124 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
2126 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
2127 if (TREE_CODE (rhs1
) == SSA_NAME
2128 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
2137 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
2141 tree base_addr
= base
;
2142 gimple
*bos_stmt
= NULL
;
2144 base_addr
= build1 (ADDR_EXPR
,
2145 build_pointer_type (TREE_TYPE (base
)), base
);
2146 unsigned HOST_WIDE_INT size
;
2147 if (compute_builtin_object_size (base_addr
, 0, &size
))
2148 sizet
= build_int_cst (sizetype
, size
);
2151 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
2152 loc
= input_location
;
2153 /* Generate __builtin_object_size call. */
2154 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
2155 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
2157 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
2159 /* If the call above didn't end up being an integer constant, go one
2160 statement back and get the __builtin_object_size stmt. Save it,
2161 we might need it later. */
2162 if (SSA_VAR_P (sizet
))
2165 bos_stmt
= gsi_stmt (*gsi
);
2167 /* Move on to where we were. */
2174 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
2176 /* ptr + sizeof (*ptr) - base */
2177 t
= fold_build2 (MINUS_EXPR
, sizetype
,
2178 fold_convert (pointer_sized_int_node
, ptr
),
2179 fold_convert (pointer_sized_int_node
, base_addr
));
2180 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
2182 /* Perhaps we can omit the check. */
2183 if (TREE_CODE (t
) == INTEGER_CST
2184 && TREE_CODE (sizet
) == INTEGER_CST
2185 && tree_int_cst_le (t
, sizet
))
2188 if (index
!= NULL_TREE
2189 && TREE_CODE (index
) == SSA_NAME
2190 && TREE_CODE (sizet
) == INTEGER_CST
)
2192 gimple
*def
= SSA_NAME_DEF_STMT (index
);
2193 if (is_gimple_assign (def
)
2194 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
2195 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
2197 tree cst
= gimple_assign_rhs2 (def
);
2198 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
2199 TYPE_SIZE_UNIT (type
));
2200 if (tree_int_cst_sgn (cst
) >= 0
2201 && tree_int_cst_lt (cst
, sz
))
2206 if (bos_stmt
&& gimple_call_builtin_p (bos_stmt
, BUILT_IN_OBJECT_SIZE
))
2207 ubsan_create_edge (bos_stmt
);
2209 /* We have to emit the check. */
2210 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
2212 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
2214 tree ckind
= build_int_cst (unsigned_char_type_node
,
2215 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
2216 gimple
*g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
2217 ptr
, t
, sizet
, ckind
);
2218 gimple_set_location (g
, loc
);
2219 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
2222 /* Instrument values passed to builtin functions. */
2225 instrument_builtin (gimple_stmt_iterator
*gsi
)
2227 gimple
*stmt
= gsi_stmt (*gsi
);
2228 location_t loc
= gimple_location (stmt
);
2230 enum built_in_function fcode
2231 = DECL_FUNCTION_CODE (gimple_call_fndecl (stmt
));
2235 CASE_INT_FN (BUILT_IN_CLZ
):
2238 CASE_INT_FN (BUILT_IN_CTZ
):
2239 arg
= gimple_call_arg (stmt
, 0);
2240 if (!integer_nonzerop (arg
))
2243 if (!is_gimple_val (arg
))
2245 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
2246 gimple_set_location (g
, loc
);
2247 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
2248 arg
= gimple_assign_lhs (g
);
2251 basic_block then_bb
, fallthru_bb
;
2252 *gsi
= create_cond_insert_point (gsi
, true, false, true,
2253 &then_bb
, &fallthru_bb
);
2254 g
= gimple_build_cond (EQ_EXPR
, arg
,
2255 build_zero_cst (TREE_TYPE (arg
)),
2256 NULL_TREE
, NULL_TREE
);
2257 gimple_set_location (g
, loc
);
2258 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
2260 *gsi
= gsi_after_labels (then_bb
);
2261 if (flag_sanitize_undefined_trap_on_error
)
2262 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
2265 tree t
= build_int_cst (unsigned_char_type_node
, kind
);
2266 tree data
= ubsan_create_data ("__ubsan_builtin_data",
2267 1, &loc
, NULL_TREE
, t
, NULL_TREE
);
2268 data
= build_fold_addr_expr_loc (loc
, data
);
2269 enum built_in_function bcode
2270 = (flag_sanitize_recover
& SANITIZE_BUILTIN
)
2271 ? BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN
2272 : BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN_ABORT
;
2273 tree fn
= builtin_decl_explicit (bcode
);
2275 g
= gimple_build_call (fn
, 1, data
);
2277 gimple_set_location (g
, loc
);
2278 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
2279 ubsan_create_edge (g
);
2281 *gsi
= gsi_for_stmt (stmt
);
2290 const pass_data pass_data_ubsan
=
2292 GIMPLE_PASS
, /* type */
2294 OPTGROUP_NONE
, /* optinfo_flags */
2295 TV_TREE_UBSAN
, /* tv_id */
2296 ( PROP_cfg
| PROP_ssa
), /* properties_required */
2297 0, /* properties_provided */
2298 0, /* properties_destroyed */
2299 0, /* todo_flags_start */
2300 TODO_update_ssa
, /* todo_flags_finish */
2303 class pass_ubsan
: public gimple_opt_pass
2306 pass_ubsan (gcc::context
*ctxt
)
2307 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
2310 /* opt_pass methods: */
2311 virtual bool gate (function
*)
2313 return sanitize_flags_p ((SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
2314 | SANITIZE_BOOL
| SANITIZE_ENUM
2315 | SANITIZE_ALIGNMENT
2316 | SANITIZE_NONNULL_ATTRIBUTE
2317 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
2318 | SANITIZE_OBJECT_SIZE
2319 | SANITIZE_POINTER_OVERFLOW
2320 | SANITIZE_BUILTIN
));
2323 virtual unsigned int execute (function
*);
2325 }; // class pass_ubsan
2328 pass_ubsan::execute (function
*fun
)
2331 gimple_stmt_iterator gsi
;
2332 unsigned int ret
= 0;
2334 initialize_sanitizer_builtins ();
2336 FOR_EACH_BB_FN (bb
, fun
)
2338 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
2340 gimple
*stmt
= gsi_stmt (gsi
);
2341 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
2347 if ((sanitize_flags_p (SANITIZE_SI_OVERFLOW
, fun
->decl
))
2348 && is_gimple_assign (stmt
))
2349 instrument_si_overflow (gsi
);
2351 if (sanitize_flags_p (SANITIZE_NULL
| SANITIZE_ALIGNMENT
, fun
->decl
))
2353 if (gimple_store_p (stmt
))
2354 instrument_null (gsi
, gimple_get_lhs (stmt
), true);
2355 if (gimple_assign_single_p (stmt
))
2356 instrument_null (gsi
, gimple_assign_rhs1 (stmt
), false);
2357 if (is_gimple_call (stmt
))
2359 unsigned args_num
= gimple_call_num_args (stmt
);
2360 for (unsigned i
= 0; i
< args_num
; ++i
)
2362 tree arg
= gimple_call_arg (stmt
, i
);
2363 if (is_gimple_reg (arg
) || is_gimple_min_invariant (arg
))
2365 instrument_null (gsi
, arg
, false);
2370 if (sanitize_flags_p (SANITIZE_BOOL
| SANITIZE_ENUM
, fun
->decl
)
2371 && gimple_assign_load_p (stmt
))
2373 instrument_bool_enum_load (&gsi
);
2374 bb
= gimple_bb (stmt
);
2377 if (sanitize_flags_p (SANITIZE_NONNULL_ATTRIBUTE
, fun
->decl
)
2378 && is_gimple_call (stmt
)
2379 && !gimple_call_internal_p (stmt
))
2381 instrument_nonnull_arg (&gsi
);
2382 bb
= gimple_bb (stmt
);
2385 if (sanitize_flags_p (SANITIZE_BUILTIN
, fun
->decl
)
2386 && gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
2388 instrument_builtin (&gsi
);
2389 bb
= gimple_bb (stmt
);
2392 if (sanitize_flags_p (SANITIZE_RETURNS_NONNULL_ATTRIBUTE
, fun
->decl
)
2393 && gimple_code (stmt
) == GIMPLE_RETURN
)
2395 instrument_nonnull_return (&gsi
);
2396 bb
= gimple_bb (stmt
);
2399 if (sanitize_flags_p (SANITIZE_OBJECT_SIZE
, fun
->decl
))
2401 if (gimple_store_p (stmt
))
2402 instrument_object_size (&gsi
, gimple_get_lhs (stmt
), true);
2403 if (gimple_assign_load_p (stmt
))
2404 instrument_object_size (&gsi
, gimple_assign_rhs1 (stmt
),
2406 if (is_gimple_call (stmt
))
2408 unsigned args_num
= gimple_call_num_args (stmt
);
2409 for (unsigned i
= 0; i
< args_num
; ++i
)
2411 tree arg
= gimple_call_arg (stmt
, i
);
2412 if (is_gimple_reg (arg
) || is_gimple_min_invariant (arg
))
2414 instrument_object_size (&gsi
, arg
, false);
2419 if (sanitize_flags_p (SANITIZE_POINTER_OVERFLOW
, fun
->decl
))
2421 if (is_gimple_assign (stmt
)
2422 && gimple_assign_rhs_code (stmt
) == POINTER_PLUS_EXPR
)
2423 instrument_pointer_overflow (&gsi
,
2424 gimple_assign_rhs1 (stmt
),
2425 gimple_assign_rhs2 (stmt
));
2426 if (gimple_store_p (stmt
))
2427 maybe_instrument_pointer_overflow (&gsi
,
2428 gimple_get_lhs (stmt
));
2429 if (gimple_assign_single_p (stmt
))
2430 maybe_instrument_pointer_overflow (&gsi
,
2431 gimple_assign_rhs1 (stmt
));
2432 if (is_gimple_call (stmt
))
2434 unsigned args_num
= gimple_call_num_args (stmt
);
2435 for (unsigned i
= 0; i
< args_num
; ++i
)
2437 tree arg
= gimple_call_arg (stmt
, i
);
2438 if (is_gimple_reg (arg
))
2440 maybe_instrument_pointer_overflow (&gsi
, arg
);
2447 if (gimple_purge_dead_eh_edges (bb
))
2448 ret
= TODO_cleanup_cfg
;
2456 make_pass_ubsan (gcc::context
*ctxt
)
2458 return new pass_ubsan (ctxt
);
2461 #include "gt-ubsan.h"