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"
36 #include "plugin-api.h"
38 #include "hard-reg-set.h"
42 #include "tree-pass.h"
43 #include "tree-ssa-alias.h"
44 #include "tree-pretty-print.h"
45 #include "internal-fn.h"
46 #include "gimple-expr.h"
48 #include "gimple-iterator.h"
49 #include "gimple-ssa.h"
50 #include "gimple-walk.h"
56 #include "c-family/c-common.h"
59 #include "insn-config.h"
68 #include "tree-ssanames.h"
70 #include "gimplify-me.h"
75 #include "tree-object-size.h"
79 /* Map from a tree to a VAR_DECL tree. */
81 struct GTY((for_user
)) tree_type_map
{
82 struct tree_map_base type
;
86 struct tree_type_map_cache_hasher
: ggc_cache_hasher
<tree_type_map
*>
88 static inline hashval_t
89 hash (tree_type_map
*t
)
91 return TYPE_UID (t
->type
.from
);
95 equal (tree_type_map
*a
, tree_type_map
*b
)
97 return a
->type
.from
== b
->type
.from
;
101 keep_cache_entry (tree_type_map
*&m
)
103 return ggc_marked_p (m
->type
.from
);
108 hash_table
<tree_type_map_cache_hasher
> *decl_tree_for_type
;
110 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
113 decl_for_type_lookup (tree type
)
115 /* If the hash table is not initialized yet, create it now. */
116 if (decl_tree_for_type
== NULL
)
119 = hash_table
<tree_type_map_cache_hasher
>::create_ggc (10);
120 /* That also means we don't have to bother with the lookup. */
124 struct tree_type_map
*h
, in
;
127 h
= decl_tree_for_type
->find_with_hash (&in
, TYPE_UID (type
));
128 return h
? h
->decl
: NULL_TREE
;
131 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
134 decl_for_type_insert (tree type
, tree decl
)
136 struct tree_type_map
*h
;
138 h
= ggc_alloc
<tree_type_map
> ();
141 *decl_tree_for_type
->find_slot_with_hash (h
, TYPE_UID (type
), INSERT
) = h
;
144 /* Helper routine, which encodes a value in the pointer_sized_int_node.
145 Arguments with precision <= POINTER_SIZE are passed directly,
146 the rest is passed by reference. T is a value we are to encode.
147 IN_EXPAND_P is true if this function is called during expansion. */
150 ubsan_encode_value (tree t
, bool in_expand_p
)
152 tree type
= TREE_TYPE (t
);
153 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
154 if (bitsize
<= POINTER_SIZE
)
155 switch (TREE_CODE (type
))
160 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
163 tree itype
= build_nonstandard_integer_type (bitsize
, true);
164 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
165 return fold_convert (pointer_sized_int_node
, t
);
172 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
174 /* The reason for this is that we don't want to pessimize
175 code by making vars unnecessarily addressable. */
176 tree var
= create_tmp_var (type
);
177 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
181 = assign_stack_temp_for_type (TYPE_MODE (type
),
182 GET_MODE_SIZE (TYPE_MODE (type
)),
184 SET_DECL_RTL (var
, mem
);
185 expand_assignment (var
, t
, false);
186 return build_fold_addr_expr (var
);
188 t
= build_fold_addr_expr (var
);
189 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
192 return build_fold_addr_expr (t
);
196 /* Cached ubsan_get_type_descriptor_type () return value. */
197 static GTY(()) tree ubsan_type_descriptor_type
;
200 struct __ubsan_type_descriptor
202 unsigned short __typekind;
203 unsigned short __typeinfo;
209 ubsan_get_type_descriptor_type (void)
211 static const char *field_names
[3]
212 = { "__typekind", "__typeinfo", "__typename" };
215 if (ubsan_type_descriptor_type
)
216 return ubsan_type_descriptor_type
;
218 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
219 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
221 ret
= make_node (RECORD_TYPE
);
222 for (int i
= 0; i
< 3; i
++)
224 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
225 get_identifier (field_names
[i
]),
226 (i
== 2) ? flex_arr_type
227 : short_unsigned_type_node
);
228 DECL_CONTEXT (fields
[i
]) = ret
;
230 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
232 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
233 get_identifier ("__ubsan_type_descriptor"),
235 DECL_IGNORED_P (type_decl
) = 1;
236 DECL_ARTIFICIAL (type_decl
) = 1;
237 TYPE_FIELDS (ret
) = fields
[0];
238 TYPE_NAME (ret
) = type_decl
;
239 TYPE_STUB_DECL (ret
) = type_decl
;
241 ubsan_type_descriptor_type
= ret
;
245 /* Cached ubsan_get_source_location_type () return value. */
246 static GTY(()) tree ubsan_source_location_type
;
249 struct __ubsan_source_location
251 const char *__filename;
253 unsigned int __column;
258 ubsan_get_source_location_type (void)
260 static const char *field_names
[3]
261 = { "__filename", "__line", "__column" };
263 if (ubsan_source_location_type
)
264 return ubsan_source_location_type
;
266 tree const_char_type
= build_qualified_type (char_type_node
,
269 ret
= make_node (RECORD_TYPE
);
270 for (int i
= 0; i
< 3; i
++)
272 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
273 get_identifier (field_names
[i
]),
274 (i
== 0) ? build_pointer_type (const_char_type
)
275 : unsigned_type_node
);
276 DECL_CONTEXT (fields
[i
]) = ret
;
278 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
280 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
281 get_identifier ("__ubsan_source_location"),
283 DECL_IGNORED_P (type_decl
) = 1;
284 DECL_ARTIFICIAL (type_decl
) = 1;
285 TYPE_FIELDS (ret
) = fields
[0];
286 TYPE_NAME (ret
) = type_decl
;
287 TYPE_STUB_DECL (ret
) = type_decl
;
289 ubsan_source_location_type
= ret
;
293 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
294 type with its fields filled from a location_t LOC. */
297 ubsan_source_location (location_t loc
)
299 expanded_location xloc
;
300 tree type
= ubsan_get_source_location_type ();
302 xloc
= expand_location (loc
);
304 if (xloc
.file
== NULL
)
306 str
= build_int_cst (ptr_type_node
, 0);
312 /* Fill in the values from LOC. */
313 size_t len
= strlen (xloc
.file
) + 1;
314 str
= build_string (len
, xloc
.file
);
315 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
316 TREE_READONLY (str
) = 1;
317 TREE_STATIC (str
) = 1;
318 str
= build_fold_addr_expr (str
);
320 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
321 build_int_cst (unsigned_type_node
,
322 xloc
.line
), NULL_TREE
,
323 build_int_cst (unsigned_type_node
,
325 TREE_CONSTANT (ctor
) = 1;
326 TREE_STATIC (ctor
) = 1;
331 /* This routine returns a magic number for TYPE. */
333 static unsigned short
334 get_ubsan_type_info_for_type (tree type
)
336 gcc_assert (TYPE_SIZE (type
) && tree_fits_uhwi_p (TYPE_SIZE (type
)));
337 if (TREE_CODE (type
) == REAL_TYPE
)
338 return tree_to_uhwi (TYPE_SIZE (type
));
339 else if (INTEGRAL_TYPE_P (type
))
341 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
342 gcc_assert (prec
!= -1);
343 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
349 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
350 descriptor. It first looks into the hash table; if not found,
351 create the VAR_DECL, put it into the hash table and return the
352 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
353 an enum controlling how we want to print the type. */
356 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
358 /* See through any typedefs. */
359 type
= TYPE_MAIN_VARIANT (type
);
361 tree decl
= decl_for_type_lookup (type
);
362 /* It is possible that some of the earlier created DECLs were found
363 unused, in that case they weren't emitted and varpool_node::get
364 returns NULL node on them. But now we really need them. Thus,
366 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
367 return build_fold_addr_expr (decl
);
369 tree dtype
= ubsan_get_type_descriptor_type ();
371 const char *tname
= NULL
;
372 pretty_printer pretty_name
;
373 unsigned char deref_depth
= 0;
374 unsigned short tkind
, tinfo
;
376 /* Get the name of the type, or the name of the pointer type. */
377 if (pstyle
== UBSAN_PRINT_POINTER
)
379 gcc_assert (POINTER_TYPE_P (type
));
380 type2
= TREE_TYPE (type
);
382 /* Remove any '*' operators from TYPE. */
383 while (POINTER_TYPE_P (type2
))
384 deref_depth
++, type2
= TREE_TYPE (type2
);
386 if (TREE_CODE (type2
) == METHOD_TYPE
)
387 type2
= TYPE_METHOD_BASETYPE (type2
);
390 /* If an array, get its type. */
391 type2
= strip_array_types (type2
);
393 if (pstyle
== UBSAN_PRINT_ARRAY
)
395 while (POINTER_TYPE_P (type2
))
396 deref_depth
++, type2
= TREE_TYPE (type2
);
399 if (TYPE_NAME (type2
) != NULL
)
401 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
402 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
403 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
404 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
408 /* We weren't able to determine the type name. */
411 if (pstyle
== UBSAN_PRINT_POINTER
)
413 pp_printf (&pretty_name
, "'%s%s%s%s%s%s%s",
414 TYPE_VOLATILE (type2
) ? "volatile " : "",
415 TYPE_READONLY (type2
) ? "const " : "",
416 TYPE_RESTRICT (type2
) ? "restrict " : "",
417 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
418 TREE_CODE (type2
) == RECORD_TYPE
420 : TREE_CODE (type2
) == UNION_TYPE
421 ? "union " : "", tname
,
422 deref_depth
== 0 ? "" : " ");
423 while (deref_depth
-- > 0)
424 pp_star (&pretty_name
);
425 pp_quote (&pretty_name
);
427 else if (pstyle
== UBSAN_PRINT_ARRAY
)
429 /* Pretty print the array dimensions. */
430 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
432 pp_printf (&pretty_name
, "'%s ", tname
);
433 while (deref_depth
-- > 0)
434 pp_star (&pretty_name
);
435 while (TREE_CODE (t
) == ARRAY_TYPE
)
437 pp_left_bracket (&pretty_name
);
438 tree dom
= TYPE_DOMAIN (t
);
439 if (dom
&& TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
441 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom
))
442 && tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1 != 0)
443 pp_printf (&pretty_name
, HOST_WIDE_INT_PRINT_DEC
,
444 tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 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 (type
))
472 /* FIXME: libubsan right now only supports float, double and
473 long double type formats. */
474 if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
)
475 || TYPE_MODE (type
) == TYPE_MODE (double_type_node
)
476 || TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
485 tinfo
= get_ubsan_type_info_for_type (type
);
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 static unsigned int type_var_id_num
;
497 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
498 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
500 TREE_STATIC (decl
) = 1;
501 TREE_PUBLIC (decl
) = 0;
502 DECL_ARTIFICIAL (decl
) = 1;
503 DECL_IGNORED_P (decl
) = 1;
504 DECL_EXTERNAL (decl
) = 0;
506 = size_binop (PLUS_EXPR
, DECL_SIZE (decl
), TYPE_SIZE (TREE_TYPE (str
)));
507 DECL_SIZE_UNIT (decl
)
508 = size_binop (PLUS_EXPR
, DECL_SIZE_UNIT (decl
),
509 TYPE_SIZE_UNIT (TREE_TYPE (str
)));
511 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
512 build_int_cst (short_unsigned_type_node
,
514 build_int_cst (short_unsigned_type_node
,
515 tinfo
), NULL_TREE
, str
);
516 TREE_CONSTANT (ctor
) = 1;
517 TREE_STATIC (ctor
) = 1;
518 DECL_INITIAL (decl
) = ctor
;
519 varpool_node::finalize_decl (decl
);
521 /* Save the VAR_DECL into the hash table. */
522 decl_for_type_insert (type
, decl
);
524 return build_fold_addr_expr (decl
);
527 /* Create a structure for the ubsan library. NAME is a name of the new
528 structure. LOCCNT is number of locations, PLOC points to array of
529 locations. The arguments in ... are of __ubsan_type_descriptor type
530 and there are at most two of them, followed by NULL_TREE, followed
531 by optional extra arguments and another NULL_TREE. */
534 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
539 vec
<tree
, va_gc
> *saved_args
= NULL
;
543 /* Firstly, create a pointer to type descriptor type. */
544 tree td_type
= ubsan_get_type_descriptor_type ();
545 td_type
= build_pointer_type (td_type
);
547 /* Create the structure type. */
548 ret
= make_node (RECORD_TYPE
);
549 for (j
= 0; j
< loccnt
; j
++)
551 gcc_checking_assert (i
< 2);
552 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
553 ubsan_get_source_location_type ());
554 DECL_CONTEXT (fields
[i
]) = ret
;
556 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
560 va_start (args
, ploc
);
561 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
562 i
++, t
= va_arg (args
, tree
))
564 gcc_checking_assert (i
< 4);
565 /* Save the tree arguments for later use. */
566 vec_safe_push (saved_args
, t
);
567 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
569 DECL_CONTEXT (fields
[i
]) = ret
;
571 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
574 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
575 i
++, t
= va_arg (args
, tree
))
577 gcc_checking_assert (i
< 6);
578 /* Save the tree arguments for later use. */
579 vec_safe_push (saved_args
, t
);
580 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
582 DECL_CONTEXT (fields
[i
]) = ret
;
584 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
588 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
589 get_identifier (name
), ret
);
590 DECL_IGNORED_P (type_decl
) = 1;
591 DECL_ARTIFICIAL (type_decl
) = 1;
592 TYPE_FIELDS (ret
) = fields
[0];
593 TYPE_NAME (ret
) = type_decl
;
594 TYPE_STUB_DECL (ret
) = type_decl
;
597 /* Now, fill in the type. */
599 static unsigned int ubsan_var_id_num
;
600 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
601 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
603 TREE_STATIC (var
) = 1;
604 TREE_PUBLIC (var
) = 0;
605 DECL_ARTIFICIAL (var
) = 1;
606 DECL_IGNORED_P (var
) = 1;
607 DECL_EXTERNAL (var
) = 0;
609 vec
<constructor_elt
, va_gc
> *v
;
611 tree ctor
= build_constructor (ret
, v
);
613 /* If desirable, set the __ubsan_source_location element. */
614 for (j
= 0; j
< loccnt
; j
++)
616 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
617 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
620 size_t nelts
= vec_safe_length (saved_args
);
621 for (i
= 0; i
< nelts
; i
++)
623 t
= (*saved_args
)[i
];
624 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
627 TREE_CONSTANT (ctor
) = 1;
628 TREE_STATIC (ctor
) = 1;
629 DECL_INITIAL (var
) = ctor
;
630 varpool_node::finalize_decl (var
);
635 /* Instrument the __builtin_unreachable call. We just call the libubsan
639 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
642 location_t loc
= gimple_location (gsi_stmt (*gsi
));
644 if (flag_sanitize_undefined_trap_on_error
)
645 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
648 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
649 NULL_TREE
, NULL_TREE
);
650 data
= build_fold_addr_expr_loc (loc
, data
);
652 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
653 g
= gimple_build_call (fn
, 1, data
);
655 gimple_set_location (g
, loc
);
656 gsi_replace (gsi
, g
, false);
660 /* Return true if T is a call to a libubsan routine. */
663 is_ubsan_builtin_p (tree t
)
665 return TREE_CODE (t
) == FUNCTION_DECL
666 && DECL_BUILT_IN_CLASS (t
) == BUILT_IN_NORMAL
667 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
668 "__builtin___ubsan_", 18) == 0;
671 /* Create a callgraph edge for statement STMT. */
674 ubsan_create_edge (gimple stmt
)
676 gcall
*call_stmt
= dyn_cast
<gcall
*> (stmt
);
677 basic_block bb
= gimple_bb (stmt
);
678 int freq
= compute_call_stmt_bb_frequency (current_function_decl
, bb
);
679 cgraph_node
*node
= cgraph_node::get (current_function_decl
);
680 tree decl
= gimple_call_fndecl (call_stmt
);
682 node
->create_edge (cgraph_node::get_create (decl
), call_stmt
, bb
->count
,
686 /* Expand the UBSAN_BOUNDS special builtin function. */
689 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
691 gimple stmt
= gsi_stmt (*gsi
);
692 location_t loc
= gimple_location (stmt
);
693 gcc_assert (gimple_call_num_args (stmt
) == 3);
695 /* Pick up the arguments of the UBSAN_BOUNDS call. */
696 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
697 tree index
= gimple_call_arg (stmt
, 1);
698 tree orig_index_type
= TREE_TYPE (index
);
699 tree bound
= gimple_call_arg (stmt
, 2);
701 gimple_stmt_iterator gsi_orig
= *gsi
;
703 /* Create condition "if (index > bound)". */
704 basic_block then_bb
, fallthru_bb
;
705 gimple_stmt_iterator cond_insert_point
706 = create_cond_insert_point (gsi
, false, false, true,
707 &then_bb
, &fallthru_bb
);
708 index
= fold_convert (TREE_TYPE (bound
), index
);
709 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
711 false, GSI_NEW_STMT
);
712 gimple g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
713 gimple_set_location (g
, loc
);
714 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
716 /* Generate __ubsan_handle_out_of_bounds call. */
717 *gsi
= gsi_after_labels (then_bb
);
718 if (flag_sanitize_undefined_trap_on_error
)
719 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
723 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
724 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
725 ubsan_type_descriptor (orig_index_type
),
726 NULL_TREE
, NULL_TREE
);
727 data
= build_fold_addr_expr_loc (loc
, data
);
728 enum built_in_function bcode
729 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
730 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
731 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
732 tree fn
= builtin_decl_explicit (bcode
);
733 tree val
= force_gimple_operand_gsi (gsi
, ubsan_encode_value (index
),
734 true, NULL_TREE
, true,
736 g
= gimple_build_call (fn
, 2, data
, val
);
738 gimple_set_location (g
, loc
);
739 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
741 /* Get rid of the UBSAN_BOUNDS call from the IR. */
742 unlink_stmt_vdef (stmt
);
743 gsi_remove (&gsi_orig
, true);
745 /* Point GSI to next logical statement. */
746 *gsi
= gsi_start_bb (fallthru_bb
);
750 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
751 argument which is a constant, because the middle-end treats pointer
752 conversions as useless and therefore the type of the first argument
753 could be changed to any other pointer type. */
756 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
758 gimple_stmt_iterator gsi
= *gsip
;
759 gimple stmt
= gsi_stmt (gsi
);
760 location_t loc
= gimple_location (stmt
);
761 gcc_assert (gimple_call_num_args (stmt
) == 3);
762 tree ptr
= gimple_call_arg (stmt
, 0);
763 tree ckind
= gimple_call_arg (stmt
, 1);
764 tree align
= gimple_call_arg (stmt
, 2);
765 tree check_align
= NULL_TREE
;
768 basic_block cur_bb
= gsi_bb (gsi
);
771 if (!integer_zerop (align
))
773 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
774 if (compare_tree_int (align
, ptralign
) == 1)
776 check_align
= make_ssa_name (pointer_sized_int_node
);
777 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
778 gimple_set_location (g
, loc
);
779 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
782 check_null
= (flag_sanitize
& SANITIZE_NULL
) != 0;
784 if (check_align
== NULL_TREE
&& !check_null
)
786 gsi_remove (gsip
, true);
787 /* Unlink the UBSAN_NULLs vops before replacing it. */
788 unlink_stmt_vdef (stmt
);
792 /* Split the original block holding the pointer dereference. */
793 edge e
= split_block (cur_bb
, stmt
);
795 /* Get a hold on the 'condition block', the 'then block' and the
797 basic_block cond_bb
= e
->src
;
798 basic_block fallthru_bb
= e
->dest
;
799 basic_block then_bb
= create_empty_bb (cond_bb
);
800 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
801 loops_state_set (LOOPS_NEED_FIXUP
);
803 /* Make an edge coming from the 'cond block' into the 'then block';
804 this edge is unlikely taken, so set up the probability accordingly. */
805 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
806 e
->probability
= PROB_VERY_UNLIKELY
;
808 /* Connect 'then block' with the 'else block'. This is needed
809 as the ubsan routines we call in the 'then block' are not noreturn.
810 The 'then block' only has one outcoming edge. */
811 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
813 /* Set up the fallthrough basic block. */
814 e
= find_edge (cond_bb
, fallthru_bb
);
815 e
->flags
= EDGE_FALSE_VALUE
;
816 e
->count
= cond_bb
->count
;
817 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
819 /* Update dominance info for the newly created then_bb; note that
820 fallthru_bb's dominance info has already been updated by
822 if (dom_info_available_p (CDI_DOMINATORS
))
823 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
825 /* Put the ubsan builtin call into the newly created BB. */
826 if (flag_sanitize_undefined_trap_on_error
)
827 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
830 enum built_in_function bcode
831 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
832 | (check_null
? SANITIZE_NULL
: 0)))
833 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
834 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
835 tree fn
= builtin_decl_implicit (bcode
);
837 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
838 ubsan_type_descriptor (TREE_TYPE (ckind
),
839 UBSAN_PRINT_POINTER
),
842 fold_convert (unsigned_char_type_node
, ckind
),
844 data
= build_fold_addr_expr_loc (loc
, data
);
845 g
= gimple_build_call (fn
, 2, data
,
846 check_align
? check_align
847 : build_zero_cst (pointer_sized_int_node
));
849 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
850 gimple_set_location (g
, loc
);
851 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
853 /* Unlink the UBSAN_NULLs vops before replacing it. */
854 unlink_stmt_vdef (stmt
);
858 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
859 NULL_TREE
, NULL_TREE
);
860 gimple_set_location (g
, loc
);
862 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
863 gsi_replace (&gsi
, g
, false);
871 /* Split the block with the condition again. */
872 e
= split_block (cond_bb
, stmt
);
873 basic_block cond1_bb
= e
->src
;
874 basic_block cond2_bb
= e
->dest
;
876 /* Make an edge coming from the 'cond1 block' into the 'then block';
877 this edge is unlikely taken, so set up the probability
879 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
880 e
->probability
= PROB_VERY_UNLIKELY
;
882 /* Set up the fallthrough basic block. */
883 e
= find_edge (cond1_bb
, cond2_bb
);
884 e
->flags
= EDGE_FALSE_VALUE
;
885 e
->count
= cond1_bb
->count
;
886 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
888 /* Update dominance info. */
889 if (dom_info_available_p (CDI_DOMINATORS
))
891 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
892 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
895 gsi2
= gsi_start_bb (cond2_bb
);
898 tree mask
= build_int_cst (pointer_sized_int_node
,
899 tree_to_uhwi (align
) - 1);
900 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
901 BIT_AND_EXPR
, check_align
, mask
);
902 gimple_set_location (g
, loc
);
904 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
906 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
908 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
909 build_int_cst (pointer_sized_int_node
, 0),
910 NULL_TREE
, NULL_TREE
);
911 gimple_set_location (g
, loc
);
913 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
915 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
916 gsi_replace (&gsi
, g
, false);
921 #define OBJSZ_MAX_OFFSET (1024 * 16)
923 /* Expand UBSAN_OBJECT_SIZE internal call. */
926 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
928 gimple stmt
= gsi_stmt (*gsi
);
929 location_t loc
= gimple_location (stmt
);
930 gcc_assert (gimple_call_num_args (stmt
) == 4);
932 tree ptr
= gimple_call_arg (stmt
, 0);
933 tree offset
= gimple_call_arg (stmt
, 1);
934 tree size
= gimple_call_arg (stmt
, 2);
935 tree ckind
= gimple_call_arg (stmt
, 3);
936 gimple_stmt_iterator gsi_orig
= *gsi
;
939 /* See if we can discard the check. */
940 if (TREE_CODE (size
) != INTEGER_CST
941 || integer_all_onesp (size
))
942 /* Yes, __builtin_object_size couldn't determine the
944 else if (TREE_CODE (offset
) == INTEGER_CST
945 && wi::ges_p (wi::to_widest (offset
), -OBJSZ_MAX_OFFSET
)
946 && wi::les_p (wi::to_widest (offset
), -1))
947 /* The offset is in range [-16K, -1]. */;
950 /* if (offset > objsize) */
951 basic_block then_bb
, fallthru_bb
;
952 gimple_stmt_iterator cond_insert_point
953 = create_cond_insert_point (gsi
, false, false, true,
954 &then_bb
, &fallthru_bb
);
955 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
956 gimple_set_location (g
, loc
);
957 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
959 /* If the offset is small enough, we don't need the second
961 if (TREE_CODE (offset
) == INTEGER_CST
962 && wi::ges_p (wi::to_widest (offset
), 0)
963 && wi::les_p (wi::to_widest (offset
), OBJSZ_MAX_OFFSET
))
964 *gsi
= gsi_after_labels (then_bb
);
967 /* Don't issue run-time error if (ptr > ptr + offset). That
968 may happen when computing a POINTER_PLUS_EXPR. */
969 basic_block then2_bb
, fallthru2_bb
;
971 gimple_stmt_iterator gsi2
= gsi_after_labels (then_bb
);
972 cond_insert_point
= create_cond_insert_point (&gsi2
, false, false,
975 /* Convert the pointer to an integer type. */
976 tree p
= make_ssa_name (pointer_sized_int_node
);
977 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
978 gimple_set_location (g
, loc
);
979 gsi_insert_before (&cond_insert_point
, g
, GSI_NEW_STMT
);
980 p
= gimple_assign_lhs (g
);
981 /* Compute ptr + offset. */
982 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
983 PLUS_EXPR
, p
, offset
);
984 gimple_set_location (g
, loc
);
985 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
986 /* Now build the conditional and put it into the IR. */
987 g
= gimple_build_cond (LE_EXPR
, p
, gimple_assign_lhs (g
),
988 NULL_TREE
, NULL_TREE
);
989 gimple_set_location (g
, loc
);
990 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
991 *gsi
= gsi_after_labels (then2_bb
);
994 /* Generate __ubsan_handle_type_mismatch call. */
995 if (flag_sanitize_undefined_trap_on_error
)
996 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1000 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
1001 ubsan_type_descriptor (TREE_TYPE (ptr
),
1002 UBSAN_PRINT_POINTER
),
1004 build_zero_cst (pointer_sized_int_node
),
1007 data
= build_fold_addr_expr_loc (loc
, data
);
1008 enum built_in_function bcode
1009 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
1010 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1011 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
1012 tree p
= make_ssa_name (pointer_sized_int_node
);
1013 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
1014 gimple_set_location (g
, loc
);
1015 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1016 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
1018 gimple_set_location (g
, loc
);
1019 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1021 /* Point GSI to next logical statement. */
1022 *gsi
= gsi_start_bb (fallthru_bb
);
1024 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1025 unlink_stmt_vdef (stmt
);
1026 gsi_remove (&gsi_orig
, true);
1030 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1031 unlink_stmt_vdef (stmt
);
1032 gsi_remove (gsi
, true);
1036 /* Cached __ubsan_vptr_type_cache decl. */
1037 static GTY(()) tree ubsan_vptr_type_cache_decl
;
1039 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1040 argument which is a constant, because the middle-end treats pointer
1041 conversions as useless and therefore the type of the first argument
1042 could be changed to any other pointer type. */
1045 ubsan_expand_vptr_ifn (gimple_stmt_iterator
*gsip
)
1047 gimple_stmt_iterator gsi
= *gsip
;
1048 gimple stmt
= gsi_stmt (gsi
);
1049 location_t loc
= gimple_location (stmt
);
1050 gcc_assert (gimple_call_num_args (stmt
) == 5);
1051 tree op
= gimple_call_arg (stmt
, 0);
1052 tree vptr
= gimple_call_arg (stmt
, 1);
1053 tree str_hash
= gimple_call_arg (stmt
, 2);
1054 tree ti_decl_addr
= gimple_call_arg (stmt
, 3);
1055 tree ckind_tree
= gimple_call_arg (stmt
, 4);
1056 ubsan_null_ckind ckind
= (ubsan_null_ckind
) tree_to_uhwi (ckind_tree
);
1057 tree type
= TREE_TYPE (TREE_TYPE (ckind_tree
));
1059 basic_block fallthru_bb
= NULL
;
1061 if (ckind
== UBSAN_DOWNCAST_POINTER
)
1063 /* Guard everything with if (op != NULL) { ... }. */
1064 basic_block then_bb
;
1065 gimple_stmt_iterator cond_insert_point
1066 = create_cond_insert_point (gsip
, false, false, true,
1067 &then_bb
, &fallthru_bb
);
1068 g
= gimple_build_cond (NE_EXPR
, op
, build_zero_cst (TREE_TYPE (op
)),
1069 NULL_TREE
, NULL_TREE
);
1070 gimple_set_location (g
, loc
);
1071 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1072 *gsip
= gsi_after_labels (then_bb
);
1073 gsi_remove (&gsi
, false);
1074 gsi_insert_before (gsip
, stmt
, GSI_NEW_STMT
);
1078 tree htype
= TREE_TYPE (str_hash
);
1079 tree cst
= wide_int_to_tree (htype
,
1080 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1082 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1084 gimple_set_location (g
, loc
);
1085 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1086 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1087 gimple_assign_lhs (g
), cst
);
1088 gimple_set_location (g
, loc
);
1089 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1090 tree t1
= gimple_assign_lhs (g
);
1091 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1092 t1
, build_int_cst (integer_type_node
, 47));
1093 gimple_set_location (g
, loc
);
1094 tree t2
= gimple_assign_lhs (g
);
1095 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1096 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1098 gimple_set_location (g
, loc
);
1099 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1100 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1101 t2
, gimple_assign_lhs (g
));
1102 gimple_set_location (g
, loc
);
1103 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1104 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1105 gimple_assign_lhs (g
), cst
);
1106 gimple_set_location (g
, loc
);
1107 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1108 tree t3
= gimple_assign_lhs (g
);
1109 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1110 t3
, build_int_cst (integer_type_node
, 47));
1111 gimple_set_location (g
, loc
);
1112 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1113 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1114 t3
, gimple_assign_lhs (g
));
1115 gimple_set_location (g
, loc
);
1116 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1117 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1118 gimple_assign_lhs (g
), cst
);
1119 gimple_set_location (g
, loc
);
1120 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1121 if (!useless_type_conversion_p (pointer_sized_int_node
, htype
))
1123 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1124 NOP_EXPR
, gimple_assign_lhs (g
));
1125 gimple_set_location (g
, loc
);
1126 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1128 tree hash
= gimple_assign_lhs (g
);
1130 if (ubsan_vptr_type_cache_decl
== NULL_TREE
)
1132 tree atype
= build_array_type_nelts (pointer_sized_int_node
, 128);
1133 tree array
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1134 get_identifier ("__ubsan_vptr_type_cache"),
1136 DECL_ARTIFICIAL (array
) = 1;
1137 DECL_IGNORED_P (array
) = 1;
1138 TREE_PUBLIC (array
) = 1;
1139 TREE_STATIC (array
) = 1;
1140 DECL_EXTERNAL (array
) = 1;
1141 DECL_VISIBILITY (array
) = VISIBILITY_DEFAULT
;
1142 DECL_VISIBILITY_SPECIFIED (array
) = 1;
1143 varpool_node::finalize_decl (array
);
1144 ubsan_vptr_type_cache_decl
= array
;
1147 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1149 build_int_cst (pointer_sized_int_node
, 127));
1150 gimple_set_location (g
, loc
);
1151 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1153 tree c
= build4_loc (loc
, ARRAY_REF
, pointer_sized_int_node
,
1154 ubsan_vptr_type_cache_decl
, gimple_assign_lhs (g
),
1155 NULL_TREE
, NULL_TREE
);
1156 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1158 gimple_set_location (g
, loc
);
1159 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1161 basic_block then_bb
, fallthru2_bb
;
1162 gimple_stmt_iterator cond_insert_point
1163 = create_cond_insert_point (gsip
, false, false, true,
1164 &then_bb
, &fallthru2_bb
);
1165 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
), hash
,
1166 NULL_TREE
, NULL_TREE
);
1167 gimple_set_location (g
, loc
);
1168 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1169 *gsip
= gsi_after_labels (then_bb
);
1170 if (fallthru_bb
== NULL
)
1171 fallthru_bb
= fallthru2_bb
;
1174 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc
,
1175 ubsan_type_descriptor (type
), NULL_TREE
, ti_decl_addr
,
1176 build_int_cst (unsigned_char_type_node
, ckind
),
1178 data
= build_fold_addr_expr_loc (loc
, data
);
1179 enum built_in_function bcode
1180 = (flag_sanitize_recover
& SANITIZE_VPTR
)
1181 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1182 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT
;
1184 g
= gimple_build_call (builtin_decl_explicit (bcode
), 3, data
, op
, hash
);
1185 gimple_set_location (g
, loc
);
1186 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1188 /* Point GSI to next logical statement. */
1189 *gsip
= gsi_start_bb (fallthru_bb
);
1191 /* Get rid of the UBSAN_VPTR call from the IR. */
1192 unlink_stmt_vdef (stmt
);
1193 gsi_remove (&gsi
, true);
1197 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1198 whether the pointer is on the left hand side of the assignment. */
1201 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
1204 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
1205 unsigned int align
= 0;
1206 if (flag_sanitize
& SANITIZE_ALIGNMENT
)
1208 align
= min_align_of_type (TREE_TYPE (base
));
1212 if (align
== 0 && (flag_sanitize
& SANITIZE_NULL
) == 0)
1214 tree t
= TREE_OPERAND (base
, 0);
1215 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
1217 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base
)) && mem
!= base
)
1218 ikind
= UBSAN_MEMBER_ACCESS
;
1219 tree kind
= build_int_cst (build_pointer_type (TREE_TYPE (base
)), ikind
);
1220 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
1221 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
1222 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
1223 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
1226 /* Perform the pointer instrumentation. */
1229 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
1231 gimple stmt
= gsi_stmt (gsi
);
1232 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1233 tree base
= get_base_address (t
);
1234 const enum tree_code code
= TREE_CODE (base
);
1236 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1237 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1240 /* Build an ubsan builtin call for the signed-integer-overflow
1241 sanitization. CODE says what kind of builtin are we building,
1242 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1243 are operands of the binary operation. */
1246 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1249 if (flag_sanitize_undefined_trap_on_error
)
1250 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1252 tree data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1253 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1255 enum built_in_function fn_code
;
1260 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1261 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1262 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1265 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1266 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1267 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1270 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1271 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1272 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1275 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1276 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1277 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1282 tree fn
= builtin_decl_explicit (fn_code
);
1283 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1284 build_fold_addr_expr_loc (loc
, data
),
1285 ubsan_encode_value (op0
, true),
1286 op1
? ubsan_encode_value (op1
, true)
1290 /* Perform the signed integer instrumentation. GSI is the iterator
1291 pointing at statement we are trying to instrument. */
1294 instrument_si_overflow (gimple_stmt_iterator gsi
)
1296 gimple stmt
= gsi_stmt (gsi
);
1297 tree_code code
= gimple_assign_rhs_code (stmt
);
1298 tree lhs
= gimple_assign_lhs (stmt
);
1299 tree lhstype
= TREE_TYPE (lhs
);
1303 /* If this is not a signed operation, don't instrument anything here.
1304 Also punt on bit-fields. */
1305 if (!INTEGRAL_TYPE_P (lhstype
)
1306 || TYPE_OVERFLOW_WRAPS (lhstype
)
1307 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
1318 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1319 a
= gimple_assign_rhs1 (stmt
);
1320 b
= gimple_assign_rhs2 (stmt
);
1321 g
= gimple_build_call_internal (code
== PLUS_EXPR
1322 ? IFN_UBSAN_CHECK_ADD
1323 : code
== MINUS_EXPR
1324 ? IFN_UBSAN_CHECK_SUB
1325 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1326 gimple_call_set_lhs (g
, lhs
);
1327 gsi_replace (&gsi
, g
, false);
1330 /* Represent i = -u;
1332 i = UBSAN_CHECK_SUB (0, u); */
1333 a
= build_int_cst (lhstype
, 0);
1334 b
= gimple_assign_rhs1 (stmt
);
1335 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1336 gimple_call_set_lhs (g
, lhs
);
1337 gsi_replace (&gsi
, g
, false);
1340 /* Transform i = ABS_EXPR<u>;
1342 _N = UBSAN_CHECK_SUB (0, u);
1343 i = ABS_EXPR<_N>; */
1344 a
= build_int_cst (lhstype
, 0);
1345 b
= gimple_assign_rhs1 (stmt
);
1346 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1347 a
= make_ssa_name (lhstype
);
1348 gimple_call_set_lhs (g
, a
);
1349 gimple_set_location (g
, gimple_location (stmt
));
1350 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1351 gimple_assign_set_rhs1 (stmt
, a
);
1359 /* Instrument loads from (non-bitfield) bool and C++ enum values
1360 to check if the memory value is outside of the range of the valid
1364 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1366 gimple stmt
= gsi_stmt (*gsi
);
1367 tree rhs
= gimple_assign_rhs1 (stmt
);
1368 tree type
= TREE_TYPE (rhs
);
1369 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1371 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
1373 minv
= boolean_false_node
;
1374 maxv
= boolean_true_node
;
1376 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1377 && (flag_sanitize
& SANITIZE_ENUM
)
1378 && TREE_TYPE (type
) != NULL_TREE
1379 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1380 && (TYPE_PRECISION (TREE_TYPE (type
))
1381 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1383 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1384 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1389 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1390 HOST_WIDE_INT bitsize
, bitpos
;
1393 int volatilep
= 0, unsignedp
= 0;
1394 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1395 &unsignedp
, &volatilep
, false);
1396 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1398 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
1399 || (bitpos
% modebitsize
) != 0
1400 || bitsize
!= modebitsize
1401 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1402 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1405 bool ends_bb
= stmt_ends_bb_p (stmt
);
1406 location_t loc
= gimple_location (stmt
);
1407 tree lhs
= gimple_assign_lhs (stmt
);
1408 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1409 tree atype
= reference_alias_ptr_type (rhs
);
1410 gimple g
= gimple_build_assign (make_ssa_name (ptype
),
1411 build_fold_addr_expr (rhs
));
1412 gimple_set_location (g
, loc
);
1413 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1414 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1415 build_int_cst (atype
, 0));
1416 tree urhs
= make_ssa_name (utype
);
1419 gimple_assign_set_lhs (stmt
, urhs
);
1420 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1421 gimple_set_location (g
, loc
);
1422 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1423 gsi_insert_on_edge_immediate (e
, g
);
1424 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1426 *gsi
= gsi_for_stmt (g
);
1431 g
= gimple_build_assign (urhs
, mem
);
1432 gimple_set_location (g
, loc
);
1433 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1435 minv
= fold_convert (utype
, minv
);
1436 maxv
= fold_convert (utype
, maxv
);
1437 if (!integer_zerop (minv
))
1439 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1440 gimple_set_location (g
, loc
);
1441 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1444 gimple_stmt_iterator gsi2
= *gsi
;
1445 basic_block then_bb
, fallthru_bb
;
1446 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1447 &then_bb
, &fallthru_bb
);
1448 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1449 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1450 NULL_TREE
, NULL_TREE
);
1451 gimple_set_location (g
, loc
);
1452 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1456 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1460 gsi2
= gsi_after_labels (then_bb
);
1461 if (flag_sanitize_undefined_trap_on_error
)
1462 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1465 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1466 ubsan_type_descriptor (type
), NULL_TREE
,
1468 data
= build_fold_addr_expr_loc (loc
, data
);
1469 enum built_in_function bcode
1470 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1471 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1472 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1473 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1474 tree fn
= builtin_decl_explicit (bcode
);
1476 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
1477 true, NULL_TREE
, true,
1479 g
= gimple_build_call (fn
, 2, data
, val
);
1481 gimple_set_location (g
, loc
);
1482 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1483 ubsan_create_edge (g
);
1484 *gsi
= gsi_for_stmt (stmt
);
1487 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1488 destination, EXPR is floating-point expression. ARG is what to pass
1489 the libubsan call as value, often EXPR itself. */
1492 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
, tree arg
)
1494 tree expr_type
= TREE_TYPE (expr
);
1495 tree t
, tt
, fn
, min
, max
;
1496 machine_mode mode
= TYPE_MODE (expr_type
);
1497 int prec
= TYPE_PRECISION (type
);
1498 bool uns_p
= TYPE_UNSIGNED (type
);
1500 /* Float to integer conversion first truncates toward zero, so
1501 even signed char c = 127.875f; is not problematic.
1502 Therefore, we should complain only if EXPR is unordered or smaller
1503 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1504 TYPE_MAX_VALUE + 1.0. */
1505 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1507 /* For maximum, TYPE_MAX_VALUE might not be representable
1508 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1509 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1510 either representable or infinity. */
1511 REAL_VALUE_TYPE maxval
= dconst1
;
1512 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1513 real_convert (&maxval
, mode
, &maxval
);
1514 max
= build_real (expr_type
, maxval
);
1516 /* For unsigned, assume -1.0 is always representable. */
1518 min
= build_minus_one_cst (expr_type
);
1521 /* TYPE_MIN_VALUE is generally representable (or -inf),
1522 but TYPE_MIN_VALUE - 1.0 might not be. */
1523 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1524 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1525 real_convert (&minval
, mode
, &minval
);
1526 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1527 real_convert (&minval2
, mode
, &minval2
);
1528 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1529 && !real_isinf (&minval
))
1531 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1532 rounds to TYPE_MIN_VALUE, we need to subtract
1533 more. As REAL_MODE_FORMAT (mode)->p is the number
1534 of base digits, we want to subtract a number that
1535 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1536 times smaller than minval. */
1538 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1539 SET_REAL_EXP (&minval2
,
1540 REAL_EXP (&minval2
) + prec
- 1
1541 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1542 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1543 real_convert (&minval2
, mode
, &minval2
);
1545 min
= build_real (expr_type
, minval2
);
1548 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1550 /* For _Decimal128 up to 34 decimal digits, - sign,
1551 dot, e, exponent. */
1554 int p
= REAL_MODE_FORMAT (mode
)->p
;
1555 REAL_VALUE_TYPE maxval
, minval
;
1557 /* Use mpfr_snprintf rounding to compute the smallest
1558 representable decimal number greater or equal than
1559 1 << (prec - !uns_p). */
1560 mpfr_init2 (m
, prec
+ 2);
1561 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1562 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1563 decimal_real_from_string (&maxval
, buf
);
1564 max
= build_real (expr_type
, maxval
);
1566 /* For unsigned, assume -1.0 is always representable. */
1568 min
= build_minus_one_cst (expr_type
);
1571 /* Use mpfr_snprintf rounding to compute the largest
1572 representable decimal number less or equal than
1573 (-1 << (prec - 1)) - 1. */
1574 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1575 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1576 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1577 decimal_real_from_string (&minval
, buf
);
1578 min
= build_real (expr_type
, minval
);
1585 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1586 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1587 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
);
1588 if (integer_zerop (t
))
1591 if (flag_sanitize_undefined_trap_on_error
)
1592 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1595 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1596 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1597 NULL
, ubsan_type_descriptor (expr_type
),
1598 ubsan_type_descriptor (type
), NULL_TREE
,
1600 enum built_in_function bcode
1601 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1602 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1603 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1604 fn
= builtin_decl_explicit (bcode
);
1605 fn
= build_call_expr_loc (loc
, fn
, 2,
1606 build_fold_addr_expr_loc (loc
, data
),
1607 ubsan_encode_value (arg
, false));
1610 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1613 /* Instrument values passed to function arguments with nonnull attribute. */
1616 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1618 gimple stmt
= gsi_stmt (*gsi
);
1620 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1621 while for nonnull sanitization it is clear. */
1622 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1623 flag_delete_null_pointer_checks
= 1;
1624 loc
[0] = gimple_location (stmt
);
1625 loc
[1] = UNKNOWN_LOCATION
;
1626 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1628 tree arg
= gimple_call_arg (stmt
, i
);
1629 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1630 && infer_nonnull_range (stmt
, arg
, false, true))
1633 if (!is_gimple_val (arg
))
1635 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1636 gimple_set_location (g
, loc
[0]);
1637 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1638 arg
= gimple_assign_lhs (g
);
1641 basic_block then_bb
, fallthru_bb
;
1642 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1643 &then_bb
, &fallthru_bb
);
1644 g
= gimple_build_cond (EQ_EXPR
, arg
,
1645 build_zero_cst (TREE_TYPE (arg
)),
1646 NULL_TREE
, NULL_TREE
);
1647 gimple_set_location (g
, loc
[0]);
1648 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1650 *gsi
= gsi_after_labels (then_bb
);
1651 if (flag_sanitize_undefined_trap_on_error
)
1652 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1655 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1657 build_int_cst (integer_type_node
,
1660 data
= build_fold_addr_expr_loc (loc
[0], data
);
1661 enum built_in_function bcode
1662 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1663 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1664 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1665 tree fn
= builtin_decl_explicit (bcode
);
1667 g
= gimple_build_call (fn
, 1, data
);
1669 gimple_set_location (g
, loc
[0]);
1670 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1671 ubsan_create_edge (g
);
1673 *gsi
= gsi_for_stmt (stmt
);
1675 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1678 /* Instrument returns in functions with returns_nonnull attribute. */
1681 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1683 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
1685 tree arg
= gimple_return_retval (stmt
);
1686 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1687 while for nonnull return sanitization it is clear. */
1688 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1689 flag_delete_null_pointer_checks
= 1;
1690 loc
[0] = gimple_location (stmt
);
1691 loc
[1] = UNKNOWN_LOCATION
;
1693 && POINTER_TYPE_P (TREE_TYPE (arg
))
1694 && is_gimple_val (arg
)
1695 && infer_nonnull_range (stmt
, arg
, false, true))
1697 basic_block then_bb
, fallthru_bb
;
1698 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1699 &then_bb
, &fallthru_bb
);
1700 gimple g
= gimple_build_cond (EQ_EXPR
, arg
,
1701 build_zero_cst (TREE_TYPE (arg
)),
1702 NULL_TREE
, NULL_TREE
);
1703 gimple_set_location (g
, loc
[0]);
1704 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1706 *gsi
= gsi_after_labels (then_bb
);
1707 if (flag_sanitize_undefined_trap_on_error
)
1708 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1711 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
1712 2, loc
, NULL_TREE
, NULL_TREE
);
1713 data
= build_fold_addr_expr_loc (loc
[0], data
);
1714 enum built_in_function bcode
1715 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1716 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1717 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
1718 tree fn
= builtin_decl_explicit (bcode
);
1720 g
= gimple_build_call (fn
, 1, data
);
1722 gimple_set_location (g
, loc
[0]);
1723 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1724 ubsan_create_edge (g
);
1725 *gsi
= gsi_for_stmt (stmt
);
1727 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1730 /* Instrument memory references. Here we check whether the pointer
1731 points to an out-of-bounds location. */
1734 instrument_object_size (gimple_stmt_iterator
*gsi
, bool is_lhs
)
1736 gimple stmt
= gsi_stmt (*gsi
);
1737 location_t loc
= gimple_location (stmt
);
1738 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1740 tree index
= NULL_TREE
;
1741 HOST_WIDE_INT size_in_bytes
;
1743 type
= TREE_TYPE (t
);
1744 if (VOID_TYPE_P (type
))
1747 switch (TREE_CODE (t
))
1750 if (TREE_CODE (t
) == COMPONENT_REF
1751 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
1753 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
1754 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
1759 index
= TREE_OPERAND (t
, 1);
1771 size_in_bytes
= int_size_in_bytes (type
);
1772 if (size_in_bytes
<= 0)
1775 HOST_WIDE_INT bitsize
, bitpos
;
1778 int volatilep
= 0, unsignedp
= 0;
1779 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1780 &unsignedp
, &volatilep
, false);
1782 if (bitpos
% BITS_PER_UNIT
!= 0
1783 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
1786 bool decl_p
= DECL_P (inner
);
1790 else if (TREE_CODE (inner
) == MEM_REF
)
1791 base
= TREE_OPERAND (inner
, 0);
1794 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
1796 while (TREE_CODE (base
) == SSA_NAME
)
1798 gimple def_stmt
= SSA_NAME_DEF_STMT (base
);
1799 if (gimple_assign_ssa_name_copy_p (def_stmt
)
1800 || (gimple_assign_cast_p (def_stmt
)
1801 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
1802 || (is_gimple_assign (def_stmt
)
1803 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
1805 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
1806 if (TREE_CODE (rhs1
) == SSA_NAME
1807 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
1816 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1820 tree base_addr
= base
;
1821 gimple bos_stmt
= NULL
;
1823 base_addr
= build1 (ADDR_EXPR
,
1824 build_pointer_type (TREE_TYPE (base
)), base
);
1825 unsigned HOST_WIDE_INT size
= compute_builtin_object_size (base_addr
, 0);
1826 if (size
!= (unsigned HOST_WIDE_INT
) -1)
1827 sizet
= build_int_cst (sizetype
, size
);
1830 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
1831 loc
= input_location
;
1832 /* Generate __builtin_object_size call. */
1833 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
1834 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
1836 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
1838 /* If the call above didn't end up being an integer constant, go one
1839 statement back and get the __builtin_object_size stmt. Save it,
1840 we might need it later. */
1841 if (SSA_VAR_P (sizet
))
1844 bos_stmt
= gsi_stmt (*gsi
);
1846 /* Move on to where we were. */
1853 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1855 /* ptr + sizeof (*ptr) - base */
1856 t
= fold_build2 (MINUS_EXPR
, sizetype
,
1857 fold_convert (pointer_sized_int_node
, ptr
),
1858 fold_convert (pointer_sized_int_node
, base_addr
));
1859 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
1861 /* Perhaps we can omit the check. */
1862 if (TREE_CODE (t
) == INTEGER_CST
1863 && TREE_CODE (sizet
) == INTEGER_CST
1864 && tree_int_cst_le (t
, sizet
))
1867 if (index
!= NULL_TREE
1868 && TREE_CODE (index
) == SSA_NAME
1869 && TREE_CODE (sizet
) == INTEGER_CST
)
1871 gimple def
= SSA_NAME_DEF_STMT (index
);
1872 if (is_gimple_assign (def
)
1873 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
1874 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
1876 tree cst
= gimple_assign_rhs2 (def
);
1877 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
1878 TYPE_SIZE_UNIT (type
));
1879 if (tree_int_cst_sgn (cst
) >= 0
1880 && tree_int_cst_lt (cst
, sz
))
1885 if (bos_stmt
&& gimple_call_builtin_p (bos_stmt
, BUILT_IN_OBJECT_SIZE
))
1886 ubsan_create_edge (bos_stmt
);
1888 /* We have to emit the check. */
1889 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1891 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
1893 tree ckind
= build_int_cst (unsigned_char_type_node
,
1894 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
1895 gimple g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
1896 ptr
, t
, sizet
, ckind
);
1897 gimple_set_location (g
, loc
);
1898 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1901 /* True if we want to play UBSan games in the current function. */
1904 do_ubsan_in_current_function ()
1906 return (current_function_decl
!= NULL_TREE
1907 && !lookup_attribute ("no_sanitize_undefined",
1908 DECL_ATTRIBUTES (current_function_decl
)));
1913 const pass_data pass_data_ubsan
=
1915 GIMPLE_PASS
, /* type */
1917 OPTGROUP_NONE
, /* optinfo_flags */
1918 TV_TREE_UBSAN
, /* tv_id */
1919 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1920 0, /* properties_provided */
1921 0, /* properties_destroyed */
1922 0, /* todo_flags_start */
1923 TODO_update_ssa
, /* todo_flags_finish */
1926 class pass_ubsan
: public gimple_opt_pass
1929 pass_ubsan (gcc::context
*ctxt
)
1930 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1933 /* opt_pass methods: */
1934 virtual bool gate (function
*)
1936 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1937 | SANITIZE_BOOL
| SANITIZE_ENUM
1938 | SANITIZE_ALIGNMENT
1939 | SANITIZE_NONNULL_ATTRIBUTE
1940 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1941 | SANITIZE_OBJECT_SIZE
)
1942 && do_ubsan_in_current_function ();
1945 virtual unsigned int execute (function
*);
1947 }; // class pass_ubsan
1950 pass_ubsan::execute (function
*fun
)
1953 gimple_stmt_iterator gsi
;
1955 initialize_sanitizer_builtins ();
1957 FOR_EACH_BB_FN (bb
, fun
)
1959 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1961 gimple stmt
= gsi_stmt (gsi
);
1962 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
1968 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
1969 && is_gimple_assign (stmt
))
1970 instrument_si_overflow (gsi
);
1972 if (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1974 if (gimple_store_p (stmt
))
1975 instrument_null (gsi
, true);
1976 if (gimple_assign_load_p (stmt
))
1977 instrument_null (gsi
, false);
1980 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
1981 && gimple_assign_load_p (stmt
))
1983 instrument_bool_enum_load (&gsi
);
1984 bb
= gimple_bb (stmt
);
1987 if ((flag_sanitize
& SANITIZE_NONNULL_ATTRIBUTE
)
1988 && is_gimple_call (stmt
)
1989 && !gimple_call_internal_p (stmt
))
1991 instrument_nonnull_arg (&gsi
);
1992 bb
= gimple_bb (stmt
);
1995 if ((flag_sanitize
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1996 && gimple_code (stmt
) == GIMPLE_RETURN
)
1998 instrument_nonnull_return (&gsi
);
1999 bb
= gimple_bb (stmt
);
2002 if (flag_sanitize
& SANITIZE_OBJECT_SIZE
)
2004 if (gimple_store_p (stmt
))
2005 instrument_object_size (&gsi
, true);
2006 if (gimple_assign_load_p (stmt
))
2007 instrument_object_size (&gsi
, false);
2019 make_pass_ubsan (gcc::context
*ctxt
)
2021 return new pass_ubsan (ctxt
);
2024 #include "gt-ubsan.h"