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 handle_cache_entry (tree_type_map
*&m
)
103 extern void gt_ggc_mx (tree_type_map
*&);
104 if (m
== HTAB_EMPTY_ENTRY
|| m
== HTAB_DELETED_ENTRY
)
106 else if (ggc_marked_p (m
->type
.from
))
109 m
= static_cast<tree_type_map
*> (HTAB_DELETED_ENTRY
);
114 hash_table
<tree_type_map_cache_hasher
> *decl_tree_for_type
;
116 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
119 decl_for_type_lookup (tree type
)
121 /* If the hash table is not initialized yet, create it now. */
122 if (decl_tree_for_type
== NULL
)
125 = hash_table
<tree_type_map_cache_hasher
>::create_ggc (10);
126 /* That also means we don't have to bother with the lookup. */
130 struct tree_type_map
*h
, in
;
133 h
= decl_tree_for_type
->find_with_hash (&in
, TYPE_UID (type
));
134 return h
? h
->decl
: NULL_TREE
;
137 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
140 decl_for_type_insert (tree type
, tree decl
)
142 struct tree_type_map
*h
;
144 h
= ggc_alloc
<tree_type_map
> ();
147 *decl_tree_for_type
->find_slot_with_hash (h
, TYPE_UID (type
), INSERT
) = h
;
150 /* Helper routine, which encodes a value in the pointer_sized_int_node.
151 Arguments with precision <= POINTER_SIZE are passed directly,
152 the rest is passed by reference. T is a value we are to encode.
153 IN_EXPAND_P is true if this function is called during expansion. */
156 ubsan_encode_value (tree t
, bool in_expand_p
)
158 tree type
= TREE_TYPE (t
);
159 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
160 if (bitsize
<= POINTER_SIZE
)
161 switch (TREE_CODE (type
))
166 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
169 tree itype
= build_nonstandard_integer_type (bitsize
, true);
170 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
171 return fold_convert (pointer_sized_int_node
, t
);
178 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
180 /* The reason for this is that we don't want to pessimize
181 code by making vars unnecessarily addressable. */
182 tree var
= create_tmp_var (type
);
183 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
187 = assign_stack_temp_for_type (TYPE_MODE (type
),
188 GET_MODE_SIZE (TYPE_MODE (type
)),
190 SET_DECL_RTL (var
, mem
);
191 expand_assignment (var
, t
, false);
192 return build_fold_addr_expr (var
);
194 t
= build_fold_addr_expr (var
);
195 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
198 return build_fold_addr_expr (t
);
202 /* Cached ubsan_get_type_descriptor_type () return value. */
203 static GTY(()) tree ubsan_type_descriptor_type
;
206 struct __ubsan_type_descriptor
208 unsigned short __typekind;
209 unsigned short __typeinfo;
215 ubsan_get_type_descriptor_type (void)
217 static const char *field_names
[3]
218 = { "__typekind", "__typeinfo", "__typename" };
221 if (ubsan_type_descriptor_type
)
222 return ubsan_type_descriptor_type
;
224 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
225 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
227 ret
= make_node (RECORD_TYPE
);
228 for (int i
= 0; i
< 3; i
++)
230 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
231 get_identifier (field_names
[i
]),
232 (i
== 2) ? flex_arr_type
233 : short_unsigned_type_node
);
234 DECL_CONTEXT (fields
[i
]) = ret
;
236 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
238 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
239 get_identifier ("__ubsan_type_descriptor"),
241 DECL_IGNORED_P (type_decl
) = 1;
242 DECL_ARTIFICIAL (type_decl
) = 1;
243 TYPE_FIELDS (ret
) = fields
[0];
244 TYPE_NAME (ret
) = type_decl
;
245 TYPE_STUB_DECL (ret
) = type_decl
;
247 ubsan_type_descriptor_type
= ret
;
251 /* Cached ubsan_get_source_location_type () return value. */
252 static GTY(()) tree ubsan_source_location_type
;
255 struct __ubsan_source_location
257 const char *__filename;
259 unsigned int __column;
264 ubsan_get_source_location_type (void)
266 static const char *field_names
[3]
267 = { "__filename", "__line", "__column" };
269 if (ubsan_source_location_type
)
270 return ubsan_source_location_type
;
272 tree const_char_type
= build_qualified_type (char_type_node
,
275 ret
= make_node (RECORD_TYPE
);
276 for (int i
= 0; i
< 3; i
++)
278 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
279 get_identifier (field_names
[i
]),
280 (i
== 0) ? build_pointer_type (const_char_type
)
281 : unsigned_type_node
);
282 DECL_CONTEXT (fields
[i
]) = ret
;
284 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
286 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
287 get_identifier ("__ubsan_source_location"),
289 DECL_IGNORED_P (type_decl
) = 1;
290 DECL_ARTIFICIAL (type_decl
) = 1;
291 TYPE_FIELDS (ret
) = fields
[0];
292 TYPE_NAME (ret
) = type_decl
;
293 TYPE_STUB_DECL (ret
) = type_decl
;
295 ubsan_source_location_type
= ret
;
299 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
300 type with its fields filled from a location_t LOC. */
303 ubsan_source_location (location_t loc
)
305 expanded_location xloc
;
306 tree type
= ubsan_get_source_location_type ();
308 xloc
= expand_location (loc
);
310 if (xloc
.file
== NULL
)
312 str
= build_int_cst (ptr_type_node
, 0);
318 /* Fill in the values from LOC. */
319 size_t len
= strlen (xloc
.file
) + 1;
320 str
= build_string (len
, xloc
.file
);
321 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
322 TREE_READONLY (str
) = 1;
323 TREE_STATIC (str
) = 1;
324 str
= build_fold_addr_expr (str
);
326 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
327 build_int_cst (unsigned_type_node
,
328 xloc
.line
), NULL_TREE
,
329 build_int_cst (unsigned_type_node
,
331 TREE_CONSTANT (ctor
) = 1;
332 TREE_STATIC (ctor
) = 1;
337 /* This routine returns a magic number for TYPE. */
339 static unsigned short
340 get_ubsan_type_info_for_type (tree type
)
342 gcc_assert (TYPE_SIZE (type
) && tree_fits_uhwi_p (TYPE_SIZE (type
)));
343 if (TREE_CODE (type
) == REAL_TYPE
)
344 return tree_to_uhwi (TYPE_SIZE (type
));
345 else if (INTEGRAL_TYPE_P (type
))
347 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
348 gcc_assert (prec
!= -1);
349 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
355 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
356 descriptor. It first looks into the hash table; if not found,
357 create the VAR_DECL, put it into the hash table and return the
358 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
359 an enum controlling how we want to print the type. */
362 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
364 /* See through any typedefs. */
365 type
= TYPE_MAIN_VARIANT (type
);
367 tree decl
= decl_for_type_lookup (type
);
368 /* It is possible that some of the earlier created DECLs were found
369 unused, in that case they weren't emitted and varpool_node::get
370 returns NULL node on them. But now we really need them. Thus,
372 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
373 return build_fold_addr_expr (decl
);
375 tree dtype
= ubsan_get_type_descriptor_type ();
377 const char *tname
= NULL
;
378 pretty_printer pretty_name
;
379 unsigned char deref_depth
= 0;
380 unsigned short tkind
, tinfo
;
382 /* Get the name of the type, or the name of the pointer type. */
383 if (pstyle
== UBSAN_PRINT_POINTER
)
385 gcc_assert (POINTER_TYPE_P (type
));
386 type2
= TREE_TYPE (type
);
388 /* Remove any '*' operators from TYPE. */
389 while (POINTER_TYPE_P (type2
))
390 deref_depth
++, type2
= TREE_TYPE (type2
);
392 if (TREE_CODE (type2
) == METHOD_TYPE
)
393 type2
= TYPE_METHOD_BASETYPE (type2
);
396 /* If an array, get its type. */
397 type2
= strip_array_types (type2
);
399 if (pstyle
== UBSAN_PRINT_ARRAY
)
401 while (POINTER_TYPE_P (type2
))
402 deref_depth
++, type2
= TREE_TYPE (type2
);
405 if (TYPE_NAME (type2
) != NULL
)
407 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
408 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
409 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
410 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
414 /* We weren't able to determine the type name. */
417 if (pstyle
== UBSAN_PRINT_POINTER
)
419 pp_printf (&pretty_name
, "'%s%s%s%s%s%s%s",
420 TYPE_VOLATILE (type2
) ? "volatile " : "",
421 TYPE_READONLY (type2
) ? "const " : "",
422 TYPE_RESTRICT (type2
) ? "restrict " : "",
423 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
424 TREE_CODE (type2
) == RECORD_TYPE
426 : TREE_CODE (type2
) == UNION_TYPE
427 ? "union " : "", tname
,
428 deref_depth
== 0 ? "" : " ");
429 while (deref_depth
-- > 0)
430 pp_star (&pretty_name
);
431 pp_quote (&pretty_name
);
433 else if (pstyle
== UBSAN_PRINT_ARRAY
)
435 /* Pretty print the array dimensions. */
436 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
438 pp_printf (&pretty_name
, "'%s ", tname
);
439 while (deref_depth
-- > 0)
440 pp_star (&pretty_name
);
441 while (TREE_CODE (t
) == ARRAY_TYPE
)
443 pp_left_bracket (&pretty_name
);
444 tree dom
= TYPE_DOMAIN (t
);
445 if (dom
&& TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
447 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom
))
448 && tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1 != 0)
449 pp_printf (&pretty_name
, HOST_WIDE_INT_PRINT_DEC
,
450 tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1);
452 pp_wide_int (&pretty_name
,
453 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom
)), 1),
454 TYPE_SIGN (TREE_TYPE (dom
)));
457 /* ??? We can't determine the variable name; print VLA unspec. */
458 pp_star (&pretty_name
);
459 pp_right_bracket (&pretty_name
);
462 pp_quote (&pretty_name
);
464 /* Save the tree with stripped types. */
468 pp_printf (&pretty_name
, "'%s'", tname
);
470 switch (TREE_CODE (type
))
478 /* FIXME: libubsan right now only supports float, double and
479 long double type formats. */
480 if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
)
481 || TYPE_MODE (type
) == TYPE_MODE (double_type_node
)
482 || TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
491 tinfo
= get_ubsan_type_info_for_type (type
);
493 /* Create a new VAR_DECL of type descriptor. */
494 const char *tmp
= pp_formatted_text (&pretty_name
);
495 size_t len
= strlen (tmp
) + 1;
496 tree str
= build_string (len
, tmp
);
497 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
498 TREE_READONLY (str
) = 1;
499 TREE_STATIC (str
) = 1;
502 static unsigned int type_var_id_num
;
503 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
504 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
506 TREE_STATIC (decl
) = 1;
507 TREE_PUBLIC (decl
) = 0;
508 DECL_ARTIFICIAL (decl
) = 1;
509 DECL_IGNORED_P (decl
) = 1;
510 DECL_EXTERNAL (decl
) = 0;
512 = size_binop (PLUS_EXPR
, DECL_SIZE (decl
), TYPE_SIZE (TREE_TYPE (str
)));
513 DECL_SIZE_UNIT (decl
)
514 = size_binop (PLUS_EXPR
, DECL_SIZE_UNIT (decl
),
515 TYPE_SIZE_UNIT (TREE_TYPE (str
)));
517 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
518 build_int_cst (short_unsigned_type_node
,
520 build_int_cst (short_unsigned_type_node
,
521 tinfo
), NULL_TREE
, str
);
522 TREE_CONSTANT (ctor
) = 1;
523 TREE_STATIC (ctor
) = 1;
524 DECL_INITIAL (decl
) = ctor
;
525 varpool_node::finalize_decl (decl
);
527 /* Save the VAR_DECL into the hash table. */
528 decl_for_type_insert (type
, decl
);
530 return build_fold_addr_expr (decl
);
533 /* Create a structure for the ubsan library. NAME is a name of the new
534 structure. LOCCNT is number of locations, PLOC points to array of
535 locations. The arguments in ... are of __ubsan_type_descriptor type
536 and there are at most two of them, followed by NULL_TREE, followed
537 by optional extra arguments and another NULL_TREE. */
540 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
545 vec
<tree
, va_gc
> *saved_args
= NULL
;
549 /* Firstly, create a pointer to type descriptor type. */
550 tree td_type
= ubsan_get_type_descriptor_type ();
551 td_type
= build_pointer_type (td_type
);
553 /* Create the structure type. */
554 ret
= make_node (RECORD_TYPE
);
555 for (j
= 0; j
< loccnt
; j
++)
557 gcc_checking_assert (i
< 2);
558 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
559 ubsan_get_source_location_type ());
560 DECL_CONTEXT (fields
[i
]) = ret
;
562 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
566 va_start (args
, ploc
);
567 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
568 i
++, t
= va_arg (args
, tree
))
570 gcc_checking_assert (i
< 4);
571 /* Save the tree arguments for later use. */
572 vec_safe_push (saved_args
, t
);
573 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
575 DECL_CONTEXT (fields
[i
]) = ret
;
577 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
580 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
581 i
++, t
= va_arg (args
, tree
))
583 gcc_checking_assert (i
< 6);
584 /* Save the tree arguments for later use. */
585 vec_safe_push (saved_args
, t
);
586 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
588 DECL_CONTEXT (fields
[i
]) = ret
;
590 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
594 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
595 get_identifier (name
), ret
);
596 DECL_IGNORED_P (type_decl
) = 1;
597 DECL_ARTIFICIAL (type_decl
) = 1;
598 TYPE_FIELDS (ret
) = fields
[0];
599 TYPE_NAME (ret
) = type_decl
;
600 TYPE_STUB_DECL (ret
) = type_decl
;
603 /* Now, fill in the type. */
605 static unsigned int ubsan_var_id_num
;
606 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
607 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
609 TREE_STATIC (var
) = 1;
610 TREE_PUBLIC (var
) = 0;
611 DECL_ARTIFICIAL (var
) = 1;
612 DECL_IGNORED_P (var
) = 1;
613 DECL_EXTERNAL (var
) = 0;
615 vec
<constructor_elt
, va_gc
> *v
;
617 tree ctor
= build_constructor (ret
, v
);
619 /* If desirable, set the __ubsan_source_location element. */
620 for (j
= 0; j
< loccnt
; j
++)
622 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
623 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
626 size_t nelts
= vec_safe_length (saved_args
);
627 for (i
= 0; i
< nelts
; i
++)
629 t
= (*saved_args
)[i
];
630 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
633 TREE_CONSTANT (ctor
) = 1;
634 TREE_STATIC (ctor
) = 1;
635 DECL_INITIAL (var
) = ctor
;
636 varpool_node::finalize_decl (var
);
641 /* Instrument the __builtin_unreachable call. We just call the libubsan
645 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
648 location_t loc
= gimple_location (gsi_stmt (*gsi
));
650 if (flag_sanitize_undefined_trap_on_error
)
651 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
654 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
655 NULL_TREE
, NULL_TREE
);
656 data
= build_fold_addr_expr_loc (loc
, data
);
658 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
659 g
= gimple_build_call (fn
, 1, data
);
661 gimple_set_location (g
, loc
);
662 gsi_replace (gsi
, g
, false);
666 /* Return true if T is a call to a libubsan routine. */
669 is_ubsan_builtin_p (tree t
)
671 return TREE_CODE (t
) == FUNCTION_DECL
672 && DECL_BUILT_IN_CLASS (t
) == BUILT_IN_NORMAL
673 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
674 "__builtin___ubsan_", 18) == 0;
677 /* Create a callgraph edge for statement STMT. */
680 ubsan_create_edge (gimple stmt
)
682 gcall
*call_stmt
= dyn_cast
<gcall
*> (stmt
);
683 basic_block bb
= gimple_bb (stmt
);
684 int freq
= compute_call_stmt_bb_frequency (current_function_decl
, bb
);
685 cgraph_node
*node
= cgraph_node::get (current_function_decl
);
686 tree decl
= gimple_call_fndecl (call_stmt
);
688 node
->create_edge (cgraph_node::get_create (decl
), call_stmt
, bb
->count
,
692 /* Expand the UBSAN_BOUNDS special builtin function. */
695 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
697 gimple stmt
= gsi_stmt (*gsi
);
698 location_t loc
= gimple_location (stmt
);
699 gcc_assert (gimple_call_num_args (stmt
) == 3);
701 /* Pick up the arguments of the UBSAN_BOUNDS call. */
702 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
703 tree index
= gimple_call_arg (stmt
, 1);
704 tree orig_index_type
= TREE_TYPE (index
);
705 tree bound
= gimple_call_arg (stmt
, 2);
707 gimple_stmt_iterator gsi_orig
= *gsi
;
709 /* Create condition "if (index > bound)". */
710 basic_block then_bb
, fallthru_bb
;
711 gimple_stmt_iterator cond_insert_point
712 = create_cond_insert_point (gsi
, false, false, true,
713 &then_bb
, &fallthru_bb
);
714 index
= fold_convert (TREE_TYPE (bound
), index
);
715 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
717 false, GSI_NEW_STMT
);
718 gimple g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
719 gimple_set_location (g
, loc
);
720 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
722 /* Generate __ubsan_handle_out_of_bounds call. */
723 *gsi
= gsi_after_labels (then_bb
);
724 if (flag_sanitize_undefined_trap_on_error
)
725 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
729 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
730 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
731 ubsan_type_descriptor (orig_index_type
),
732 NULL_TREE
, NULL_TREE
);
733 data
= build_fold_addr_expr_loc (loc
, data
);
734 enum built_in_function bcode
735 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
736 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
737 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
738 tree fn
= builtin_decl_explicit (bcode
);
739 tree val
= force_gimple_operand_gsi (gsi
, ubsan_encode_value (index
),
740 true, NULL_TREE
, true,
742 g
= gimple_build_call (fn
, 2, data
, val
);
744 gimple_set_location (g
, loc
);
745 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
747 /* Get rid of the UBSAN_BOUNDS call from the IR. */
748 unlink_stmt_vdef (stmt
);
749 gsi_remove (&gsi_orig
, true);
751 /* Point GSI to next logical statement. */
752 *gsi
= gsi_start_bb (fallthru_bb
);
756 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
757 argument which is a constant, because the middle-end treats pointer
758 conversions as useless and therefore the type of the first argument
759 could be changed to any other pointer type. */
762 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
764 gimple_stmt_iterator gsi
= *gsip
;
765 gimple stmt
= gsi_stmt (gsi
);
766 location_t loc
= gimple_location (stmt
);
767 gcc_assert (gimple_call_num_args (stmt
) == 3);
768 tree ptr
= gimple_call_arg (stmt
, 0);
769 tree ckind
= gimple_call_arg (stmt
, 1);
770 tree align
= gimple_call_arg (stmt
, 2);
771 tree check_align
= NULL_TREE
;
774 basic_block cur_bb
= gsi_bb (gsi
);
777 if (!integer_zerop (align
))
779 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
780 if (compare_tree_int (align
, ptralign
) == 1)
782 check_align
= make_ssa_name (pointer_sized_int_node
);
783 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
784 gimple_set_location (g
, loc
);
785 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
788 check_null
= (flag_sanitize
& SANITIZE_NULL
) != 0;
790 if (check_align
== NULL_TREE
&& !check_null
)
792 gsi_remove (gsip
, true);
793 /* Unlink the UBSAN_NULLs vops before replacing it. */
794 unlink_stmt_vdef (stmt
);
798 /* Split the original block holding the pointer dereference. */
799 edge e
= split_block (cur_bb
, stmt
);
801 /* Get a hold on the 'condition block', the 'then block' and the
803 basic_block cond_bb
= e
->src
;
804 basic_block fallthru_bb
= e
->dest
;
805 basic_block then_bb
= create_empty_bb (cond_bb
);
806 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
807 loops_state_set (LOOPS_NEED_FIXUP
);
809 /* Make an edge coming from the 'cond block' into the 'then block';
810 this edge is unlikely taken, so set up the probability accordingly. */
811 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
812 e
->probability
= PROB_VERY_UNLIKELY
;
814 /* Connect 'then block' with the 'else block'. This is needed
815 as the ubsan routines we call in the 'then block' are not noreturn.
816 The 'then block' only has one outcoming edge. */
817 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
819 /* Set up the fallthrough basic block. */
820 e
= find_edge (cond_bb
, fallthru_bb
);
821 e
->flags
= EDGE_FALSE_VALUE
;
822 e
->count
= cond_bb
->count
;
823 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
825 /* Update dominance info for the newly created then_bb; note that
826 fallthru_bb's dominance info has already been updated by
828 if (dom_info_available_p (CDI_DOMINATORS
))
829 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
831 /* Put the ubsan builtin call into the newly created BB. */
832 if (flag_sanitize_undefined_trap_on_error
)
833 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
836 enum built_in_function bcode
837 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
838 | (check_null
? SANITIZE_NULL
: 0)))
839 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
840 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
841 tree fn
= builtin_decl_implicit (bcode
);
843 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
844 ubsan_type_descriptor (TREE_TYPE (ckind
),
845 UBSAN_PRINT_POINTER
),
848 fold_convert (unsigned_char_type_node
, ckind
),
850 data
= build_fold_addr_expr_loc (loc
, data
);
851 g
= gimple_build_call (fn
, 2, data
,
852 check_align
? check_align
853 : build_zero_cst (pointer_sized_int_node
));
855 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
856 gimple_set_location (g
, loc
);
857 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
859 /* Unlink the UBSAN_NULLs vops before replacing it. */
860 unlink_stmt_vdef (stmt
);
864 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
865 NULL_TREE
, NULL_TREE
);
866 gimple_set_location (g
, loc
);
868 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
869 gsi_replace (&gsi
, g
, false);
877 /* Split the block with the condition again. */
878 e
= split_block (cond_bb
, stmt
);
879 basic_block cond1_bb
= e
->src
;
880 basic_block cond2_bb
= e
->dest
;
882 /* Make an edge coming from the 'cond1 block' into the 'then block';
883 this edge is unlikely taken, so set up the probability
885 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
886 e
->probability
= PROB_VERY_UNLIKELY
;
888 /* Set up the fallthrough basic block. */
889 e
= find_edge (cond1_bb
, cond2_bb
);
890 e
->flags
= EDGE_FALSE_VALUE
;
891 e
->count
= cond1_bb
->count
;
892 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
894 /* Update dominance info. */
895 if (dom_info_available_p (CDI_DOMINATORS
))
897 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
898 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
901 gsi2
= gsi_start_bb (cond2_bb
);
904 tree mask
= build_int_cst (pointer_sized_int_node
,
905 tree_to_uhwi (align
) - 1);
906 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
907 BIT_AND_EXPR
, check_align
, mask
);
908 gimple_set_location (g
, loc
);
910 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
912 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
914 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
915 build_int_cst (pointer_sized_int_node
, 0),
916 NULL_TREE
, NULL_TREE
);
917 gimple_set_location (g
, loc
);
919 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
921 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
922 gsi_replace (&gsi
, g
, false);
927 #define OBJSZ_MAX_OFFSET (1024 * 16)
929 /* Expand UBSAN_OBJECT_SIZE internal call. */
932 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
934 gimple stmt
= gsi_stmt (*gsi
);
935 location_t loc
= gimple_location (stmt
);
936 gcc_assert (gimple_call_num_args (stmt
) == 4);
938 tree ptr
= gimple_call_arg (stmt
, 0);
939 tree offset
= gimple_call_arg (stmt
, 1);
940 tree size
= gimple_call_arg (stmt
, 2);
941 tree ckind
= gimple_call_arg (stmt
, 3);
942 gimple_stmt_iterator gsi_orig
= *gsi
;
945 /* See if we can discard the check. */
946 if (TREE_CODE (size
) != INTEGER_CST
947 || integer_all_onesp (size
))
948 /* Yes, __builtin_object_size couldn't determine the
950 else if (TREE_CODE (offset
) == INTEGER_CST
951 && wi::ges_p (wi::to_widest (offset
), -OBJSZ_MAX_OFFSET
)
952 && wi::les_p (wi::to_widest (offset
), -1))
953 /* The offset is in range [-16K, -1]. */;
956 /* if (offset > objsize) */
957 basic_block then_bb
, fallthru_bb
;
958 gimple_stmt_iterator cond_insert_point
959 = create_cond_insert_point (gsi
, false, false, true,
960 &then_bb
, &fallthru_bb
);
961 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
962 gimple_set_location (g
, loc
);
963 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
965 /* If the offset is small enough, we don't need the second
967 if (TREE_CODE (offset
) == INTEGER_CST
968 && wi::ges_p (wi::to_widest (offset
), 0)
969 && wi::les_p (wi::to_widest (offset
), OBJSZ_MAX_OFFSET
))
970 *gsi
= gsi_after_labels (then_bb
);
973 /* Don't issue run-time error if (ptr > ptr + offset). That
974 may happen when computing a POINTER_PLUS_EXPR. */
975 basic_block then2_bb
, fallthru2_bb
;
977 gimple_stmt_iterator gsi2
= gsi_after_labels (then_bb
);
978 cond_insert_point
= create_cond_insert_point (&gsi2
, false, false,
981 /* Convert the pointer to an integer type. */
982 tree p
= make_ssa_name (pointer_sized_int_node
);
983 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
984 gimple_set_location (g
, loc
);
985 gsi_insert_before (&cond_insert_point
, g
, GSI_NEW_STMT
);
986 p
= gimple_assign_lhs (g
);
987 /* Compute ptr + offset. */
988 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
989 PLUS_EXPR
, p
, offset
);
990 gimple_set_location (g
, loc
);
991 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
992 /* Now build the conditional and put it into the IR. */
993 g
= gimple_build_cond (LE_EXPR
, p
, gimple_assign_lhs (g
),
994 NULL_TREE
, NULL_TREE
);
995 gimple_set_location (g
, loc
);
996 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
997 *gsi
= gsi_after_labels (then2_bb
);
1000 /* Generate __ubsan_handle_type_mismatch call. */
1001 if (flag_sanitize_undefined_trap_on_error
)
1002 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1006 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
1007 ubsan_type_descriptor (TREE_TYPE (ptr
),
1008 UBSAN_PRINT_POINTER
),
1010 build_zero_cst (pointer_sized_int_node
),
1013 data
= build_fold_addr_expr_loc (loc
, data
);
1014 enum built_in_function bcode
1015 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
1016 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1017 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
1018 tree p
= make_ssa_name (pointer_sized_int_node
);
1019 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
1020 gimple_set_location (g
, loc
);
1021 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1022 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
1024 gimple_set_location (g
, loc
);
1025 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1027 /* Point GSI to next logical statement. */
1028 *gsi
= gsi_start_bb (fallthru_bb
);
1030 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1031 unlink_stmt_vdef (stmt
);
1032 gsi_remove (&gsi_orig
, true);
1036 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1037 unlink_stmt_vdef (stmt
);
1038 gsi_remove (gsi
, true);
1042 /* Cached __ubsan_vptr_type_cache decl. */
1043 static GTY(()) tree ubsan_vptr_type_cache_decl
;
1045 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1046 argument which is a constant, because the middle-end treats pointer
1047 conversions as useless and therefore the type of the first argument
1048 could be changed to any other pointer type. */
1051 ubsan_expand_vptr_ifn (gimple_stmt_iterator
*gsip
)
1053 gimple_stmt_iterator gsi
= *gsip
;
1054 gimple stmt
= gsi_stmt (gsi
);
1055 location_t loc
= gimple_location (stmt
);
1056 gcc_assert (gimple_call_num_args (stmt
) == 5);
1057 tree op
= gimple_call_arg (stmt
, 0);
1058 tree vptr
= gimple_call_arg (stmt
, 1);
1059 tree str_hash
= gimple_call_arg (stmt
, 2);
1060 tree ti_decl_addr
= gimple_call_arg (stmt
, 3);
1061 tree ckind_tree
= gimple_call_arg (stmt
, 4);
1062 ubsan_null_ckind ckind
= (ubsan_null_ckind
) tree_to_uhwi (ckind_tree
);
1063 tree type
= TREE_TYPE (TREE_TYPE (ckind_tree
));
1065 basic_block fallthru_bb
= NULL
;
1067 if (ckind
== UBSAN_DOWNCAST_POINTER
)
1069 /* Guard everything with if (op != NULL) { ... }. */
1070 basic_block then_bb
;
1071 gimple_stmt_iterator cond_insert_point
1072 = create_cond_insert_point (gsip
, false, false, true,
1073 &then_bb
, &fallthru_bb
);
1074 g
= gimple_build_cond (NE_EXPR
, op
, build_zero_cst (TREE_TYPE (op
)),
1075 NULL_TREE
, NULL_TREE
);
1076 gimple_set_location (g
, loc
);
1077 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1078 *gsip
= gsi_after_labels (then_bb
);
1079 gsi_remove (&gsi
, false);
1080 gsi_insert_before (gsip
, stmt
, GSI_NEW_STMT
);
1084 tree htype
= TREE_TYPE (str_hash
);
1085 tree cst
= wide_int_to_tree (htype
,
1086 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1088 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1090 gimple_set_location (g
, loc
);
1091 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1092 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1093 gimple_assign_lhs (g
), cst
);
1094 gimple_set_location (g
, loc
);
1095 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1096 tree t1
= gimple_assign_lhs (g
);
1097 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1098 t1
, build_int_cst (integer_type_node
, 47));
1099 gimple_set_location (g
, loc
);
1100 tree t2
= gimple_assign_lhs (g
);
1101 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1102 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1104 gimple_set_location (g
, loc
);
1105 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1106 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1107 t2
, gimple_assign_lhs (g
));
1108 gimple_set_location (g
, loc
);
1109 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1110 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1111 gimple_assign_lhs (g
), cst
);
1112 gimple_set_location (g
, loc
);
1113 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1114 tree t3
= gimple_assign_lhs (g
);
1115 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1116 t3
, build_int_cst (integer_type_node
, 47));
1117 gimple_set_location (g
, loc
);
1118 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1119 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1120 t3
, gimple_assign_lhs (g
));
1121 gimple_set_location (g
, loc
);
1122 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1123 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1124 gimple_assign_lhs (g
), cst
);
1125 gimple_set_location (g
, loc
);
1126 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1127 if (!useless_type_conversion_p (pointer_sized_int_node
, htype
))
1129 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1130 NOP_EXPR
, gimple_assign_lhs (g
));
1131 gimple_set_location (g
, loc
);
1132 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1134 tree hash
= gimple_assign_lhs (g
);
1136 if (ubsan_vptr_type_cache_decl
== NULL_TREE
)
1138 tree atype
= build_array_type_nelts (pointer_sized_int_node
, 128);
1139 tree array
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1140 get_identifier ("__ubsan_vptr_type_cache"),
1142 DECL_ARTIFICIAL (array
) = 1;
1143 DECL_IGNORED_P (array
) = 1;
1144 TREE_PUBLIC (array
) = 1;
1145 TREE_STATIC (array
) = 1;
1146 DECL_EXTERNAL (array
) = 1;
1147 DECL_VISIBILITY (array
) = VISIBILITY_DEFAULT
;
1148 DECL_VISIBILITY_SPECIFIED (array
) = 1;
1149 varpool_node::finalize_decl (array
);
1150 ubsan_vptr_type_cache_decl
= array
;
1153 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1155 build_int_cst (pointer_sized_int_node
, 127));
1156 gimple_set_location (g
, loc
);
1157 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1159 tree c
= build4_loc (loc
, ARRAY_REF
, pointer_sized_int_node
,
1160 ubsan_vptr_type_cache_decl
, gimple_assign_lhs (g
),
1161 NULL_TREE
, NULL_TREE
);
1162 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1164 gimple_set_location (g
, loc
);
1165 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1167 basic_block then_bb
, fallthru2_bb
;
1168 gimple_stmt_iterator cond_insert_point
1169 = create_cond_insert_point (gsip
, false, false, true,
1170 &then_bb
, &fallthru2_bb
);
1171 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
), hash
,
1172 NULL_TREE
, NULL_TREE
);
1173 gimple_set_location (g
, loc
);
1174 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1175 *gsip
= gsi_after_labels (then_bb
);
1176 if (fallthru_bb
== NULL
)
1177 fallthru_bb
= fallthru2_bb
;
1180 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc
,
1181 ubsan_type_descriptor (type
), NULL_TREE
, ti_decl_addr
,
1182 build_int_cst (unsigned_char_type_node
, ckind
),
1184 data
= build_fold_addr_expr_loc (loc
, data
);
1185 enum built_in_function bcode
1186 = (flag_sanitize_recover
& SANITIZE_VPTR
)
1187 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1188 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT
;
1190 g
= gimple_build_call (builtin_decl_explicit (bcode
), 3, data
, op
, hash
);
1191 gimple_set_location (g
, loc
);
1192 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1194 /* Point GSI to next logical statement. */
1195 *gsip
= gsi_start_bb (fallthru_bb
);
1197 /* Get rid of the UBSAN_VPTR call from the IR. */
1198 unlink_stmt_vdef (stmt
);
1199 gsi_remove (&gsi
, true);
1203 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1204 whether the pointer is on the left hand side of the assignment. */
1207 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
1210 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
1211 unsigned int align
= 0;
1212 if (flag_sanitize
& SANITIZE_ALIGNMENT
)
1214 align
= min_align_of_type (TREE_TYPE (base
));
1218 if (align
== 0 && (flag_sanitize
& SANITIZE_NULL
) == 0)
1220 tree t
= TREE_OPERAND (base
, 0);
1221 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
1223 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base
)) && mem
!= base
)
1224 ikind
= UBSAN_MEMBER_ACCESS
;
1225 tree kind
= build_int_cst (build_pointer_type (TREE_TYPE (base
)), ikind
);
1226 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
1227 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
1228 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
1229 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
1232 /* Perform the pointer instrumentation. */
1235 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
1237 gimple stmt
= gsi_stmt (gsi
);
1238 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1239 tree base
= get_base_address (t
);
1240 const enum tree_code code
= TREE_CODE (base
);
1242 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1243 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1246 /* Build an ubsan builtin call for the signed-integer-overflow
1247 sanitization. CODE says what kind of builtin are we building,
1248 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1249 are operands of the binary operation. */
1252 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1255 if (flag_sanitize_undefined_trap_on_error
)
1256 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1258 tree data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1259 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1261 enum built_in_function fn_code
;
1266 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1267 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1268 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1271 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1272 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1273 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1276 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1277 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1278 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1281 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1282 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1283 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1288 tree fn
= builtin_decl_explicit (fn_code
);
1289 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1290 build_fold_addr_expr_loc (loc
, data
),
1291 ubsan_encode_value (op0
, true),
1292 op1
? ubsan_encode_value (op1
, true)
1296 /* Perform the signed integer instrumentation. GSI is the iterator
1297 pointing at statement we are trying to instrument. */
1300 instrument_si_overflow (gimple_stmt_iterator gsi
)
1302 gimple stmt
= gsi_stmt (gsi
);
1303 tree_code code
= gimple_assign_rhs_code (stmt
);
1304 tree lhs
= gimple_assign_lhs (stmt
);
1305 tree lhstype
= TREE_TYPE (lhs
);
1309 /* If this is not a signed operation, don't instrument anything here.
1310 Also punt on bit-fields. */
1311 if (!INTEGRAL_TYPE_P (lhstype
)
1312 || TYPE_OVERFLOW_WRAPS (lhstype
)
1313 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
1324 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1325 a
= gimple_assign_rhs1 (stmt
);
1326 b
= gimple_assign_rhs2 (stmt
);
1327 g
= gimple_build_call_internal (code
== PLUS_EXPR
1328 ? IFN_UBSAN_CHECK_ADD
1329 : code
== MINUS_EXPR
1330 ? IFN_UBSAN_CHECK_SUB
1331 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1332 gimple_call_set_lhs (g
, lhs
);
1333 gsi_replace (&gsi
, g
, false);
1336 /* Represent i = -u;
1338 i = UBSAN_CHECK_SUB (0, u); */
1339 a
= build_int_cst (lhstype
, 0);
1340 b
= gimple_assign_rhs1 (stmt
);
1341 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1342 gimple_call_set_lhs (g
, lhs
);
1343 gsi_replace (&gsi
, g
, false);
1346 /* Transform i = ABS_EXPR<u>;
1348 _N = UBSAN_CHECK_SUB (0, u);
1349 i = ABS_EXPR<_N>; */
1350 a
= build_int_cst (lhstype
, 0);
1351 b
= gimple_assign_rhs1 (stmt
);
1352 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1353 a
= make_ssa_name (lhstype
);
1354 gimple_call_set_lhs (g
, a
);
1355 gimple_set_location (g
, gimple_location (stmt
));
1356 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1357 gimple_assign_set_rhs1 (stmt
, a
);
1365 /* Instrument loads from (non-bitfield) bool and C++ enum values
1366 to check if the memory value is outside of the range of the valid
1370 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1372 gimple stmt
= gsi_stmt (*gsi
);
1373 tree rhs
= gimple_assign_rhs1 (stmt
);
1374 tree type
= TREE_TYPE (rhs
);
1375 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1377 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
1379 minv
= boolean_false_node
;
1380 maxv
= boolean_true_node
;
1382 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1383 && (flag_sanitize
& SANITIZE_ENUM
)
1384 && TREE_TYPE (type
) != NULL_TREE
1385 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1386 && (TYPE_PRECISION (TREE_TYPE (type
))
1387 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1389 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1390 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1395 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1396 HOST_WIDE_INT bitsize
, bitpos
;
1399 int volatilep
= 0, unsignedp
= 0;
1400 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1401 &unsignedp
, &volatilep
, false);
1402 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1404 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
1405 || (bitpos
% modebitsize
) != 0
1406 || bitsize
!= modebitsize
1407 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1408 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1411 bool ends_bb
= stmt_ends_bb_p (stmt
);
1412 location_t loc
= gimple_location (stmt
);
1413 tree lhs
= gimple_assign_lhs (stmt
);
1414 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1415 tree atype
= reference_alias_ptr_type (rhs
);
1416 gimple g
= gimple_build_assign (make_ssa_name (ptype
),
1417 build_fold_addr_expr (rhs
));
1418 gimple_set_location (g
, loc
);
1419 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1420 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1421 build_int_cst (atype
, 0));
1422 tree urhs
= make_ssa_name (utype
);
1425 gimple_assign_set_lhs (stmt
, urhs
);
1426 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1427 gimple_set_location (g
, loc
);
1428 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1429 gsi_insert_on_edge_immediate (e
, g
);
1430 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1432 *gsi
= gsi_for_stmt (g
);
1437 g
= gimple_build_assign (urhs
, mem
);
1438 gimple_set_location (g
, loc
);
1439 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1441 minv
= fold_convert (utype
, minv
);
1442 maxv
= fold_convert (utype
, maxv
);
1443 if (!integer_zerop (minv
))
1445 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1446 gimple_set_location (g
, loc
);
1447 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1450 gimple_stmt_iterator gsi2
= *gsi
;
1451 basic_block then_bb
, fallthru_bb
;
1452 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1453 &then_bb
, &fallthru_bb
);
1454 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1455 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1456 NULL_TREE
, NULL_TREE
);
1457 gimple_set_location (g
, loc
);
1458 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1462 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1466 gsi2
= gsi_after_labels (then_bb
);
1467 if (flag_sanitize_undefined_trap_on_error
)
1468 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1471 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1472 ubsan_type_descriptor (type
), NULL_TREE
,
1474 data
= build_fold_addr_expr_loc (loc
, data
);
1475 enum built_in_function bcode
1476 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1477 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1478 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1479 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1480 tree fn
= builtin_decl_explicit (bcode
);
1482 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
1483 true, NULL_TREE
, true,
1485 g
= gimple_build_call (fn
, 2, data
, val
);
1487 gimple_set_location (g
, loc
);
1488 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1489 ubsan_create_edge (g
);
1490 *gsi
= gsi_for_stmt (stmt
);
1493 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1494 destination, EXPR is floating-point expression. ARG is what to pass
1495 the libubsan call as value, often EXPR itself. */
1498 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
, tree arg
)
1500 tree expr_type
= TREE_TYPE (expr
);
1501 tree t
, tt
, fn
, min
, max
;
1502 machine_mode mode
= TYPE_MODE (expr_type
);
1503 int prec
= TYPE_PRECISION (type
);
1504 bool uns_p
= TYPE_UNSIGNED (type
);
1506 /* Float to integer conversion first truncates toward zero, so
1507 even signed char c = 127.875f; is not problematic.
1508 Therefore, we should complain only if EXPR is unordered or smaller
1509 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1510 TYPE_MAX_VALUE + 1.0. */
1511 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1513 /* For maximum, TYPE_MAX_VALUE might not be representable
1514 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1515 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1516 either representable or infinity. */
1517 REAL_VALUE_TYPE maxval
= dconst1
;
1518 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1519 real_convert (&maxval
, mode
, &maxval
);
1520 max
= build_real (expr_type
, maxval
);
1522 /* For unsigned, assume -1.0 is always representable. */
1524 min
= build_minus_one_cst (expr_type
);
1527 /* TYPE_MIN_VALUE is generally representable (or -inf),
1528 but TYPE_MIN_VALUE - 1.0 might not be. */
1529 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1530 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1531 real_convert (&minval
, mode
, &minval
);
1532 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1533 real_convert (&minval2
, mode
, &minval2
);
1534 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1535 && !real_isinf (&minval
))
1537 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1538 rounds to TYPE_MIN_VALUE, we need to subtract
1539 more. As REAL_MODE_FORMAT (mode)->p is the number
1540 of base digits, we want to subtract a number that
1541 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1542 times smaller than minval. */
1544 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1545 SET_REAL_EXP (&minval2
,
1546 REAL_EXP (&minval2
) + prec
- 1
1547 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1548 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1549 real_convert (&minval2
, mode
, &minval2
);
1551 min
= build_real (expr_type
, minval2
);
1554 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1556 /* For _Decimal128 up to 34 decimal digits, - sign,
1557 dot, e, exponent. */
1560 int p
= REAL_MODE_FORMAT (mode
)->p
;
1561 REAL_VALUE_TYPE maxval
, minval
;
1563 /* Use mpfr_snprintf rounding to compute the smallest
1564 representable decimal number greater or equal than
1565 1 << (prec - !uns_p). */
1566 mpfr_init2 (m
, prec
+ 2);
1567 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1568 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1569 decimal_real_from_string (&maxval
, buf
);
1570 max
= build_real (expr_type
, maxval
);
1572 /* For unsigned, assume -1.0 is always representable. */
1574 min
= build_minus_one_cst (expr_type
);
1577 /* Use mpfr_snprintf rounding to compute the largest
1578 representable decimal number less or equal than
1579 (-1 << (prec - 1)) - 1. */
1580 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1581 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1582 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1583 decimal_real_from_string (&minval
, buf
);
1584 min
= build_real (expr_type
, minval
);
1591 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1592 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1593 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
);
1594 if (integer_zerop (t
))
1597 if (flag_sanitize_undefined_trap_on_error
)
1598 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1601 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1602 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1603 NULL
, ubsan_type_descriptor (expr_type
),
1604 ubsan_type_descriptor (type
), NULL_TREE
,
1606 enum built_in_function bcode
1607 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1608 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1609 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1610 fn
= builtin_decl_explicit (bcode
);
1611 fn
= build_call_expr_loc (loc
, fn
, 2,
1612 build_fold_addr_expr_loc (loc
, data
),
1613 ubsan_encode_value (arg
, false));
1616 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1619 /* Instrument values passed to function arguments with nonnull attribute. */
1622 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1624 gimple stmt
= gsi_stmt (*gsi
);
1626 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1627 while for nonnull sanitization it is clear. */
1628 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1629 flag_delete_null_pointer_checks
= 1;
1630 loc
[0] = gimple_location (stmt
);
1631 loc
[1] = UNKNOWN_LOCATION
;
1632 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1634 tree arg
= gimple_call_arg (stmt
, i
);
1635 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1636 && infer_nonnull_range (stmt
, arg
, false, true))
1639 if (!is_gimple_val (arg
))
1641 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1642 gimple_set_location (g
, loc
[0]);
1643 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1644 arg
= gimple_assign_lhs (g
);
1647 basic_block then_bb
, fallthru_bb
;
1648 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1649 &then_bb
, &fallthru_bb
);
1650 g
= gimple_build_cond (EQ_EXPR
, arg
,
1651 build_zero_cst (TREE_TYPE (arg
)),
1652 NULL_TREE
, NULL_TREE
);
1653 gimple_set_location (g
, loc
[0]);
1654 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1656 *gsi
= gsi_after_labels (then_bb
);
1657 if (flag_sanitize_undefined_trap_on_error
)
1658 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1661 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1663 build_int_cst (integer_type_node
,
1666 data
= build_fold_addr_expr_loc (loc
[0], data
);
1667 enum built_in_function bcode
1668 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1669 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1670 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1671 tree fn
= builtin_decl_explicit (bcode
);
1673 g
= gimple_build_call (fn
, 1, data
);
1675 gimple_set_location (g
, loc
[0]);
1676 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1677 ubsan_create_edge (g
);
1679 *gsi
= gsi_for_stmt (stmt
);
1681 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1684 /* Instrument returns in functions with returns_nonnull attribute. */
1687 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1689 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
1691 tree arg
= gimple_return_retval (stmt
);
1692 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1693 while for nonnull return sanitization it is clear. */
1694 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1695 flag_delete_null_pointer_checks
= 1;
1696 loc
[0] = gimple_location (stmt
);
1697 loc
[1] = UNKNOWN_LOCATION
;
1699 && POINTER_TYPE_P (TREE_TYPE (arg
))
1700 && is_gimple_val (arg
)
1701 && infer_nonnull_range (stmt
, arg
, false, true))
1703 basic_block then_bb
, fallthru_bb
;
1704 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1705 &then_bb
, &fallthru_bb
);
1706 gimple g
= gimple_build_cond (EQ_EXPR
, arg
,
1707 build_zero_cst (TREE_TYPE (arg
)),
1708 NULL_TREE
, NULL_TREE
);
1709 gimple_set_location (g
, loc
[0]);
1710 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1712 *gsi
= gsi_after_labels (then_bb
);
1713 if (flag_sanitize_undefined_trap_on_error
)
1714 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1717 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
1718 2, loc
, NULL_TREE
, NULL_TREE
);
1719 data
= build_fold_addr_expr_loc (loc
[0], data
);
1720 enum built_in_function bcode
1721 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1722 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1723 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
1724 tree fn
= builtin_decl_explicit (bcode
);
1726 g
= gimple_build_call (fn
, 1, data
);
1728 gimple_set_location (g
, loc
[0]);
1729 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1730 ubsan_create_edge (g
);
1731 *gsi
= gsi_for_stmt (stmt
);
1733 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1736 /* Instrument memory references. Here we check whether the pointer
1737 points to an out-of-bounds location. */
1740 instrument_object_size (gimple_stmt_iterator
*gsi
, bool is_lhs
)
1742 gimple stmt
= gsi_stmt (*gsi
);
1743 location_t loc
= gimple_location (stmt
);
1744 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1746 tree index
= NULL_TREE
;
1747 HOST_WIDE_INT size_in_bytes
;
1749 type
= TREE_TYPE (t
);
1750 if (VOID_TYPE_P (type
))
1753 switch (TREE_CODE (t
))
1756 if (TREE_CODE (t
) == COMPONENT_REF
1757 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
1759 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
1760 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
1765 index
= TREE_OPERAND (t
, 1);
1777 size_in_bytes
= int_size_in_bytes (type
);
1778 if (size_in_bytes
<= 0)
1781 HOST_WIDE_INT bitsize
, bitpos
;
1784 int volatilep
= 0, unsignedp
= 0;
1785 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1786 &unsignedp
, &volatilep
, false);
1788 if (bitpos
% BITS_PER_UNIT
!= 0
1789 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
1792 bool decl_p
= DECL_P (inner
);
1796 else if (TREE_CODE (inner
) == MEM_REF
)
1797 base
= TREE_OPERAND (inner
, 0);
1800 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
1802 while (TREE_CODE (base
) == SSA_NAME
)
1804 gimple def_stmt
= SSA_NAME_DEF_STMT (base
);
1805 if (gimple_assign_ssa_name_copy_p (def_stmt
)
1806 || (gimple_assign_cast_p (def_stmt
)
1807 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
1808 || (is_gimple_assign (def_stmt
)
1809 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
1811 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
1812 if (TREE_CODE (rhs1
) == SSA_NAME
1813 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
1822 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1826 tree base_addr
= base
;
1827 gimple bos_stmt
= NULL
;
1829 base_addr
= build1 (ADDR_EXPR
,
1830 build_pointer_type (TREE_TYPE (base
)), base
);
1831 unsigned HOST_WIDE_INT size
= compute_builtin_object_size (base_addr
, 0);
1832 if (size
!= (unsigned HOST_WIDE_INT
) -1)
1833 sizet
= build_int_cst (sizetype
, size
);
1836 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
1837 loc
= input_location
;
1838 /* Generate __builtin_object_size call. */
1839 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
1840 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
1842 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
1844 /* If the call above didn't end up being an integer constant, go one
1845 statement back and get the __builtin_object_size stmt. Save it,
1846 we might need it later. */
1847 if (SSA_VAR_P (sizet
))
1850 bos_stmt
= gsi_stmt (*gsi
);
1852 /* Move on to where we were. */
1859 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1861 /* ptr + sizeof (*ptr) - base */
1862 t
= fold_build2 (MINUS_EXPR
, sizetype
,
1863 fold_convert (pointer_sized_int_node
, ptr
),
1864 fold_convert (pointer_sized_int_node
, base_addr
));
1865 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
1867 /* Perhaps we can omit the check. */
1868 if (TREE_CODE (t
) == INTEGER_CST
1869 && TREE_CODE (sizet
) == INTEGER_CST
1870 && tree_int_cst_le (t
, sizet
))
1873 if (index
!= NULL_TREE
1874 && TREE_CODE (index
) == SSA_NAME
1875 && TREE_CODE (sizet
) == INTEGER_CST
)
1877 gimple def
= SSA_NAME_DEF_STMT (index
);
1878 if (is_gimple_assign (def
)
1879 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
1880 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
1882 tree cst
= gimple_assign_rhs2 (def
);
1883 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
1884 TYPE_SIZE_UNIT (type
));
1885 if (tree_int_cst_sgn (cst
) >= 0
1886 && tree_int_cst_lt (cst
, sz
))
1891 if (bos_stmt
&& gimple_call_builtin_p (bos_stmt
, BUILT_IN_OBJECT_SIZE
))
1892 ubsan_create_edge (bos_stmt
);
1894 /* We have to emit the check. */
1895 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1897 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
1899 tree ckind
= build_int_cst (unsigned_char_type_node
,
1900 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
1901 gimple g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
1902 ptr
, t
, sizet
, ckind
);
1903 gimple_set_location (g
, loc
);
1904 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1907 /* True if we want to play UBSan games in the current function. */
1910 do_ubsan_in_current_function ()
1912 return (current_function_decl
!= NULL_TREE
1913 && !lookup_attribute ("no_sanitize_undefined",
1914 DECL_ATTRIBUTES (current_function_decl
)));
1919 const pass_data pass_data_ubsan
=
1921 GIMPLE_PASS
, /* type */
1923 OPTGROUP_NONE
, /* optinfo_flags */
1924 TV_TREE_UBSAN
, /* tv_id */
1925 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1926 0, /* properties_provided */
1927 0, /* properties_destroyed */
1928 0, /* todo_flags_start */
1929 TODO_update_ssa
, /* todo_flags_finish */
1932 class pass_ubsan
: public gimple_opt_pass
1935 pass_ubsan (gcc::context
*ctxt
)
1936 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1939 /* opt_pass methods: */
1940 virtual bool gate (function
*)
1942 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1943 | SANITIZE_BOOL
| SANITIZE_ENUM
1944 | SANITIZE_ALIGNMENT
1945 | SANITIZE_NONNULL_ATTRIBUTE
1946 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1947 | SANITIZE_OBJECT_SIZE
)
1948 && do_ubsan_in_current_function ();
1951 virtual unsigned int execute (function
*);
1953 }; // class pass_ubsan
1956 pass_ubsan::execute (function
*fun
)
1959 gimple_stmt_iterator gsi
;
1961 initialize_sanitizer_builtins ();
1963 FOR_EACH_BB_FN (bb
, fun
)
1965 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1967 gimple stmt
= gsi_stmt (gsi
);
1968 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
1974 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
1975 && is_gimple_assign (stmt
))
1976 instrument_si_overflow (gsi
);
1978 if (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1980 if (gimple_store_p (stmt
))
1981 instrument_null (gsi
, true);
1982 if (gimple_assign_load_p (stmt
))
1983 instrument_null (gsi
, false);
1986 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
1987 && gimple_assign_load_p (stmt
))
1989 instrument_bool_enum_load (&gsi
);
1990 bb
= gimple_bb (stmt
);
1993 if ((flag_sanitize
& SANITIZE_NONNULL_ATTRIBUTE
)
1994 && is_gimple_call (stmt
)
1995 && !gimple_call_internal_p (stmt
))
1997 instrument_nonnull_arg (&gsi
);
1998 bb
= gimple_bb (stmt
);
2001 if ((flag_sanitize
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
2002 && gimple_code (stmt
) == GIMPLE_RETURN
)
2004 instrument_nonnull_return (&gsi
);
2005 bb
= gimple_bb (stmt
);
2008 if (flag_sanitize
& SANITIZE_OBJECT_SIZE
)
2010 if (gimple_store_p (stmt
))
2011 instrument_object_size (&gsi
, true);
2012 if (gimple_assign_load_p (stmt
))
2013 instrument_object_size (&gsi
, false);
2025 make_pass_ubsan (gcc::context
*ctxt
)
2027 return new pass_ubsan (ctxt
);
2030 #include "gt-ubsan.h"