1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2016 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
26 #include "c-family/c-common.h"
29 #include "tree-pass.h"
33 #include "tree-pretty-print.h"
34 #include "stor-layout.h"
36 #include "gimple-iterator.h"
42 #include "gimplify-me.h"
45 #include "tree-object-size.h"
48 /* Map from a tree to a VAR_DECL tree. */
50 struct GTY((for_user
)) tree_type_map
{
51 struct tree_map_base type
;
55 struct tree_type_map_cache_hasher
: ggc_cache_ptr_hash
<tree_type_map
>
57 static inline hashval_t
58 hash (tree_type_map
*t
)
60 return TYPE_UID (t
->type
.from
);
64 equal (tree_type_map
*a
, tree_type_map
*b
)
66 return a
->type
.from
== b
->type
.from
;
70 keep_cache_entry (tree_type_map
*&m
)
72 return ggc_marked_p (m
->type
.from
);
77 hash_table
<tree_type_map_cache_hasher
> *decl_tree_for_type
;
79 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
82 decl_for_type_lookup (tree type
)
84 /* If the hash table is not initialized yet, create it now. */
85 if (decl_tree_for_type
== NULL
)
88 = hash_table
<tree_type_map_cache_hasher
>::create_ggc (10);
89 /* That also means we don't have to bother with the lookup. */
93 struct tree_type_map
*h
, in
;
96 h
= decl_tree_for_type
->find_with_hash (&in
, TYPE_UID (type
));
97 return h
? h
->decl
: NULL_TREE
;
100 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
103 decl_for_type_insert (tree type
, tree decl
)
105 struct tree_type_map
*h
;
107 h
= ggc_alloc
<tree_type_map
> ();
110 *decl_tree_for_type
->find_slot_with_hash (h
, TYPE_UID (type
), INSERT
) = h
;
113 /* Helper routine, which encodes a value in the pointer_sized_int_node.
114 Arguments with precision <= POINTER_SIZE are passed directly,
115 the rest is passed by reference. T is a value we are to encode.
116 IN_EXPAND_P is true if this function is called during expansion. */
119 ubsan_encode_value (tree t
, bool in_expand_p
)
121 tree type
= TREE_TYPE (t
);
122 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
123 if (bitsize
<= POINTER_SIZE
)
124 switch (TREE_CODE (type
))
129 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
132 tree itype
= build_nonstandard_integer_type (bitsize
, true);
133 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
134 return fold_convert (pointer_sized_int_node
, t
);
141 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
143 /* The reason for this is that we don't want to pessimize
144 code by making vars unnecessarily addressable. */
145 tree var
= create_tmp_var (type
);
146 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
150 = assign_stack_temp_for_type (TYPE_MODE (type
),
151 GET_MODE_SIZE (TYPE_MODE (type
)),
153 SET_DECL_RTL (var
, mem
);
154 expand_assignment (var
, t
, false);
155 return build_fold_addr_expr (var
);
157 t
= build_fold_addr_expr (var
);
158 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
161 return build_fold_addr_expr (t
);
165 /* Cached ubsan_get_type_descriptor_type () return value. */
166 static GTY(()) tree ubsan_type_descriptor_type
;
169 struct __ubsan_type_descriptor
171 unsigned short __typekind;
172 unsigned short __typeinfo;
178 ubsan_get_type_descriptor_type (void)
180 static const char *field_names
[3]
181 = { "__typekind", "__typeinfo", "__typename" };
184 if (ubsan_type_descriptor_type
)
185 return ubsan_type_descriptor_type
;
187 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
188 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
190 ret
= make_node (RECORD_TYPE
);
191 for (int i
= 0; i
< 3; i
++)
193 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
194 get_identifier (field_names
[i
]),
195 (i
== 2) ? flex_arr_type
196 : short_unsigned_type_node
);
197 DECL_CONTEXT (fields
[i
]) = ret
;
199 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
201 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
202 get_identifier ("__ubsan_type_descriptor"),
204 DECL_IGNORED_P (type_decl
) = 1;
205 DECL_ARTIFICIAL (type_decl
) = 1;
206 TYPE_FIELDS (ret
) = fields
[0];
207 TYPE_NAME (ret
) = type_decl
;
208 TYPE_STUB_DECL (ret
) = type_decl
;
210 ubsan_type_descriptor_type
= ret
;
214 /* Cached ubsan_get_source_location_type () return value. */
215 static GTY(()) tree ubsan_source_location_type
;
218 struct __ubsan_source_location
220 const char *__filename;
222 unsigned int __column;
227 ubsan_get_source_location_type (void)
229 static const char *field_names
[3]
230 = { "__filename", "__line", "__column" };
232 if (ubsan_source_location_type
)
233 return ubsan_source_location_type
;
235 tree const_char_type
= build_qualified_type (char_type_node
,
238 ret
= make_node (RECORD_TYPE
);
239 for (int i
= 0; i
< 3; i
++)
241 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
242 get_identifier (field_names
[i
]),
243 (i
== 0) ? build_pointer_type (const_char_type
)
244 : unsigned_type_node
);
245 DECL_CONTEXT (fields
[i
]) = ret
;
247 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
249 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
250 get_identifier ("__ubsan_source_location"),
252 DECL_IGNORED_P (type_decl
) = 1;
253 DECL_ARTIFICIAL (type_decl
) = 1;
254 TYPE_FIELDS (ret
) = fields
[0];
255 TYPE_NAME (ret
) = type_decl
;
256 TYPE_STUB_DECL (ret
) = type_decl
;
258 ubsan_source_location_type
= ret
;
262 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
263 type with its fields filled from a location_t LOC. */
266 ubsan_source_location (location_t loc
)
268 expanded_location xloc
;
269 tree type
= ubsan_get_source_location_type ();
271 xloc
= expand_location (loc
);
273 if (xloc
.file
== NULL
)
275 str
= build_int_cst (ptr_type_node
, 0);
281 /* Fill in the values from LOC. */
282 size_t len
= strlen (xloc
.file
) + 1;
283 str
= build_string (len
, xloc
.file
);
284 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
285 TREE_READONLY (str
) = 1;
286 TREE_STATIC (str
) = 1;
287 str
= build_fold_addr_expr (str
);
289 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
290 build_int_cst (unsigned_type_node
,
291 xloc
.line
), NULL_TREE
,
292 build_int_cst (unsigned_type_node
,
294 TREE_CONSTANT (ctor
) = 1;
295 TREE_STATIC (ctor
) = 1;
300 /* This routine returns a magic number for TYPE. */
302 static unsigned short
303 get_ubsan_type_info_for_type (tree type
)
305 if (TREE_CODE (type
) == REAL_TYPE
)
306 return tree_to_uhwi (TYPE_SIZE (type
));
307 else if (INTEGRAL_TYPE_P (type
))
309 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
310 gcc_assert (prec
!= -1);
311 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
317 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
318 descriptor. It first looks into the hash table; if not found,
319 create the VAR_DECL, put it into the hash table and return the
320 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
321 an enum controlling how we want to print the type. */
324 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
326 /* See through any typedefs. */
327 type
= TYPE_MAIN_VARIANT (type
);
329 tree decl
= decl_for_type_lookup (type
);
330 /* It is possible that some of the earlier created DECLs were found
331 unused, in that case they weren't emitted and varpool_node::get
332 returns NULL node on them. But now we really need them. Thus,
334 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
335 return build_fold_addr_expr (decl
);
337 tree dtype
= ubsan_get_type_descriptor_type ();
339 const char *tname
= NULL
;
340 pretty_printer pretty_name
;
341 unsigned char deref_depth
= 0;
342 unsigned short tkind
, tinfo
;
344 /* Get the name of the type, or the name of the pointer type. */
345 if (pstyle
== UBSAN_PRINT_POINTER
)
347 gcc_assert (POINTER_TYPE_P (type
));
348 type2
= TREE_TYPE (type
);
350 /* Remove any '*' operators from TYPE. */
351 while (POINTER_TYPE_P (type2
))
352 deref_depth
++, type2
= TREE_TYPE (type2
);
354 if (TREE_CODE (type2
) == METHOD_TYPE
)
355 type2
= TYPE_METHOD_BASETYPE (type2
);
358 /* If an array, get its type. */
359 type2
= strip_array_types (type2
);
361 if (pstyle
== UBSAN_PRINT_ARRAY
)
363 while (POINTER_TYPE_P (type2
))
364 deref_depth
++, type2
= TREE_TYPE (type2
);
367 if (TYPE_NAME (type2
) != NULL
)
369 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
370 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
371 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
372 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
376 /* We weren't able to determine the type name. */
379 if (pstyle
== UBSAN_PRINT_POINTER
)
381 pp_printf (&pretty_name
, "'%s%s%s%s%s%s%s",
382 TYPE_VOLATILE (type2
) ? "volatile " : "",
383 TYPE_READONLY (type2
) ? "const " : "",
384 TYPE_RESTRICT (type2
) ? "restrict " : "",
385 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
386 TREE_CODE (type2
) == RECORD_TYPE
388 : TREE_CODE (type2
) == UNION_TYPE
389 ? "union " : "", tname
,
390 deref_depth
== 0 ? "" : " ");
391 while (deref_depth
-- > 0)
392 pp_star (&pretty_name
);
393 pp_quote (&pretty_name
);
395 else if (pstyle
== UBSAN_PRINT_ARRAY
)
397 /* Pretty print the array dimensions. */
398 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
400 pp_printf (&pretty_name
, "'%s ", tname
);
401 while (deref_depth
-- > 0)
402 pp_star (&pretty_name
);
403 while (TREE_CODE (t
) == ARRAY_TYPE
)
405 pp_left_bracket (&pretty_name
);
406 tree dom
= TYPE_DOMAIN (t
);
407 if (dom
&& TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
409 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom
))
410 && tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1 != 0)
411 pp_printf (&pretty_name
, HOST_WIDE_INT_PRINT_DEC
,
412 tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1);
414 pp_wide_int (&pretty_name
,
415 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom
)), 1),
416 TYPE_SIGN (TREE_TYPE (dom
)));
419 /* ??? We can't determine the variable name; print VLA unspec. */
420 pp_star (&pretty_name
);
421 pp_right_bracket (&pretty_name
);
424 pp_quote (&pretty_name
);
426 /* Save the tree with stripped types. */
430 pp_printf (&pretty_name
, "'%s'", tname
);
432 switch (TREE_CODE (type
))
440 /* FIXME: libubsan right now only supports float, double and
441 long double type formats. */
442 if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
)
443 || TYPE_MODE (type
) == TYPE_MODE (double_type_node
)
444 || TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
453 tinfo
= get_ubsan_type_info_for_type (type
);
455 /* Create a new VAR_DECL of type descriptor. */
456 const char *tmp
= pp_formatted_text (&pretty_name
);
457 size_t len
= strlen (tmp
) + 1;
458 tree str
= build_string (len
, tmp
);
459 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
460 TREE_READONLY (str
) = 1;
461 TREE_STATIC (str
) = 1;
464 static unsigned int type_var_id_num
;
465 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
466 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
468 TREE_STATIC (decl
) = 1;
469 TREE_PUBLIC (decl
) = 0;
470 DECL_ARTIFICIAL (decl
) = 1;
471 DECL_IGNORED_P (decl
) = 1;
472 DECL_EXTERNAL (decl
) = 0;
474 = size_binop (PLUS_EXPR
, DECL_SIZE (decl
), TYPE_SIZE (TREE_TYPE (str
)));
475 DECL_SIZE_UNIT (decl
)
476 = size_binop (PLUS_EXPR
, DECL_SIZE_UNIT (decl
),
477 TYPE_SIZE_UNIT (TREE_TYPE (str
)));
479 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
480 build_int_cst (short_unsigned_type_node
,
482 build_int_cst (short_unsigned_type_node
,
483 tinfo
), NULL_TREE
, str
);
484 TREE_CONSTANT (ctor
) = 1;
485 TREE_STATIC (ctor
) = 1;
486 DECL_INITIAL (decl
) = ctor
;
487 varpool_node::finalize_decl (decl
);
489 /* Save the VAR_DECL into the hash table. */
490 decl_for_type_insert (type
, decl
);
492 return build_fold_addr_expr (decl
);
495 /* Create a structure for the ubsan library. NAME is a name of the new
496 structure. LOCCNT is number of locations, PLOC points to array of
497 locations. The arguments in ... are of __ubsan_type_descriptor type
498 and there are at most two of them, followed by NULL_TREE, followed
499 by optional extra arguments and another NULL_TREE. */
502 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
507 vec
<tree
, va_gc
> *saved_args
= NULL
;
511 /* Firstly, create a pointer to type descriptor type. */
512 tree td_type
= ubsan_get_type_descriptor_type ();
513 td_type
= build_pointer_type (td_type
);
515 /* Create the structure type. */
516 ret
= make_node (RECORD_TYPE
);
517 for (j
= 0; j
< loccnt
; j
++)
519 gcc_checking_assert (i
< 2);
520 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
521 ubsan_get_source_location_type ());
522 DECL_CONTEXT (fields
[i
]) = ret
;
524 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
528 va_start (args
, ploc
);
529 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
530 i
++, t
= va_arg (args
, tree
))
532 gcc_checking_assert (i
< 4);
533 /* Save the tree arguments for later use. */
534 vec_safe_push (saved_args
, t
);
535 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
537 DECL_CONTEXT (fields
[i
]) = ret
;
539 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
542 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
543 i
++, t
= va_arg (args
, tree
))
545 gcc_checking_assert (i
< 6);
546 /* Save the tree arguments for later use. */
547 vec_safe_push (saved_args
, t
);
548 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
550 DECL_CONTEXT (fields
[i
]) = ret
;
552 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
556 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
557 get_identifier (name
), ret
);
558 DECL_IGNORED_P (type_decl
) = 1;
559 DECL_ARTIFICIAL (type_decl
) = 1;
560 TYPE_FIELDS (ret
) = fields
[0];
561 TYPE_NAME (ret
) = type_decl
;
562 TYPE_STUB_DECL (ret
) = type_decl
;
565 /* Now, fill in the type. */
567 static unsigned int ubsan_var_id_num
;
568 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
569 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
571 TREE_STATIC (var
) = 1;
572 TREE_PUBLIC (var
) = 0;
573 DECL_ARTIFICIAL (var
) = 1;
574 DECL_IGNORED_P (var
) = 1;
575 DECL_EXTERNAL (var
) = 0;
577 vec
<constructor_elt
, va_gc
> *v
;
579 tree ctor
= build_constructor (ret
, v
);
581 /* If desirable, set the __ubsan_source_location element. */
582 for (j
= 0; j
< loccnt
; j
++)
584 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
585 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
588 size_t nelts
= vec_safe_length (saved_args
);
589 for (i
= 0; i
< nelts
; i
++)
591 t
= (*saved_args
)[i
];
592 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
595 TREE_CONSTANT (ctor
) = 1;
596 TREE_STATIC (ctor
) = 1;
597 DECL_INITIAL (var
) = ctor
;
598 varpool_node::finalize_decl (var
);
603 /* Instrument the __builtin_unreachable call. We just call the libubsan
607 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
610 location_t loc
= gimple_location (gsi_stmt (*gsi
));
612 if (flag_sanitize_undefined_trap_on_error
)
613 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
616 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
617 NULL_TREE
, NULL_TREE
);
618 data
= build_fold_addr_expr_loc (loc
, data
);
620 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
621 g
= gimple_build_call (fn
, 1, data
);
623 gimple_set_location (g
, loc
);
624 gsi_replace (gsi
, g
, false);
628 /* Return true if T is a call to a libubsan routine. */
631 is_ubsan_builtin_p (tree t
)
633 return TREE_CODE (t
) == FUNCTION_DECL
634 && DECL_BUILT_IN_CLASS (t
) == BUILT_IN_NORMAL
635 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
636 "__builtin___ubsan_", 18) == 0;
639 /* Create a callgraph edge for statement STMT. */
642 ubsan_create_edge (gimple
*stmt
)
644 gcall
*call_stmt
= dyn_cast
<gcall
*> (stmt
);
645 basic_block bb
= gimple_bb (stmt
);
646 int freq
= compute_call_stmt_bb_frequency (current_function_decl
, bb
);
647 cgraph_node
*node
= cgraph_node::get (current_function_decl
);
648 tree decl
= gimple_call_fndecl (call_stmt
);
650 node
->create_edge (cgraph_node::get_create (decl
), call_stmt
, bb
->count
,
654 /* Expand the UBSAN_BOUNDS special builtin function. */
657 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
659 gimple
*stmt
= gsi_stmt (*gsi
);
660 location_t loc
= gimple_location (stmt
);
661 gcc_assert (gimple_call_num_args (stmt
) == 3);
663 /* Pick up the arguments of the UBSAN_BOUNDS call. */
664 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
665 tree index
= gimple_call_arg (stmt
, 1);
666 tree orig_index_type
= TREE_TYPE (index
);
667 tree bound
= gimple_call_arg (stmt
, 2);
669 gimple_stmt_iterator gsi_orig
= *gsi
;
671 /* Create condition "if (index > bound)". */
672 basic_block then_bb
, fallthru_bb
;
673 gimple_stmt_iterator cond_insert_point
674 = create_cond_insert_point (gsi
, false, false, true,
675 &then_bb
, &fallthru_bb
);
676 index
= fold_convert (TREE_TYPE (bound
), index
);
677 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
679 false, GSI_NEW_STMT
);
680 gimple
*g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
681 gimple_set_location (g
, loc
);
682 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
684 /* Generate __ubsan_handle_out_of_bounds call. */
685 *gsi
= gsi_after_labels (then_bb
);
686 if (flag_sanitize_undefined_trap_on_error
)
687 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
691 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
692 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
693 ubsan_type_descriptor (orig_index_type
),
694 NULL_TREE
, NULL_TREE
);
695 data
= build_fold_addr_expr_loc (loc
, data
);
696 enum built_in_function bcode
697 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
698 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
699 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
700 tree fn
= builtin_decl_explicit (bcode
);
701 tree val
= force_gimple_operand_gsi (gsi
, ubsan_encode_value (index
),
702 true, NULL_TREE
, true,
704 g
= gimple_build_call (fn
, 2, data
, val
);
706 gimple_set_location (g
, loc
);
707 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
709 /* Get rid of the UBSAN_BOUNDS call from the IR. */
710 unlink_stmt_vdef (stmt
);
711 gsi_remove (&gsi_orig
, true);
713 /* Point GSI to next logical statement. */
714 *gsi
= gsi_start_bb (fallthru_bb
);
718 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
719 argument which is a constant, because the middle-end treats pointer
720 conversions as useless and therefore the type of the first argument
721 could be changed to any other pointer type. */
724 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
726 gimple_stmt_iterator gsi
= *gsip
;
727 gimple
*stmt
= gsi_stmt (gsi
);
728 location_t loc
= gimple_location (stmt
);
729 gcc_assert (gimple_call_num_args (stmt
) == 3);
730 tree ptr
= gimple_call_arg (stmt
, 0);
731 tree ckind
= gimple_call_arg (stmt
, 1);
732 tree align
= gimple_call_arg (stmt
, 2);
733 tree check_align
= NULL_TREE
;
736 basic_block cur_bb
= gsi_bb (gsi
);
739 if (!integer_zerop (align
))
741 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
742 if (compare_tree_int (align
, ptralign
) == 1)
744 check_align
= make_ssa_name (pointer_sized_int_node
);
745 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
746 gimple_set_location (g
, loc
);
747 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
750 check_null
= (flag_sanitize
& SANITIZE_NULL
) != 0;
752 if (check_align
== NULL_TREE
&& !check_null
)
754 gsi_remove (gsip
, true);
755 /* Unlink the UBSAN_NULLs vops before replacing it. */
756 unlink_stmt_vdef (stmt
);
760 /* Split the original block holding the pointer dereference. */
761 edge e
= split_block (cur_bb
, stmt
);
763 /* Get a hold on the 'condition block', the 'then block' and the
765 basic_block cond_bb
= e
->src
;
766 basic_block fallthru_bb
= e
->dest
;
767 basic_block then_bb
= create_empty_bb (cond_bb
);
768 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
769 loops_state_set (LOOPS_NEED_FIXUP
);
771 /* Make an edge coming from the 'cond block' into the 'then block';
772 this edge is unlikely taken, so set up the probability accordingly. */
773 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
774 e
->probability
= PROB_VERY_UNLIKELY
;
776 /* Connect 'then block' with the 'else block'. This is needed
777 as the ubsan routines we call in the 'then block' are not noreturn.
778 The 'then block' only has one outcoming edge. */
779 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
781 /* Set up the fallthrough basic block. */
782 e
= find_edge (cond_bb
, fallthru_bb
);
783 e
->flags
= EDGE_FALSE_VALUE
;
784 e
->count
= cond_bb
->count
;
785 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
787 /* Update dominance info for the newly created then_bb; note that
788 fallthru_bb's dominance info has already been updated by
790 if (dom_info_available_p (CDI_DOMINATORS
))
791 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
793 /* Put the ubsan builtin call into the newly created BB. */
794 if (flag_sanitize_undefined_trap_on_error
)
795 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
798 enum built_in_function bcode
799 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
800 | (check_null
? SANITIZE_NULL
: 0)))
801 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
802 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
803 tree fn
= builtin_decl_implicit (bcode
);
805 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
806 ubsan_type_descriptor (TREE_TYPE (ckind
),
807 UBSAN_PRINT_POINTER
),
810 fold_convert (unsigned_char_type_node
, ckind
),
812 data
= build_fold_addr_expr_loc (loc
, data
);
813 g
= gimple_build_call (fn
, 2, data
,
814 check_align
? check_align
815 : build_zero_cst (pointer_sized_int_node
));
817 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
818 gimple_set_location (g
, loc
);
819 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
821 /* Unlink the UBSAN_NULLs vops before replacing it. */
822 unlink_stmt_vdef (stmt
);
826 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
827 NULL_TREE
, NULL_TREE
);
828 gimple_set_location (g
, loc
);
830 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
831 gsi_replace (&gsi
, g
, false);
839 /* Split the block with the condition again. */
840 e
= split_block (cond_bb
, stmt
);
841 basic_block cond1_bb
= e
->src
;
842 basic_block cond2_bb
= e
->dest
;
844 /* Make an edge coming from the 'cond1 block' into the 'then block';
845 this edge is unlikely taken, so set up the probability
847 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
848 e
->probability
= PROB_VERY_UNLIKELY
;
850 /* Set up the fallthrough basic block. */
851 e
= find_edge (cond1_bb
, cond2_bb
);
852 e
->flags
= EDGE_FALSE_VALUE
;
853 e
->count
= cond1_bb
->count
;
854 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
856 /* Update dominance info. */
857 if (dom_info_available_p (CDI_DOMINATORS
))
859 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
860 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
863 gsi2
= gsi_start_bb (cond2_bb
);
866 tree mask
= build_int_cst (pointer_sized_int_node
,
867 tree_to_uhwi (align
) - 1);
868 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
869 BIT_AND_EXPR
, check_align
, mask
);
870 gimple_set_location (g
, loc
);
872 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
874 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
876 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
877 build_int_cst (pointer_sized_int_node
, 0),
878 NULL_TREE
, NULL_TREE
);
879 gimple_set_location (g
, loc
);
881 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
883 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
884 gsi_replace (&gsi
, g
, false);
889 #define OBJSZ_MAX_OFFSET (1024 * 16)
891 /* Expand UBSAN_OBJECT_SIZE internal call. */
894 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
896 gimple
*stmt
= gsi_stmt (*gsi
);
897 location_t loc
= gimple_location (stmt
);
898 gcc_assert (gimple_call_num_args (stmt
) == 4);
900 tree ptr
= gimple_call_arg (stmt
, 0);
901 tree offset
= gimple_call_arg (stmt
, 1);
902 tree size
= gimple_call_arg (stmt
, 2);
903 tree ckind
= gimple_call_arg (stmt
, 3);
904 gimple_stmt_iterator gsi_orig
= *gsi
;
907 /* See if we can discard the check. */
908 if (TREE_CODE (size
) != INTEGER_CST
909 || integer_all_onesp (size
))
910 /* Yes, __builtin_object_size couldn't determine the
912 else if (TREE_CODE (offset
) == INTEGER_CST
913 && wi::to_widest (offset
) >= -OBJSZ_MAX_OFFSET
914 && wi::to_widest (offset
) <= -1)
915 /* The offset is in range [-16K, -1]. */;
918 /* if (offset > objsize) */
919 basic_block then_bb
, fallthru_bb
;
920 gimple_stmt_iterator cond_insert_point
921 = create_cond_insert_point (gsi
, false, false, true,
922 &then_bb
, &fallthru_bb
);
923 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
924 gimple_set_location (g
, loc
);
925 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
927 /* If the offset is small enough, we don't need the second
929 if (TREE_CODE (offset
) == INTEGER_CST
930 && wi::to_widest (offset
) >= 0
931 && wi::to_widest (offset
) <= OBJSZ_MAX_OFFSET
)
932 *gsi
= gsi_after_labels (then_bb
);
935 /* Don't issue run-time error if (ptr > ptr + offset). That
936 may happen when computing a POINTER_PLUS_EXPR. */
937 basic_block then2_bb
, fallthru2_bb
;
939 gimple_stmt_iterator gsi2
= gsi_after_labels (then_bb
);
940 cond_insert_point
= create_cond_insert_point (&gsi2
, false, false,
943 /* Convert the pointer to an integer type. */
944 tree p
= make_ssa_name (pointer_sized_int_node
);
945 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
946 gimple_set_location (g
, loc
);
947 gsi_insert_before (&cond_insert_point
, g
, GSI_NEW_STMT
);
948 p
= gimple_assign_lhs (g
);
949 /* Compute ptr + offset. */
950 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
951 PLUS_EXPR
, p
, offset
);
952 gimple_set_location (g
, loc
);
953 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
954 /* Now build the conditional and put it into the IR. */
955 g
= gimple_build_cond (LE_EXPR
, p
, gimple_assign_lhs (g
),
956 NULL_TREE
, NULL_TREE
);
957 gimple_set_location (g
, loc
);
958 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
959 *gsi
= gsi_after_labels (then2_bb
);
962 /* Generate __ubsan_handle_type_mismatch call. */
963 if (flag_sanitize_undefined_trap_on_error
)
964 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
968 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
969 ubsan_type_descriptor (TREE_TYPE (ptr
),
970 UBSAN_PRINT_POINTER
),
972 build_zero_cst (pointer_sized_int_node
),
975 data
= build_fold_addr_expr_loc (loc
, data
);
976 enum built_in_function bcode
977 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
978 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
979 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
980 tree p
= make_ssa_name (pointer_sized_int_node
);
981 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
982 gimple_set_location (g
, loc
);
983 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
984 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
986 gimple_set_location (g
, loc
);
987 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
989 /* Point GSI to next logical statement. */
990 *gsi
= gsi_start_bb (fallthru_bb
);
992 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
993 unlink_stmt_vdef (stmt
);
994 gsi_remove (&gsi_orig
, true);
998 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
999 unlink_stmt_vdef (stmt
);
1000 gsi_remove (gsi
, true);
1004 /* Cached __ubsan_vptr_type_cache decl. */
1005 static GTY(()) tree ubsan_vptr_type_cache_decl
;
1007 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1008 argument which is a constant, because the middle-end treats pointer
1009 conversions as useless and therefore the type of the first argument
1010 could be changed to any other pointer type. */
1013 ubsan_expand_vptr_ifn (gimple_stmt_iterator
*gsip
)
1015 gimple_stmt_iterator gsi
= *gsip
;
1016 gimple
*stmt
= gsi_stmt (gsi
);
1017 location_t loc
= gimple_location (stmt
);
1018 gcc_assert (gimple_call_num_args (stmt
) == 5);
1019 tree op
= gimple_call_arg (stmt
, 0);
1020 tree vptr
= gimple_call_arg (stmt
, 1);
1021 tree str_hash
= gimple_call_arg (stmt
, 2);
1022 tree ti_decl_addr
= gimple_call_arg (stmt
, 3);
1023 tree ckind_tree
= gimple_call_arg (stmt
, 4);
1024 ubsan_null_ckind ckind
= (ubsan_null_ckind
) tree_to_uhwi (ckind_tree
);
1025 tree type
= TREE_TYPE (TREE_TYPE (ckind_tree
));
1027 basic_block fallthru_bb
= NULL
;
1029 if (ckind
== UBSAN_DOWNCAST_POINTER
)
1031 /* Guard everything with if (op != NULL) { ... }. */
1032 basic_block then_bb
;
1033 gimple_stmt_iterator cond_insert_point
1034 = create_cond_insert_point (gsip
, false, false, true,
1035 &then_bb
, &fallthru_bb
);
1036 g
= gimple_build_cond (NE_EXPR
, op
, build_zero_cst (TREE_TYPE (op
)),
1037 NULL_TREE
, NULL_TREE
);
1038 gimple_set_location (g
, loc
);
1039 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1040 *gsip
= gsi_after_labels (then_bb
);
1041 gsi_remove (&gsi
, false);
1042 gsi_insert_before (gsip
, stmt
, GSI_NEW_STMT
);
1046 tree htype
= TREE_TYPE (str_hash
);
1047 tree cst
= wide_int_to_tree (htype
,
1048 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1050 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1052 gimple_set_location (g
, loc
);
1053 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1054 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1055 gimple_assign_lhs (g
), cst
);
1056 gimple_set_location (g
, loc
);
1057 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1058 tree t1
= gimple_assign_lhs (g
);
1059 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1060 t1
, build_int_cst (integer_type_node
, 47));
1061 gimple_set_location (g
, loc
);
1062 tree t2
= gimple_assign_lhs (g
);
1063 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1064 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1066 gimple_set_location (g
, loc
);
1067 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1068 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1069 t2
, gimple_assign_lhs (g
));
1070 gimple_set_location (g
, loc
);
1071 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1072 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1073 gimple_assign_lhs (g
), cst
);
1074 gimple_set_location (g
, loc
);
1075 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1076 tree t3
= gimple_assign_lhs (g
);
1077 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1078 t3
, build_int_cst (integer_type_node
, 47));
1079 gimple_set_location (g
, loc
);
1080 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1081 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1082 t3
, gimple_assign_lhs (g
));
1083 gimple_set_location (g
, loc
);
1084 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1085 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1086 gimple_assign_lhs (g
), cst
);
1087 gimple_set_location (g
, loc
);
1088 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1089 if (!useless_type_conversion_p (pointer_sized_int_node
, htype
))
1091 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1092 NOP_EXPR
, gimple_assign_lhs (g
));
1093 gimple_set_location (g
, loc
);
1094 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1096 tree hash
= gimple_assign_lhs (g
);
1098 if (ubsan_vptr_type_cache_decl
== NULL_TREE
)
1100 tree atype
= build_array_type_nelts (pointer_sized_int_node
, 128);
1101 tree array
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1102 get_identifier ("__ubsan_vptr_type_cache"),
1104 DECL_ARTIFICIAL (array
) = 1;
1105 DECL_IGNORED_P (array
) = 1;
1106 TREE_PUBLIC (array
) = 1;
1107 TREE_STATIC (array
) = 1;
1108 DECL_EXTERNAL (array
) = 1;
1109 DECL_VISIBILITY (array
) = VISIBILITY_DEFAULT
;
1110 DECL_VISIBILITY_SPECIFIED (array
) = 1;
1111 varpool_node::finalize_decl (array
);
1112 ubsan_vptr_type_cache_decl
= array
;
1115 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1117 build_int_cst (pointer_sized_int_node
, 127));
1118 gimple_set_location (g
, loc
);
1119 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1121 tree c
= build4_loc (loc
, ARRAY_REF
, pointer_sized_int_node
,
1122 ubsan_vptr_type_cache_decl
, gimple_assign_lhs (g
),
1123 NULL_TREE
, NULL_TREE
);
1124 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1126 gimple_set_location (g
, loc
);
1127 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1129 basic_block then_bb
, fallthru2_bb
;
1130 gimple_stmt_iterator cond_insert_point
1131 = create_cond_insert_point (gsip
, false, false, true,
1132 &then_bb
, &fallthru2_bb
);
1133 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
), hash
,
1134 NULL_TREE
, NULL_TREE
);
1135 gimple_set_location (g
, loc
);
1136 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1137 *gsip
= gsi_after_labels (then_bb
);
1138 if (fallthru_bb
== NULL
)
1139 fallthru_bb
= fallthru2_bb
;
1142 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc
,
1143 ubsan_type_descriptor (type
), NULL_TREE
, ti_decl_addr
,
1144 build_int_cst (unsigned_char_type_node
, ckind
),
1146 data
= build_fold_addr_expr_loc (loc
, data
);
1147 enum built_in_function bcode
1148 = (flag_sanitize_recover
& SANITIZE_VPTR
)
1149 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1150 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT
;
1152 g
= gimple_build_call (builtin_decl_explicit (bcode
), 3, data
, op
, hash
);
1153 gimple_set_location (g
, loc
);
1154 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1156 /* Point GSI to next logical statement. */
1157 *gsip
= gsi_start_bb (fallthru_bb
);
1159 /* Get rid of the UBSAN_VPTR call from the IR. */
1160 unlink_stmt_vdef (stmt
);
1161 gsi_remove (&gsi
, true);
1165 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1166 whether the pointer is on the left hand side of the assignment. */
1169 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
1172 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
1173 unsigned int align
= 0;
1174 if (flag_sanitize
& SANITIZE_ALIGNMENT
)
1176 align
= min_align_of_type (TREE_TYPE (base
));
1180 if (align
== 0 && (flag_sanitize
& SANITIZE_NULL
) == 0)
1182 tree t
= TREE_OPERAND (base
, 0);
1183 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
1185 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base
)) && mem
!= base
)
1186 ikind
= UBSAN_MEMBER_ACCESS
;
1187 tree kind
= build_int_cst (build_pointer_type (TREE_TYPE (base
)), ikind
);
1188 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
1189 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
1190 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
1191 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
1194 /* Perform the pointer instrumentation. */
1197 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
1199 gimple
*stmt
= gsi_stmt (gsi
);
1200 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1201 tree base
= get_base_address (t
);
1202 const enum tree_code code
= TREE_CODE (base
);
1204 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1205 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1208 /* Build an ubsan builtin call for the signed-integer-overflow
1209 sanitization. CODE says what kind of builtin are we building,
1210 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1211 are operands of the binary operation. */
1214 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1217 if (flag_sanitize_undefined_trap_on_error
)
1218 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1220 tree data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1221 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1223 enum built_in_function fn_code
;
1228 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1229 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1230 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1233 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1234 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1235 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1238 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1239 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1240 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1243 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1244 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1245 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1250 tree fn
= builtin_decl_explicit (fn_code
);
1251 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1252 build_fold_addr_expr_loc (loc
, data
),
1253 ubsan_encode_value (op0
, true),
1254 op1
? ubsan_encode_value (op1
, true)
1258 /* Perform the signed integer instrumentation. GSI is the iterator
1259 pointing at statement we are trying to instrument. */
1262 instrument_si_overflow (gimple_stmt_iterator gsi
)
1264 gimple
*stmt
= gsi_stmt (gsi
);
1265 tree_code code
= gimple_assign_rhs_code (stmt
);
1266 tree lhs
= gimple_assign_lhs (stmt
);
1267 tree lhstype
= TREE_TYPE (lhs
);
1271 /* If this is not a signed operation, don't instrument anything here.
1272 Also punt on bit-fields. */
1273 if (!INTEGRAL_TYPE_P (lhstype
)
1274 || TYPE_OVERFLOW_WRAPS (lhstype
)
1275 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
1286 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1287 a
= gimple_assign_rhs1 (stmt
);
1288 b
= gimple_assign_rhs2 (stmt
);
1289 g
= gimple_build_call_internal (code
== PLUS_EXPR
1290 ? IFN_UBSAN_CHECK_ADD
1291 : code
== MINUS_EXPR
1292 ? IFN_UBSAN_CHECK_SUB
1293 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1294 gimple_call_set_lhs (g
, lhs
);
1295 gsi_replace (&gsi
, g
, false);
1298 /* Represent i = -u;
1300 i = UBSAN_CHECK_SUB (0, u); */
1301 a
= build_int_cst (lhstype
, 0);
1302 b
= gimple_assign_rhs1 (stmt
);
1303 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1304 gimple_call_set_lhs (g
, lhs
);
1305 gsi_replace (&gsi
, g
, false);
1308 /* Transform i = ABS_EXPR<u>;
1310 _N = UBSAN_CHECK_SUB (0, u);
1311 i = ABS_EXPR<_N>; */
1312 a
= build_int_cst (lhstype
, 0);
1313 b
= gimple_assign_rhs1 (stmt
);
1314 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1315 a
= make_ssa_name (lhstype
);
1316 gimple_call_set_lhs (g
, a
);
1317 gimple_set_location (g
, gimple_location (stmt
));
1318 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1319 gimple_assign_set_rhs1 (stmt
, a
);
1327 /* Instrument loads from (non-bitfield) bool and C++ enum values
1328 to check if the memory value is outside of the range of the valid
1332 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1334 gimple
*stmt
= gsi_stmt (*gsi
);
1335 tree rhs
= gimple_assign_rhs1 (stmt
);
1336 tree type
= TREE_TYPE (rhs
);
1337 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1339 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
1341 minv
= boolean_false_node
;
1342 maxv
= boolean_true_node
;
1344 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1345 && (flag_sanitize
& SANITIZE_ENUM
)
1346 && TREE_TYPE (type
) != NULL_TREE
1347 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1348 && (TYPE_PRECISION (TREE_TYPE (type
))
1349 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1351 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1352 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1357 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1358 HOST_WIDE_INT bitsize
, bitpos
;
1361 int volatilep
= 0, reversep
, unsignedp
= 0;
1362 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1363 &unsignedp
, &reversep
, &volatilep
, false);
1364 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1366 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
1367 || (bitpos
% modebitsize
) != 0
1368 || bitsize
!= modebitsize
1369 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1370 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1373 bool ends_bb
= stmt_ends_bb_p (stmt
);
1374 location_t loc
= gimple_location (stmt
);
1375 tree lhs
= gimple_assign_lhs (stmt
);
1376 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1377 tree atype
= reference_alias_ptr_type (rhs
);
1378 gimple
*g
= gimple_build_assign (make_ssa_name (ptype
),
1379 build_fold_addr_expr (rhs
));
1380 gimple_set_location (g
, loc
);
1381 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1382 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1383 build_int_cst (atype
, 0));
1384 tree urhs
= make_ssa_name (utype
);
1387 gimple_assign_set_lhs (stmt
, urhs
);
1388 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1389 gimple_set_location (g
, loc
);
1390 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1391 gsi_insert_on_edge_immediate (e
, g
);
1392 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1394 *gsi
= gsi_for_stmt (g
);
1399 g
= gimple_build_assign (urhs
, mem
);
1400 gimple_set_location (g
, loc
);
1401 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1403 minv
= fold_convert (utype
, minv
);
1404 maxv
= fold_convert (utype
, maxv
);
1405 if (!integer_zerop (minv
))
1407 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1408 gimple_set_location (g
, loc
);
1409 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1412 gimple_stmt_iterator gsi2
= *gsi
;
1413 basic_block then_bb
, fallthru_bb
;
1414 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1415 &then_bb
, &fallthru_bb
);
1416 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1417 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1418 NULL_TREE
, NULL_TREE
);
1419 gimple_set_location (g
, loc
);
1420 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1424 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1428 gsi2
= gsi_after_labels (then_bb
);
1429 if (flag_sanitize_undefined_trap_on_error
)
1430 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1433 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1434 ubsan_type_descriptor (type
), NULL_TREE
,
1436 data
= build_fold_addr_expr_loc (loc
, data
);
1437 enum built_in_function bcode
1438 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1439 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1440 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1441 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1442 tree fn
= builtin_decl_explicit (bcode
);
1444 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
1445 true, NULL_TREE
, true,
1447 g
= gimple_build_call (fn
, 2, data
, val
);
1449 gimple_set_location (g
, loc
);
1450 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1451 ubsan_create_edge (g
);
1452 *gsi
= gsi_for_stmt (stmt
);
1455 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1456 new style handlers. Libubsan uses heuristics to destinguish between old and
1457 new styles and relies on these properties for filename:
1459 a) Location's filename must not be NULL.
1460 b) Location's filename must not be equal to "".
1461 c) Location's filename must not be equal to "\1".
1462 d) First two bytes of filename must not contain '\xff' symbol. */
1465 ubsan_use_new_style_p (location_t loc
)
1467 if (loc
== UNKNOWN_LOCATION
)
1470 expanded_location xloc
= expand_location (loc
);
1471 if (xloc
.file
== NULL
|| strncmp (xloc
.file
, "\1", 2) == 0
1472 || xloc
.file
== '\0' || xloc
.file
[0] == '\xff'
1473 || xloc
.file
[1] == '\xff')
1479 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1480 destination, EXPR is floating-point expression. */
1483 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
)
1485 tree expr_type
= TREE_TYPE (expr
);
1486 tree t
, tt
, fn
, min
, max
;
1487 machine_mode mode
= TYPE_MODE (expr_type
);
1488 int prec
= TYPE_PRECISION (type
);
1489 bool uns_p
= TYPE_UNSIGNED (type
);
1490 if (loc
== UNKNOWN_LOCATION
)
1491 loc
= input_location
;
1493 /* Float to integer conversion first truncates toward zero, so
1494 even signed char c = 127.875f; is not problematic.
1495 Therefore, we should complain only if EXPR is unordered or smaller
1496 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1497 TYPE_MAX_VALUE + 1.0. */
1498 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1500 /* For maximum, TYPE_MAX_VALUE might not be representable
1501 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1502 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1503 either representable or infinity. */
1504 REAL_VALUE_TYPE maxval
= dconst1
;
1505 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1506 real_convert (&maxval
, mode
, &maxval
);
1507 max
= build_real (expr_type
, maxval
);
1509 /* For unsigned, assume -1.0 is always representable. */
1511 min
= build_minus_one_cst (expr_type
);
1514 /* TYPE_MIN_VALUE is generally representable (or -inf),
1515 but TYPE_MIN_VALUE - 1.0 might not be. */
1516 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1517 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1518 real_convert (&minval
, mode
, &minval
);
1519 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1520 real_convert (&minval2
, mode
, &minval2
);
1521 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1522 && !real_isinf (&minval
))
1524 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1525 rounds to TYPE_MIN_VALUE, we need to subtract
1526 more. As REAL_MODE_FORMAT (mode)->p is the number
1527 of base digits, we want to subtract a number that
1528 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1529 times smaller than minval. */
1531 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1532 SET_REAL_EXP (&minval2
,
1533 REAL_EXP (&minval2
) + prec
- 1
1534 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1535 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1536 real_convert (&minval2
, mode
, &minval2
);
1538 min
= build_real (expr_type
, minval2
);
1541 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1543 /* For _Decimal128 up to 34 decimal digits, - sign,
1544 dot, e, exponent. */
1547 int p
= REAL_MODE_FORMAT (mode
)->p
;
1548 REAL_VALUE_TYPE maxval
, minval
;
1550 /* Use mpfr_snprintf rounding to compute the smallest
1551 representable decimal number greater or equal than
1552 1 << (prec - !uns_p). */
1553 mpfr_init2 (m
, prec
+ 2);
1554 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1555 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1556 decimal_real_from_string (&maxval
, buf
);
1557 max
= build_real (expr_type
, maxval
);
1559 /* For unsigned, assume -1.0 is always representable. */
1561 min
= build_minus_one_cst (expr_type
);
1564 /* Use mpfr_snprintf rounding to compute the largest
1565 representable decimal number less or equal than
1566 (-1 << (prec - 1)) - 1. */
1567 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1568 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1569 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1570 decimal_real_from_string (&minval
, buf
);
1571 min
= build_real (expr_type
, minval
);
1578 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1579 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1580 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
);
1581 if (integer_zerop (t
))
1584 if (flag_sanitize_undefined_trap_on_error
)
1585 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1588 location_t
*loc_ptr
= NULL
;
1589 unsigned num_locations
= 0;
1590 initialize_sanitizer_builtins ();
1591 /* Figure out if we can propagate location to ubsan_data and use new
1592 style handlers in libubsan. */
1593 if (ubsan_use_new_style_p (loc
))
1598 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1599 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data",
1600 num_locations
, loc_ptr
,
1601 ubsan_type_descriptor (expr_type
),
1602 ubsan_type_descriptor (type
), NULL_TREE
,
1604 enum built_in_function bcode
1605 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1606 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1607 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1608 fn
= builtin_decl_explicit (bcode
);
1609 fn
= build_call_expr_loc (loc
, fn
, 2,
1610 build_fold_addr_expr_loc (loc
, data
),
1611 ubsan_encode_value (expr
, false));
1614 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1617 /* Instrument values passed to function arguments with nonnull attribute. */
1620 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1622 gimple
*stmt
= gsi_stmt (*gsi
);
1624 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1625 while for nonnull sanitization it is clear. */
1626 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1627 flag_delete_null_pointer_checks
= 1;
1628 loc
[0] = gimple_location (stmt
);
1629 loc
[1] = UNKNOWN_LOCATION
;
1630 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1632 tree arg
= gimple_call_arg (stmt
, i
);
1633 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1634 && infer_nonnull_range_by_attribute (stmt
, arg
))
1637 if (!is_gimple_val (arg
))
1639 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1640 gimple_set_location (g
, loc
[0]);
1641 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1642 arg
= gimple_assign_lhs (g
);
1645 basic_block then_bb
, fallthru_bb
;
1646 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1647 &then_bb
, &fallthru_bb
);
1648 g
= gimple_build_cond (EQ_EXPR
, arg
,
1649 build_zero_cst (TREE_TYPE (arg
)),
1650 NULL_TREE
, NULL_TREE
);
1651 gimple_set_location (g
, loc
[0]);
1652 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1654 *gsi
= gsi_after_labels (then_bb
);
1655 if (flag_sanitize_undefined_trap_on_error
)
1656 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1659 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1661 build_int_cst (integer_type_node
,
1664 data
= build_fold_addr_expr_loc (loc
[0], data
);
1665 enum built_in_function bcode
1666 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1667 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1668 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1669 tree fn
= builtin_decl_explicit (bcode
);
1671 g
= gimple_build_call (fn
, 1, data
);
1673 gimple_set_location (g
, loc
[0]);
1674 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1675 ubsan_create_edge (g
);
1677 *gsi
= gsi_for_stmt (stmt
);
1679 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1682 /* Instrument returns in functions with returns_nonnull attribute. */
1685 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1687 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
1689 tree arg
= gimple_return_retval (stmt
);
1690 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1691 while for nonnull return sanitization it is clear. */
1692 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1693 flag_delete_null_pointer_checks
= 1;
1694 loc
[0] = gimple_location (stmt
);
1695 loc
[1] = UNKNOWN_LOCATION
;
1697 && POINTER_TYPE_P (TREE_TYPE (arg
))
1698 && is_gimple_val (arg
)
1699 && infer_nonnull_range_by_attribute (stmt
, arg
))
1701 basic_block then_bb
, fallthru_bb
;
1702 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1703 &then_bb
, &fallthru_bb
);
1704 gimple
*g
= gimple_build_cond (EQ_EXPR
, arg
,
1705 build_zero_cst (TREE_TYPE (arg
)),
1706 NULL_TREE
, NULL_TREE
);
1707 gimple_set_location (g
, loc
[0]);
1708 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1710 *gsi
= gsi_after_labels (then_bb
);
1711 if (flag_sanitize_undefined_trap_on_error
)
1712 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1715 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
1716 2, loc
, NULL_TREE
, NULL_TREE
);
1717 data
= build_fold_addr_expr_loc (loc
[0], data
);
1718 enum built_in_function bcode
1719 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1720 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1721 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
1722 tree fn
= builtin_decl_explicit (bcode
);
1724 g
= gimple_build_call (fn
, 1, data
);
1726 gimple_set_location (g
, loc
[0]);
1727 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1728 ubsan_create_edge (g
);
1729 *gsi
= gsi_for_stmt (stmt
);
1731 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1734 /* Instrument memory references. Here we check whether the pointer
1735 points to an out-of-bounds location. */
1738 instrument_object_size (gimple_stmt_iterator
*gsi
, bool is_lhs
)
1740 gimple
*stmt
= gsi_stmt (*gsi
);
1741 location_t loc
= gimple_location (stmt
);
1742 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1744 tree index
= NULL_TREE
;
1745 HOST_WIDE_INT size_in_bytes
;
1747 type
= TREE_TYPE (t
);
1748 if (VOID_TYPE_P (type
))
1751 switch (TREE_CODE (t
))
1754 if (TREE_CODE (t
) == COMPONENT_REF
1755 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
1757 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
1758 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
1763 index
= TREE_OPERAND (t
, 1);
1775 size_in_bytes
= int_size_in_bytes (type
);
1776 if (size_in_bytes
<= 0)
1779 HOST_WIDE_INT bitsize
, bitpos
;
1782 int volatilep
= 0, reversep
, unsignedp
= 0;
1783 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1784 &unsignedp
, &reversep
, &volatilep
, false);
1786 if (bitpos
% BITS_PER_UNIT
!= 0
1787 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
1790 bool decl_p
= DECL_P (inner
);
1794 else if (TREE_CODE (inner
) == MEM_REF
)
1795 base
= TREE_OPERAND (inner
, 0);
1798 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
1800 while (TREE_CODE (base
) == SSA_NAME
)
1802 gimple
*def_stmt
= SSA_NAME_DEF_STMT (base
);
1803 if (gimple_assign_ssa_name_copy_p (def_stmt
)
1804 || (gimple_assign_cast_p (def_stmt
)
1805 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
1806 || (is_gimple_assign (def_stmt
)
1807 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
1809 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
1810 if (TREE_CODE (rhs1
) == SSA_NAME
1811 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
1820 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1824 tree base_addr
= base
;
1825 gimple
*bos_stmt
= NULL
;
1827 base_addr
= build1 (ADDR_EXPR
,
1828 build_pointer_type (TREE_TYPE (base
)), base
);
1829 unsigned HOST_WIDE_INT size
= compute_builtin_object_size (base_addr
, 0);
1830 if (size
!= (unsigned HOST_WIDE_INT
) -1)
1831 sizet
= build_int_cst (sizetype
, size
);
1834 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
1835 loc
= input_location
;
1836 /* Generate __builtin_object_size call. */
1837 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
1838 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
1840 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
1842 /* If the call above didn't end up being an integer constant, go one
1843 statement back and get the __builtin_object_size stmt. Save it,
1844 we might need it later. */
1845 if (SSA_VAR_P (sizet
))
1848 bos_stmt
= gsi_stmt (*gsi
);
1850 /* Move on to where we were. */
1857 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1859 /* ptr + sizeof (*ptr) - base */
1860 t
= fold_build2 (MINUS_EXPR
, sizetype
,
1861 fold_convert (pointer_sized_int_node
, ptr
),
1862 fold_convert (pointer_sized_int_node
, base_addr
));
1863 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
1865 /* Perhaps we can omit the check. */
1866 if (TREE_CODE (t
) == INTEGER_CST
1867 && TREE_CODE (sizet
) == INTEGER_CST
1868 && tree_int_cst_le (t
, sizet
))
1871 if (index
!= NULL_TREE
1872 && TREE_CODE (index
) == SSA_NAME
1873 && TREE_CODE (sizet
) == INTEGER_CST
)
1875 gimple
*def
= SSA_NAME_DEF_STMT (index
);
1876 if (is_gimple_assign (def
)
1877 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
1878 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
1880 tree cst
= gimple_assign_rhs2 (def
);
1881 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
1882 TYPE_SIZE_UNIT (type
));
1883 if (tree_int_cst_sgn (cst
) >= 0
1884 && tree_int_cst_lt (cst
, sz
))
1889 if (bos_stmt
&& gimple_call_builtin_p (bos_stmt
, BUILT_IN_OBJECT_SIZE
))
1890 ubsan_create_edge (bos_stmt
);
1892 /* We have to emit the check. */
1893 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1895 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
1897 tree ckind
= build_int_cst (unsigned_char_type_node
,
1898 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
1899 gimple
*g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
1900 ptr
, t
, sizet
, ckind
);
1901 gimple_set_location (g
, loc
);
1902 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1905 /* True if we want to play UBSan games in the current function. */
1908 do_ubsan_in_current_function ()
1910 return (current_function_decl
!= NULL_TREE
1911 && !lookup_attribute ("no_sanitize_undefined",
1912 DECL_ATTRIBUTES (current_function_decl
)));
1917 const pass_data pass_data_ubsan
=
1919 GIMPLE_PASS
, /* type */
1921 OPTGROUP_NONE
, /* optinfo_flags */
1922 TV_TREE_UBSAN
, /* tv_id */
1923 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1924 0, /* properties_provided */
1925 0, /* properties_destroyed */
1926 0, /* todo_flags_start */
1927 TODO_update_ssa
, /* todo_flags_finish */
1930 class pass_ubsan
: public gimple_opt_pass
1933 pass_ubsan (gcc::context
*ctxt
)
1934 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1937 /* opt_pass methods: */
1938 virtual bool gate (function
*)
1940 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1941 | SANITIZE_BOOL
| SANITIZE_ENUM
1942 | SANITIZE_ALIGNMENT
1943 | SANITIZE_NONNULL_ATTRIBUTE
1944 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1945 | SANITIZE_OBJECT_SIZE
)
1946 && do_ubsan_in_current_function ();
1949 virtual unsigned int execute (function
*);
1951 }; // class pass_ubsan
1954 pass_ubsan::execute (function
*fun
)
1957 gimple_stmt_iterator gsi
;
1959 initialize_sanitizer_builtins ();
1961 FOR_EACH_BB_FN (bb
, fun
)
1963 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1965 gimple
*stmt
= gsi_stmt (gsi
);
1966 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
1972 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
1973 && is_gimple_assign (stmt
))
1974 instrument_si_overflow (gsi
);
1976 if (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1978 if (gimple_store_p (stmt
))
1979 instrument_null (gsi
, true);
1980 if (gimple_assign_load_p (stmt
))
1981 instrument_null (gsi
, false);
1984 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
1985 && gimple_assign_load_p (stmt
))
1987 instrument_bool_enum_load (&gsi
);
1988 bb
= gimple_bb (stmt
);
1991 if ((flag_sanitize
& SANITIZE_NONNULL_ATTRIBUTE
)
1992 && is_gimple_call (stmt
)
1993 && !gimple_call_internal_p (stmt
))
1995 instrument_nonnull_arg (&gsi
);
1996 bb
= gimple_bb (stmt
);
1999 if ((flag_sanitize
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
2000 && gimple_code (stmt
) == GIMPLE_RETURN
)
2002 instrument_nonnull_return (&gsi
);
2003 bb
= gimple_bb (stmt
);
2006 if (flag_sanitize
& SANITIZE_OBJECT_SIZE
)
2008 if (gimple_store_p (stmt
))
2009 instrument_object_size (&gsi
, true);
2010 if (gimple_assign_load_p (stmt
))
2011 instrument_object_size (&gsi
, false);
2023 make_pass_ubsan (gcc::context
*ctxt
)
2025 return new pass_ubsan (ctxt
);
2028 #include "gt-ubsan.h"