1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2017 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
26 #include "c-family/c-common.h"
29 #include "tree-pass.h"
34 #include "tree-pretty-print.h"
35 #include "stor-layout.h"
37 #include "gimple-iterator.h"
42 #include "stringpool.h"
45 #include "gimplify-me.h"
48 #include "tree-object-size.h"
50 #include "gimple-fold.h"
53 /* Map from a tree to a VAR_DECL tree. */
55 struct GTY((for_user
)) tree_type_map
{
56 struct tree_map_base type
;
60 struct tree_type_map_cache_hasher
: ggc_cache_ptr_hash
<tree_type_map
>
62 static inline hashval_t
63 hash (tree_type_map
*t
)
65 return TYPE_UID (t
->type
.from
);
69 equal (tree_type_map
*a
, tree_type_map
*b
)
71 return a
->type
.from
== b
->type
.from
;
75 keep_cache_entry (tree_type_map
*&m
)
77 return ggc_marked_p (m
->type
.from
);
82 hash_table
<tree_type_map_cache_hasher
> *decl_tree_for_type
;
84 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
87 decl_for_type_lookup (tree type
)
89 /* If the hash table is not initialized yet, create it now. */
90 if (decl_tree_for_type
== NULL
)
93 = hash_table
<tree_type_map_cache_hasher
>::create_ggc (10);
94 /* That also means we don't have to bother with the lookup. */
98 struct tree_type_map
*h
, in
;
101 h
= decl_tree_for_type
->find_with_hash (&in
, TYPE_UID (type
));
102 return h
? h
->decl
: NULL_TREE
;
105 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
108 decl_for_type_insert (tree type
, tree decl
)
110 struct tree_type_map
*h
;
112 h
= ggc_alloc
<tree_type_map
> ();
115 *decl_tree_for_type
->find_slot_with_hash (h
, TYPE_UID (type
), INSERT
) = h
;
118 /* Helper routine, which encodes a value in the pointer_sized_int_node.
119 Arguments with precision <= POINTER_SIZE are passed directly,
120 the rest is passed by reference. T is a value we are to encode.
121 PHASE determines when this function is called. */
124 ubsan_encode_value (tree t
, enum ubsan_encode_value_phase phase
)
126 tree type
= TREE_TYPE (t
);
127 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
128 if (bitsize
<= POINTER_SIZE
)
129 switch (TREE_CODE (type
))
134 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
137 tree itype
= build_nonstandard_integer_type (bitsize
, true);
138 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
139 return fold_convert (pointer_sized_int_node
, t
);
146 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
148 /* The reason for this is that we don't want to pessimize
149 code by making vars unnecessarily addressable. */
151 if (phase
!= UBSAN_ENCODE_VALUE_GENERIC
)
153 var
= create_tmp_var (type
);
154 mark_addressable (var
);
158 var
= create_tmp_var_raw (type
);
159 TREE_ADDRESSABLE (var
) = 1;
160 DECL_CONTEXT (var
) = current_function_decl
;
162 if (phase
== UBSAN_ENCODE_VALUE_RTL
)
165 = assign_stack_temp_for_type (TYPE_MODE (type
),
166 GET_MODE_SIZE (TYPE_MODE (type
)),
168 SET_DECL_RTL (var
, mem
);
169 expand_assignment (var
, t
, false);
170 return build_fold_addr_expr (var
);
172 if (phase
!= UBSAN_ENCODE_VALUE_GENERIC
)
174 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
175 t
= build_fold_addr_expr (var
);
176 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
180 var
= build4 (TARGET_EXPR
, type
, var
, t
, NULL_TREE
, NULL_TREE
);
181 return build_fold_addr_expr (var
);
185 return build_fold_addr_expr (t
);
189 /* Cached ubsan_get_type_descriptor_type () return value. */
190 static GTY(()) tree ubsan_type_descriptor_type
;
193 struct __ubsan_type_descriptor
195 unsigned short __typekind;
196 unsigned short __typeinfo;
202 ubsan_get_type_descriptor_type (void)
204 static const char *field_names
[3]
205 = { "__typekind", "__typeinfo", "__typename" };
208 if (ubsan_type_descriptor_type
)
209 return ubsan_type_descriptor_type
;
211 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
212 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
214 ret
= make_node (RECORD_TYPE
);
215 for (int i
= 0; i
< 3; i
++)
217 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
218 get_identifier (field_names
[i
]),
219 (i
== 2) ? flex_arr_type
220 : short_unsigned_type_node
);
221 DECL_CONTEXT (fields
[i
]) = ret
;
223 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
225 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
226 get_identifier ("__ubsan_type_descriptor"),
228 DECL_IGNORED_P (type_decl
) = 1;
229 DECL_ARTIFICIAL (type_decl
) = 1;
230 TYPE_FIELDS (ret
) = fields
[0];
231 TYPE_NAME (ret
) = type_decl
;
232 TYPE_STUB_DECL (ret
) = type_decl
;
234 ubsan_type_descriptor_type
= ret
;
238 /* Cached ubsan_get_source_location_type () return value. */
239 static GTY(()) tree ubsan_source_location_type
;
242 struct __ubsan_source_location
244 const char *__filename;
246 unsigned int __column;
251 ubsan_get_source_location_type (void)
253 static const char *field_names
[3]
254 = { "__filename", "__line", "__column" };
256 if (ubsan_source_location_type
)
257 return ubsan_source_location_type
;
259 tree const_char_type
= build_qualified_type (char_type_node
,
262 ret
= make_node (RECORD_TYPE
);
263 for (int i
= 0; i
< 3; i
++)
265 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
266 get_identifier (field_names
[i
]),
267 (i
== 0) ? build_pointer_type (const_char_type
)
268 : unsigned_type_node
);
269 DECL_CONTEXT (fields
[i
]) = ret
;
271 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
273 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
274 get_identifier ("__ubsan_source_location"),
276 DECL_IGNORED_P (type_decl
) = 1;
277 DECL_ARTIFICIAL (type_decl
) = 1;
278 TYPE_FIELDS (ret
) = fields
[0];
279 TYPE_NAME (ret
) = type_decl
;
280 TYPE_STUB_DECL (ret
) = type_decl
;
282 ubsan_source_location_type
= ret
;
286 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
287 type with its fields filled from a location_t LOC. */
290 ubsan_source_location (location_t loc
)
292 expanded_location xloc
;
293 tree type
= ubsan_get_source_location_type ();
295 xloc
= expand_location (loc
);
297 if (xloc
.file
== NULL
)
299 str
= build_int_cst (ptr_type_node
, 0);
305 /* Fill in the values from LOC. */
306 size_t len
= strlen (xloc
.file
) + 1;
307 str
= build_string (len
, xloc
.file
);
308 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
309 TREE_READONLY (str
) = 1;
310 TREE_STATIC (str
) = 1;
311 str
= build_fold_addr_expr (str
);
313 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
314 build_int_cst (unsigned_type_node
,
315 xloc
.line
), NULL_TREE
,
316 build_int_cst (unsigned_type_node
,
318 TREE_CONSTANT (ctor
) = 1;
319 TREE_STATIC (ctor
) = 1;
324 /* This routine returns a magic number for TYPE. */
326 static unsigned short
327 get_ubsan_type_info_for_type (tree type
)
329 if (TREE_CODE (type
) == REAL_TYPE
)
330 return tree_to_uhwi (TYPE_SIZE (type
));
331 else if (INTEGRAL_TYPE_P (type
))
333 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
334 gcc_assert (prec
!= -1);
335 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
341 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
342 ubsan_ids[1] for Lubsan_data labels. */
343 static GTY(()) unsigned int ubsan_ids
[2];
345 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
346 descriptor. It first looks into the hash table; if not found,
347 create the VAR_DECL, put it into the hash table and return the
348 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
349 an enum controlling how we want to print the type. */
352 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
354 /* See through any typedefs. */
355 type
= TYPE_MAIN_VARIANT (type
);
357 tree decl
= decl_for_type_lookup (type
);
358 /* It is possible that some of the earlier created DECLs were found
359 unused, in that case they weren't emitted and varpool_node::get
360 returns NULL node on them. But now we really need them. Thus,
362 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
363 return build_fold_addr_expr (decl
);
365 tree dtype
= ubsan_get_type_descriptor_type ();
367 const char *tname
= NULL
;
368 pretty_printer pretty_name
;
369 unsigned char deref_depth
= 0;
370 unsigned short tkind
, tinfo
;
372 /* Get the name of the type, or the name of the pointer type. */
373 if (pstyle
== UBSAN_PRINT_POINTER
)
375 gcc_assert (POINTER_TYPE_P (type
));
376 type2
= TREE_TYPE (type
);
378 /* Remove any '*' operators from TYPE. */
379 while (POINTER_TYPE_P (type2
))
380 deref_depth
++, type2
= TREE_TYPE (type2
);
382 if (TREE_CODE (type2
) == METHOD_TYPE
)
383 type2
= TYPE_METHOD_BASETYPE (type2
);
386 /* If an array, get its type. */
387 type2
= strip_array_types (type2
);
389 if (pstyle
== UBSAN_PRINT_ARRAY
)
391 while (POINTER_TYPE_P (type2
))
392 deref_depth
++, type2
= TREE_TYPE (type2
);
395 if (TYPE_NAME (type2
) != NULL
)
397 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
398 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
399 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
400 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
404 /* We weren't able to determine the type name. */
408 if (pstyle
== UBSAN_PRINT_POINTER
)
410 pp_printf (&pretty_name
, "'%s%s%s%s%s%s%s",
411 TYPE_VOLATILE (type2
) ? "volatile " : "",
412 TYPE_READONLY (type2
) ? "const " : "",
413 TYPE_RESTRICT (type2
) ? "restrict " : "",
414 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
415 TREE_CODE (type2
) == RECORD_TYPE
417 : TREE_CODE (type2
) == UNION_TYPE
418 ? "union " : "", tname
,
419 deref_depth
== 0 ? "" : " ");
420 while (deref_depth
-- > 0)
421 pp_star (&pretty_name
);
422 pp_quote (&pretty_name
);
424 else if (pstyle
== UBSAN_PRINT_ARRAY
)
426 /* Pretty print the array dimensions. */
427 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
429 pp_printf (&pretty_name
, "'%s ", tname
);
430 while (deref_depth
-- > 0)
431 pp_star (&pretty_name
);
432 while (TREE_CODE (t
) == ARRAY_TYPE
)
434 pp_left_bracket (&pretty_name
);
435 tree dom
= TYPE_DOMAIN (t
);
437 && TYPE_MAX_VALUE (dom
) != NULL_TREE
438 && TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
440 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom
))
441 && tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1 != 0)
442 pp_printf (&pretty_name
, HOST_WIDE_INT_PRINT_DEC
,
443 tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1);
445 pp_wide_int (&pretty_name
,
446 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom
)), 1),
447 TYPE_SIGN (TREE_TYPE (dom
)));
450 /* ??? We can't determine the variable name; print VLA unspec. */
451 pp_star (&pretty_name
);
452 pp_right_bracket (&pretty_name
);
455 pp_quote (&pretty_name
);
457 /* Save the tree with stripped types. */
461 pp_printf (&pretty_name
, "'%s'", tname
);
463 switch (TREE_CODE (eltype
))
471 /* FIXME: libubsan right now only supports float, double and
472 long double type formats. */
473 if (TYPE_MODE (eltype
) == TYPE_MODE (float_type_node
)
474 || TYPE_MODE (eltype
) == TYPE_MODE (double_type_node
)
475 || TYPE_MODE (eltype
) == TYPE_MODE (long_double_type_node
))
484 tinfo
= get_ubsan_type_info_for_type (eltype
);
486 /* Create a new VAR_DECL of type descriptor. */
487 const char *tmp
= pp_formatted_text (&pretty_name
);
488 size_t len
= strlen (tmp
) + 1;
489 tree str
= build_string (len
, tmp
);
490 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
491 TREE_READONLY (str
) = 1;
492 TREE_STATIC (str
) = 1;
495 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", ubsan_ids
[0]++);
496 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
498 TREE_STATIC (decl
) = 1;
499 TREE_PUBLIC (decl
) = 0;
500 DECL_ARTIFICIAL (decl
) = 1;
501 DECL_IGNORED_P (decl
) = 1;
502 DECL_EXTERNAL (decl
) = 0;
504 = size_binop (PLUS_EXPR
, DECL_SIZE (decl
), TYPE_SIZE (TREE_TYPE (str
)));
505 DECL_SIZE_UNIT (decl
)
506 = size_binop (PLUS_EXPR
, DECL_SIZE_UNIT (decl
),
507 TYPE_SIZE_UNIT (TREE_TYPE (str
)));
509 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
510 build_int_cst (short_unsigned_type_node
,
512 build_int_cst (short_unsigned_type_node
,
513 tinfo
), NULL_TREE
, str
);
514 TREE_CONSTANT (ctor
) = 1;
515 TREE_STATIC (ctor
) = 1;
516 DECL_INITIAL (decl
) = ctor
;
517 varpool_node::finalize_decl (decl
);
519 /* Save the VAR_DECL into the hash table. */
520 decl_for_type_insert (type
, decl
);
522 return build_fold_addr_expr (decl
);
525 /* Create a structure for the ubsan library. NAME is a name of the new
526 structure. LOCCNT is number of locations, PLOC points to array of
527 locations. The arguments in ... are of __ubsan_type_descriptor type
528 and there are at most two of them, followed by NULL_TREE, followed
529 by optional extra arguments and another NULL_TREE. */
532 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
537 vec
<tree
, va_gc
> *saved_args
= NULL
;
541 /* It is possible that PCH zapped table with definitions of sanitizer
542 builtins. Reinitialize them if needed. */
543 initialize_sanitizer_builtins ();
545 /* Firstly, create a pointer to type descriptor type. */
546 tree td_type
= ubsan_get_type_descriptor_type ();
547 td_type
= build_pointer_type (td_type
);
549 /* Create the structure type. */
550 ret
= make_node (RECORD_TYPE
);
551 for (j
= 0; j
< loccnt
; j
++)
553 gcc_checking_assert (i
< 2);
554 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
555 ubsan_get_source_location_type ());
556 DECL_CONTEXT (fields
[i
]) = ret
;
558 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
562 va_start (args
, ploc
);
563 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
564 i
++, t
= va_arg (args
, tree
))
566 gcc_checking_assert (i
< 4);
567 /* Save the tree arguments for later use. */
568 vec_safe_push (saved_args
, t
);
569 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
571 DECL_CONTEXT (fields
[i
]) = ret
;
573 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
576 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
577 i
++, t
= va_arg (args
, tree
))
579 gcc_checking_assert (i
< 6);
580 /* Save the tree arguments for later use. */
581 vec_safe_push (saved_args
, t
);
582 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
584 DECL_CONTEXT (fields
[i
]) = ret
;
586 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
590 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
591 get_identifier (name
), ret
);
592 DECL_IGNORED_P (type_decl
) = 1;
593 DECL_ARTIFICIAL (type_decl
) = 1;
594 TYPE_FIELDS (ret
) = fields
[0];
595 TYPE_NAME (ret
) = type_decl
;
596 TYPE_STUB_DECL (ret
) = type_decl
;
599 /* Now, fill in the type. */
601 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_ids
[1]++);
602 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
604 TREE_STATIC (var
) = 1;
605 TREE_PUBLIC (var
) = 0;
606 DECL_ARTIFICIAL (var
) = 1;
607 DECL_IGNORED_P (var
) = 1;
608 DECL_EXTERNAL (var
) = 0;
610 vec
<constructor_elt
, va_gc
> *v
;
612 tree ctor
= build_constructor (ret
, v
);
614 /* If desirable, set the __ubsan_source_location element. */
615 for (j
= 0; j
< loccnt
; j
++)
617 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
618 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
621 size_t nelts
= vec_safe_length (saved_args
);
622 for (i
= 0; i
< nelts
; i
++)
624 t
= (*saved_args
)[i
];
625 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
628 TREE_CONSTANT (ctor
) = 1;
629 TREE_STATIC (ctor
) = 1;
630 DECL_INITIAL (var
) = ctor
;
631 varpool_node::finalize_decl (var
);
636 /* Instrument the __builtin_unreachable call. We just call the libubsan
640 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
643 location_t loc
= gimple_location (gsi_stmt (*gsi
));
645 if (flag_sanitize_undefined_trap_on_error
)
646 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
649 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
650 NULL_TREE
, NULL_TREE
);
651 data
= build_fold_addr_expr_loc (loc
, data
);
653 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
654 g
= gimple_build_call (fn
, 1, data
);
656 gimple_set_location (g
, loc
);
657 gsi_replace (gsi
, g
, false);
661 /* Return true if T is a call to a libubsan routine. */
664 is_ubsan_builtin_p (tree t
)
666 return TREE_CODE (t
) == FUNCTION_DECL
667 && DECL_BUILT_IN_CLASS (t
) == BUILT_IN_NORMAL
668 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
669 "__builtin___ubsan_", 18) == 0;
672 /* Create a callgraph edge for statement STMT. */
675 ubsan_create_edge (gimple
*stmt
)
677 gcall
*call_stmt
= dyn_cast
<gcall
*> (stmt
);
678 basic_block bb
= gimple_bb (stmt
);
679 int freq
= compute_call_stmt_bb_frequency (current_function_decl
, bb
);
680 cgraph_node
*node
= cgraph_node::get (current_function_decl
);
681 tree decl
= gimple_call_fndecl (call_stmt
);
683 node
->create_edge (cgraph_node::get_create (decl
), call_stmt
, bb
->count
,
687 /* Expand the UBSAN_BOUNDS special builtin function. */
690 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
692 gimple
*stmt
= gsi_stmt (*gsi
);
693 location_t loc
= gimple_location (stmt
);
694 gcc_assert (gimple_call_num_args (stmt
) == 3);
696 /* Pick up the arguments of the UBSAN_BOUNDS call. */
697 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
698 tree index
= gimple_call_arg (stmt
, 1);
699 tree orig_index
= index
;
700 tree bound
= gimple_call_arg (stmt
, 2);
702 gimple_stmt_iterator gsi_orig
= *gsi
;
704 /* Create condition "if (index > bound)". */
705 basic_block then_bb
, fallthru_bb
;
706 gimple_stmt_iterator cond_insert_point
707 = create_cond_insert_point (gsi
, false, false, true,
708 &then_bb
, &fallthru_bb
);
709 index
= fold_convert (TREE_TYPE (bound
), index
);
710 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
712 false, GSI_NEW_STMT
);
713 gimple
*g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
714 gimple_set_location (g
, loc
);
715 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
717 /* Generate __ubsan_handle_out_of_bounds call. */
718 *gsi
= gsi_after_labels (then_bb
);
719 if (flag_sanitize_undefined_trap_on_error
)
720 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
724 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
725 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
726 ubsan_type_descriptor (TREE_TYPE (orig_index
)),
727 NULL_TREE
, NULL_TREE
);
728 data
= build_fold_addr_expr_loc (loc
, data
);
729 enum built_in_function bcode
730 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
731 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
732 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
733 tree fn
= builtin_decl_explicit (bcode
);
734 tree val
= ubsan_encode_value (orig_index
, UBSAN_ENCODE_VALUE_GIMPLE
);
735 val
= force_gimple_operand_gsi (gsi
, val
, true, NULL_TREE
, true,
737 g
= gimple_build_call (fn
, 2, data
, val
);
739 gimple_set_location (g
, loc
);
740 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
742 /* Get rid of the UBSAN_BOUNDS call from the IR. */
743 unlink_stmt_vdef (stmt
);
744 gsi_remove (&gsi_orig
, true);
746 /* Point GSI to next logical statement. */
747 *gsi
= gsi_start_bb (fallthru_bb
);
751 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
752 argument which is a constant, because the middle-end treats pointer
753 conversions as useless and therefore the type of the first argument
754 could be changed to any other pointer type. */
757 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
759 gimple_stmt_iterator gsi
= *gsip
;
760 gimple
*stmt
= gsi_stmt (gsi
);
761 location_t loc
= gimple_location (stmt
);
762 gcc_assert (gimple_call_num_args (stmt
) == 3);
763 tree ptr
= gimple_call_arg (stmt
, 0);
764 tree ckind
= gimple_call_arg (stmt
, 1);
765 tree align
= gimple_call_arg (stmt
, 2);
766 tree check_align
= NULL_TREE
;
769 basic_block cur_bb
= gsi_bb (gsi
);
772 if (!integer_zerop (align
))
774 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
775 if (compare_tree_int (align
, ptralign
) == 1)
777 check_align
= make_ssa_name (pointer_sized_int_node
);
778 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
779 gimple_set_location (g
, loc
);
780 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
783 check_null
= sanitize_flags_p (SANITIZE_NULL
);
785 if (check_align
== NULL_TREE
&& !check_null
)
787 gsi_remove (gsip
, true);
788 /* Unlink the UBSAN_NULLs vops before replacing it. */
789 unlink_stmt_vdef (stmt
);
793 /* Split the original block holding the pointer dereference. */
794 edge e
= split_block (cur_bb
, stmt
);
796 /* Get a hold on the 'condition block', the 'then block' and the
798 basic_block cond_bb
= e
->src
;
799 basic_block fallthru_bb
= e
->dest
;
800 basic_block then_bb
= create_empty_bb (cond_bb
);
801 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
802 loops_state_set (LOOPS_NEED_FIXUP
);
804 /* Make an edge coming from the 'cond block' into the 'then block';
805 this edge is unlikely taken, so set up the probability accordingly. */
806 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
807 e
->probability
= profile_probability::very_unlikely ();
809 /* Connect 'then block' with the 'else block'. This is needed
810 as the ubsan routines we call in the 'then block' are not noreturn.
811 The 'then block' only has one outcoming edge. */
812 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
814 /* Set up the fallthrough basic block. */
815 e
= find_edge (cond_bb
, fallthru_bb
);
816 e
->flags
= EDGE_FALSE_VALUE
;
817 e
->count
= cond_bb
->count
;
818 e
->probability
= profile_probability::very_likely ();
820 /* Update dominance info for the newly created then_bb; note that
821 fallthru_bb's dominance info has already been updated by
823 if (dom_info_available_p (CDI_DOMINATORS
))
824 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
826 /* Put the ubsan builtin call into the newly created BB. */
827 if (flag_sanitize_undefined_trap_on_error
)
828 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
831 enum built_in_function bcode
832 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
833 | (check_null
? SANITIZE_NULL
: 0)))
834 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
835 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
836 tree fn
= builtin_decl_implicit (bcode
);
838 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
839 ubsan_type_descriptor (TREE_TYPE (ckind
),
840 UBSAN_PRINT_POINTER
),
843 fold_convert (unsigned_char_type_node
, ckind
),
845 data
= build_fold_addr_expr_loc (loc
, data
);
846 g
= gimple_build_call (fn
, 2, data
,
847 check_align
? check_align
848 : build_zero_cst (pointer_sized_int_node
));
850 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
851 gimple_set_location (g
, loc
);
852 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
854 /* Unlink the UBSAN_NULLs vops before replacing it. */
855 unlink_stmt_vdef (stmt
);
859 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
860 NULL_TREE
, NULL_TREE
);
861 gimple_set_location (g
, loc
);
863 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
864 gsi_replace (&gsi
, g
, false);
872 /* Split the block with the condition again. */
873 e
= split_block (cond_bb
, stmt
);
874 basic_block cond1_bb
= e
->src
;
875 basic_block cond2_bb
= e
->dest
;
877 /* Make an edge coming from the 'cond1 block' into the 'then block';
878 this edge is unlikely taken, so set up the probability
880 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
881 e
->probability
= profile_probability::very_unlikely ();
883 /* Set up the fallthrough basic block. */
884 e
= find_edge (cond1_bb
, cond2_bb
);
885 e
->flags
= EDGE_FALSE_VALUE
;
886 e
->count
= cond1_bb
->count
;
887 e
->probability
= profile_probability::very_likely ();
889 /* Update dominance info. */
890 if (dom_info_available_p (CDI_DOMINATORS
))
892 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
893 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
896 gsi2
= gsi_start_bb (cond2_bb
);
899 tree mask
= build_int_cst (pointer_sized_int_node
,
900 tree_to_uhwi (align
) - 1);
901 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
902 BIT_AND_EXPR
, check_align
, mask
);
903 gimple_set_location (g
, loc
);
905 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
907 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
909 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
910 build_int_cst (pointer_sized_int_node
, 0),
911 NULL_TREE
, NULL_TREE
);
912 gimple_set_location (g
, loc
);
914 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
916 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
917 gsi_replace (&gsi
, g
, false);
922 #define OBJSZ_MAX_OFFSET (1024 * 16)
924 /* Expand UBSAN_OBJECT_SIZE internal call. */
927 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
929 gimple
*stmt
= gsi_stmt (*gsi
);
930 location_t loc
= gimple_location (stmt
);
931 gcc_assert (gimple_call_num_args (stmt
) == 4);
933 tree ptr
= gimple_call_arg (stmt
, 0);
934 tree offset
= gimple_call_arg (stmt
, 1);
935 tree size
= gimple_call_arg (stmt
, 2);
936 tree ckind
= gimple_call_arg (stmt
, 3);
937 gimple_stmt_iterator gsi_orig
= *gsi
;
940 /* See if we can discard the check. */
941 if (TREE_CODE (size
) != INTEGER_CST
942 || integer_all_onesp (size
))
943 /* Yes, __builtin_object_size couldn't determine the
945 else if (TREE_CODE (offset
) == INTEGER_CST
946 && wi::to_widest (offset
) >= -OBJSZ_MAX_OFFSET
947 && wi::to_widest (offset
) <= -1)
948 /* The offset is in range [-16K, -1]. */;
951 /* if (offset > objsize) */
952 basic_block then_bb
, fallthru_bb
;
953 gimple_stmt_iterator cond_insert_point
954 = create_cond_insert_point (gsi
, false, false, true,
955 &then_bb
, &fallthru_bb
);
956 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
957 gimple_set_location (g
, loc
);
958 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
960 /* If the offset is small enough, we don't need the second
962 if (TREE_CODE (offset
) == INTEGER_CST
963 && wi::to_widest (offset
) >= 0
964 && wi::to_widest (offset
) <= OBJSZ_MAX_OFFSET
)
965 *gsi
= gsi_after_labels (then_bb
);
968 /* Don't issue run-time error if (ptr > ptr + offset). That
969 may happen when computing a POINTER_PLUS_EXPR. */
970 basic_block then2_bb
, fallthru2_bb
;
972 gimple_stmt_iterator gsi2
= gsi_after_labels (then_bb
);
973 cond_insert_point
= create_cond_insert_point (&gsi2
, false, false,
976 /* Convert the pointer to an integer type. */
977 tree p
= make_ssa_name (pointer_sized_int_node
);
978 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
979 gimple_set_location (g
, loc
);
980 gsi_insert_before (&cond_insert_point
, g
, GSI_NEW_STMT
);
981 p
= gimple_assign_lhs (g
);
982 /* Compute ptr + offset. */
983 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
984 PLUS_EXPR
, p
, offset
);
985 gimple_set_location (g
, loc
);
986 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
987 /* Now build the conditional and put it into the IR. */
988 g
= gimple_build_cond (LE_EXPR
, p
, gimple_assign_lhs (g
),
989 NULL_TREE
, NULL_TREE
);
990 gimple_set_location (g
, loc
);
991 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
992 *gsi
= gsi_after_labels (then2_bb
);
995 /* Generate __ubsan_handle_type_mismatch call. */
996 if (flag_sanitize_undefined_trap_on_error
)
997 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1001 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
1002 ubsan_type_descriptor (TREE_TYPE (ptr
),
1003 UBSAN_PRINT_POINTER
),
1005 build_zero_cst (pointer_sized_int_node
),
1008 data
= build_fold_addr_expr_loc (loc
, data
);
1009 enum built_in_function bcode
1010 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
1011 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1012 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
1013 tree p
= make_ssa_name (pointer_sized_int_node
);
1014 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
1015 gimple_set_location (g
, loc
);
1016 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1017 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
1019 gimple_set_location (g
, loc
);
1020 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1022 /* Point GSI to next logical statement. */
1023 *gsi
= gsi_start_bb (fallthru_bb
);
1025 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1026 unlink_stmt_vdef (stmt
);
1027 gsi_remove (&gsi_orig
, true);
1031 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1032 unlink_stmt_vdef (stmt
);
1033 gsi_remove (gsi
, true);
1037 /* Expand UBSAN_PTR internal call. */
1040 ubsan_expand_ptr_ifn (gimple_stmt_iterator
*gsip
)
1042 gimple_stmt_iterator gsi
= *gsip
;
1043 gimple
*stmt
= gsi_stmt (gsi
);
1044 location_t loc
= gimple_location (stmt
);
1045 gcc_assert (gimple_call_num_args (stmt
) == 2);
1046 tree ptr
= gimple_call_arg (stmt
, 0);
1047 tree off
= gimple_call_arg (stmt
, 1);
1049 if (integer_zerop (off
))
1051 gsi_remove (gsip
, true);
1052 unlink_stmt_vdef (stmt
);
1056 basic_block cur_bb
= gsi_bb (gsi
);
1057 tree ptrplusoff
= make_ssa_name (pointer_sized_int_node
);
1058 tree ptri
= make_ssa_name (pointer_sized_int_node
);
1059 int pos_neg
= get_range_pos_neg (off
);
1061 /* Split the original block holding the pointer dereference. */
1062 edge e
= split_block (cur_bb
, stmt
);
1064 /* Get a hold on the 'condition block', the 'then block' and the
1066 basic_block cond_bb
= e
->src
;
1067 basic_block fallthru_bb
= e
->dest
;
1068 basic_block then_bb
= create_empty_bb (cond_bb
);
1069 basic_block cond_pos_bb
= NULL
, cond_neg_bb
= NULL
;
1070 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
1071 loops_state_set (LOOPS_NEED_FIXUP
);
1073 /* Set up the fallthrough basic block. */
1074 e
->flags
= EDGE_FALSE_VALUE
;
1077 e
->count
= cond_bb
->count
;
1078 e
->probability
= profile_probability::very_likely ();
1080 /* Connect 'then block' with the 'else block'. This is needed
1081 as the ubsan routines we call in the 'then block' are not noreturn.
1082 The 'then block' only has one outcoming edge. */
1083 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
1085 /* Make an edge coming from the 'cond block' into the 'then block';
1086 this edge is unlikely taken, so set up the probability
1088 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
1089 e
->probability
= profile_probability::very_unlikely ();
1093 profile_count count
= cond_bb
->count
.apply_probability (PROB_EVEN
);
1095 e
->probability
= profile_probability::even ();
1097 e
= split_block (fallthru_bb
, (gimple
*) NULL
);
1098 cond_neg_bb
= e
->src
;
1099 fallthru_bb
= e
->dest
;
1101 e
->probability
= profile_probability::very_likely ();
1102 e
->flags
= EDGE_FALSE_VALUE
;
1104 e
= make_edge (cond_neg_bb
, then_bb
, EDGE_TRUE_VALUE
);
1105 e
->probability
= profile_probability::very_unlikely ();
1107 cond_pos_bb
= create_empty_bb (cond_bb
);
1108 add_bb_to_loop (cond_pos_bb
, cond_bb
->loop_father
);
1110 e
= make_edge (cond_bb
, cond_pos_bb
, EDGE_TRUE_VALUE
);
1112 e
->probability
= profile_probability::even ();
1114 e
= make_edge (cond_pos_bb
, then_bb
, EDGE_TRUE_VALUE
);
1115 e
->probability
= profile_probability::very_unlikely ();
1117 e
= make_edge (cond_pos_bb
, fallthru_bb
, EDGE_FALSE_VALUE
);
1119 e
->probability
= profile_probability::very_likely ();
1121 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
1124 gimple
*g
= gimple_build_assign (ptri
, NOP_EXPR
, ptr
);
1125 gimple_set_location (g
, loc
);
1126 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1127 g
= gimple_build_assign (ptrplusoff
, PLUS_EXPR
, ptri
, off
);
1128 gimple_set_location (g
, loc
);
1129 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1131 /* Update dominance info for the newly created then_bb; note that
1132 fallthru_bb's dominance info has already been updated by
1134 if (dom_info_available_p (CDI_DOMINATORS
))
1136 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
1139 set_immediate_dominator (CDI_DOMINATORS
, cond_pos_bb
, cond_bb
);
1140 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond_bb
);
1144 /* Put the ubsan builtin call into the newly created BB. */
1145 if (flag_sanitize_undefined_trap_on_error
)
1146 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
1149 enum built_in_function bcode
1150 = (flag_sanitize_recover
& SANITIZE_POINTER_OVERFLOW
)
1151 ? BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW
1152 : BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW_ABORT
;
1153 tree fn
= builtin_decl_implicit (bcode
);
1155 = ubsan_create_data ("__ubsan_ptrovf_data", 1, &loc
,
1156 NULL_TREE
, NULL_TREE
);
1157 data
= build_fold_addr_expr_loc (loc
, data
);
1158 g
= gimple_build_call (fn
, 3, data
, ptr
, ptrplusoff
);
1160 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
1161 gimple_set_location (g
, loc
);
1162 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
1164 /* Unlink the UBSAN_PTRs vops before replacing it. */
1165 unlink_stmt_vdef (stmt
);
1167 if (TREE_CODE (off
) == INTEGER_CST
)
1168 g
= gimple_build_cond (wi::neg_p (off
) ? LT_EXPR
: GE_EXPR
, ptri
,
1169 fold_build1 (NEGATE_EXPR
, sizetype
, off
),
1170 NULL_TREE
, NULL_TREE
);
1171 else if (pos_neg
!= 3)
1172 g
= gimple_build_cond (pos_neg
== 1 ? LT_EXPR
: GT_EXPR
,
1173 ptrplusoff
, ptri
, NULL_TREE
, NULL_TREE
);
1176 gsi2
= gsi_start_bb (cond_pos_bb
);
1177 g
= gimple_build_cond (LT_EXPR
, ptrplusoff
, ptri
, NULL_TREE
, NULL_TREE
);
1178 gimple_set_location (g
, loc
);
1179 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
1181 gsi2
= gsi_start_bb (cond_neg_bb
);
1182 g
= gimple_build_cond (GT_EXPR
, ptrplusoff
, ptri
, NULL_TREE
, NULL_TREE
);
1183 gimple_set_location (g
, loc
);
1184 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
1186 gimple_seq seq
= NULL
;
1187 tree t
= gimple_build (&seq
, loc
, NOP_EXPR
, ssizetype
, off
);
1188 t
= gimple_build (&seq
, loc
, GE_EXPR
, boolean_type_node
,
1190 gsi_insert_seq_before (&gsi
, seq
, GSI_SAME_STMT
);
1191 g
= gimple_build_cond (NE_EXPR
, t
, boolean_false_node
,
1192 NULL_TREE
, NULL_TREE
);
1194 gimple_set_location (g
, loc
);
1195 /* Replace the UBSAN_PTR with a GIMPLE_COND stmt. */
1196 gsi_replace (&gsi
, g
, false);
1201 /* Cached __ubsan_vptr_type_cache decl. */
1202 static GTY(()) tree ubsan_vptr_type_cache_decl
;
1204 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1205 argument which is a constant, because the middle-end treats pointer
1206 conversions as useless and therefore the type of the first argument
1207 could be changed to any other pointer type. */
1210 ubsan_expand_vptr_ifn (gimple_stmt_iterator
*gsip
)
1212 gimple_stmt_iterator gsi
= *gsip
;
1213 gimple
*stmt
= gsi_stmt (gsi
);
1214 location_t loc
= gimple_location (stmt
);
1215 gcc_assert (gimple_call_num_args (stmt
) == 5);
1216 tree op
= gimple_call_arg (stmt
, 0);
1217 tree vptr
= gimple_call_arg (stmt
, 1);
1218 tree str_hash
= gimple_call_arg (stmt
, 2);
1219 tree ti_decl_addr
= gimple_call_arg (stmt
, 3);
1220 tree ckind_tree
= gimple_call_arg (stmt
, 4);
1221 ubsan_null_ckind ckind
= (ubsan_null_ckind
) tree_to_uhwi (ckind_tree
);
1222 tree type
= TREE_TYPE (TREE_TYPE (ckind_tree
));
1224 basic_block fallthru_bb
= NULL
;
1226 if (ckind
== UBSAN_DOWNCAST_POINTER
)
1228 /* Guard everything with if (op != NULL) { ... }. */
1229 basic_block then_bb
;
1230 gimple_stmt_iterator cond_insert_point
1231 = create_cond_insert_point (gsip
, false, false, true,
1232 &then_bb
, &fallthru_bb
);
1233 g
= gimple_build_cond (NE_EXPR
, op
, build_zero_cst (TREE_TYPE (op
)),
1234 NULL_TREE
, NULL_TREE
);
1235 gimple_set_location (g
, loc
);
1236 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1237 *gsip
= gsi_after_labels (then_bb
);
1238 gsi_remove (&gsi
, false);
1239 gsi_insert_before (gsip
, stmt
, GSI_NEW_STMT
);
1243 tree htype
= TREE_TYPE (str_hash
);
1244 tree cst
= wide_int_to_tree (htype
,
1245 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1247 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1249 gimple_set_location (g
, loc
);
1250 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1251 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1252 gimple_assign_lhs (g
), cst
);
1253 gimple_set_location (g
, loc
);
1254 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1255 tree t1
= gimple_assign_lhs (g
);
1256 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1257 t1
, build_int_cst (integer_type_node
, 47));
1258 gimple_set_location (g
, loc
);
1259 tree t2
= gimple_assign_lhs (g
);
1260 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1261 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1263 gimple_set_location (g
, loc
);
1264 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1265 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1266 t2
, gimple_assign_lhs (g
));
1267 gimple_set_location (g
, loc
);
1268 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1269 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1270 gimple_assign_lhs (g
), cst
);
1271 gimple_set_location (g
, loc
);
1272 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1273 tree t3
= gimple_assign_lhs (g
);
1274 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1275 t3
, build_int_cst (integer_type_node
, 47));
1276 gimple_set_location (g
, loc
);
1277 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1278 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1279 t3
, gimple_assign_lhs (g
));
1280 gimple_set_location (g
, loc
);
1281 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1282 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1283 gimple_assign_lhs (g
), cst
);
1284 gimple_set_location (g
, loc
);
1285 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1286 if (!useless_type_conversion_p (pointer_sized_int_node
, htype
))
1288 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1289 NOP_EXPR
, gimple_assign_lhs (g
));
1290 gimple_set_location (g
, loc
);
1291 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1293 tree hash
= gimple_assign_lhs (g
);
1295 if (ubsan_vptr_type_cache_decl
== NULL_TREE
)
1297 tree atype
= build_array_type_nelts (pointer_sized_int_node
, 128);
1298 tree array
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1299 get_identifier ("__ubsan_vptr_type_cache"),
1301 DECL_ARTIFICIAL (array
) = 1;
1302 DECL_IGNORED_P (array
) = 1;
1303 TREE_PUBLIC (array
) = 1;
1304 TREE_STATIC (array
) = 1;
1305 DECL_EXTERNAL (array
) = 1;
1306 DECL_VISIBILITY (array
) = VISIBILITY_DEFAULT
;
1307 DECL_VISIBILITY_SPECIFIED (array
) = 1;
1308 varpool_node::finalize_decl (array
);
1309 ubsan_vptr_type_cache_decl
= array
;
1312 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1314 build_int_cst (pointer_sized_int_node
, 127));
1315 gimple_set_location (g
, loc
);
1316 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1318 tree c
= build4_loc (loc
, ARRAY_REF
, pointer_sized_int_node
,
1319 ubsan_vptr_type_cache_decl
, gimple_assign_lhs (g
),
1320 NULL_TREE
, NULL_TREE
);
1321 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1323 gimple_set_location (g
, loc
);
1324 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1326 basic_block then_bb
, fallthru2_bb
;
1327 gimple_stmt_iterator cond_insert_point
1328 = create_cond_insert_point (gsip
, false, false, true,
1329 &then_bb
, &fallthru2_bb
);
1330 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
), hash
,
1331 NULL_TREE
, NULL_TREE
);
1332 gimple_set_location (g
, loc
);
1333 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1334 *gsip
= gsi_after_labels (then_bb
);
1335 if (fallthru_bb
== NULL
)
1336 fallthru_bb
= fallthru2_bb
;
1339 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc
,
1340 ubsan_type_descriptor (type
), NULL_TREE
, ti_decl_addr
,
1341 build_int_cst (unsigned_char_type_node
, ckind
),
1343 data
= build_fold_addr_expr_loc (loc
, data
);
1344 enum built_in_function bcode
1345 = (flag_sanitize_recover
& SANITIZE_VPTR
)
1346 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1347 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT
;
1349 g
= gimple_build_call (builtin_decl_explicit (bcode
), 3, data
, op
, hash
);
1350 gimple_set_location (g
, loc
);
1351 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1353 /* Point GSI to next logical statement. */
1354 *gsip
= gsi_start_bb (fallthru_bb
);
1356 /* Get rid of the UBSAN_VPTR call from the IR. */
1357 unlink_stmt_vdef (stmt
);
1358 gsi_remove (&gsi
, true);
1362 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1363 whether the pointer is on the left hand side of the assignment. */
1366 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
1369 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
1370 unsigned int align
= 0;
1371 if (sanitize_flags_p (SANITIZE_ALIGNMENT
))
1373 align
= min_align_of_type (TREE_TYPE (base
));
1377 if (align
== 0 && !sanitize_flags_p (SANITIZE_NULL
))
1379 tree t
= TREE_OPERAND (base
, 0);
1380 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
1382 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base
)) && mem
!= base
)
1383 ikind
= UBSAN_MEMBER_ACCESS
;
1384 tree kind
= build_int_cst (build_pointer_type (TREE_TYPE (base
)), ikind
);
1385 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
1386 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
1387 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
1388 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
1391 /* Perform the pointer instrumentation. */
1394 instrument_null (gimple_stmt_iterator gsi
, tree t
, bool is_lhs
)
1396 /* Handle also e.g. &s->i. */
1397 if (TREE_CODE (t
) == ADDR_EXPR
)
1398 t
= TREE_OPERAND (t
, 0);
1399 tree base
= get_base_address (t
);
1400 if (base
!= NULL_TREE
1401 && TREE_CODE (base
) == MEM_REF
1402 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1403 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1406 /* Instrument pointer arithmetics PTR p+ OFF. */
1409 instrument_pointer_overflow (gimple_stmt_iterator
*gsi
, tree ptr
, tree off
)
1411 if (TYPE_PRECISION (sizetype
) != POINTER_SIZE
)
1413 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_PTR
, 2, ptr
, off
);
1414 gimple_set_location (g
, gimple_location (gsi_stmt (*gsi
)));
1415 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1418 /* Instrument pointer arithmetics if any. */
1421 maybe_instrument_pointer_overflow (gimple_stmt_iterator
*gsi
, tree t
)
1423 if (TYPE_PRECISION (sizetype
) != POINTER_SIZE
)
1426 /* Handle also e.g. &s->i. */
1427 if (TREE_CODE (t
) == ADDR_EXPR
)
1428 t
= TREE_OPERAND (t
, 0);
1430 if (!handled_component_p (t
) && TREE_CODE (t
) != MEM_REF
)
1433 HOST_WIDE_INT bitsize
, bitpos
, bytepos
;
1436 int volatilep
= 0, reversep
, unsignedp
= 0;
1437 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1438 &unsignedp
, &reversep
, &volatilep
);
1439 tree moff
= NULL_TREE
;
1441 bool decl_p
= DECL_P (inner
);
1445 if (DECL_REGISTER (inner
))
1448 /* If BASE is a fixed size automatic variable or
1449 global variable defined in the current TU and bitpos
1450 fits, don't instrument anything. */
1451 if (offset
== NULL_TREE
1454 || TREE_CODE (base
) == PARM_DECL
1455 || TREE_CODE (base
) == RESULT_DECL
)
1457 && TREE_CODE (DECL_SIZE (base
)) == INTEGER_CST
1458 && compare_tree_int (DECL_SIZE (base
), bitpos
) >= 0
1459 && (!is_global_var (base
) || decl_binds_to_current_def_p (base
)))
1462 else if (TREE_CODE (inner
) == MEM_REF
)
1464 base
= TREE_OPERAND (inner
, 0);
1465 if (TREE_CODE (base
) == ADDR_EXPR
1466 && DECL_P (TREE_OPERAND (base
, 0))
1467 && !TREE_ADDRESSABLE (TREE_OPERAND (base
, 0))
1468 && !is_global_var (TREE_OPERAND (base
, 0)))
1470 moff
= TREE_OPERAND (inner
, 1);
1471 if (integer_zerop (moff
))
1477 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1479 bytepos
= bitpos
/ BITS_PER_UNIT
;
1480 if (offset
== NULL_TREE
&& bytepos
== 0 && moff
== NULL_TREE
)
1483 tree base_addr
= base
;
1485 base_addr
= build1 (ADDR_EXPR
,
1486 build_pointer_type (TREE_TYPE (base
)), base
);
1491 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t
,
1492 build_int_cst (TREE_TYPE (t
), bytepos
));
1494 t
= size_int (bytepos
);
1499 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t
,
1500 fold_convert (TREE_TYPE (t
), moff
));
1502 t
= fold_convert (sizetype
, moff
);
1504 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1506 base_addr
= force_gimple_operand_gsi (gsi
, base_addr
, true, NULL_TREE
, true,
1508 instrument_pointer_overflow (gsi
, base_addr
, t
);
1511 /* Build an ubsan builtin call for the signed-integer-overflow
1512 sanitization. CODE says what kind of builtin are we building,
1513 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1514 are operands of the binary operation. */
1517 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1518 tree op0
, tree op1
, tree
*datap
)
1520 if (flag_sanitize_undefined_trap_on_error
)
1521 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1524 if (datap
&& *datap
)
1527 data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1528 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1532 enum built_in_function fn_code
;
1537 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1538 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1539 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1542 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1543 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1544 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1547 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1548 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1549 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1552 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1553 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1554 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1559 tree fn
= builtin_decl_explicit (fn_code
);
1560 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1561 build_fold_addr_expr_loc (loc
, data
),
1562 ubsan_encode_value (op0
, UBSAN_ENCODE_VALUE_RTL
),
1564 ? ubsan_encode_value (op1
,
1565 UBSAN_ENCODE_VALUE_RTL
)
1569 /* Perform the signed integer instrumentation. GSI is the iterator
1570 pointing at statement we are trying to instrument. */
1573 instrument_si_overflow (gimple_stmt_iterator gsi
)
1575 gimple
*stmt
= gsi_stmt (gsi
);
1576 tree_code code
= gimple_assign_rhs_code (stmt
);
1577 tree lhs
= gimple_assign_lhs (stmt
);
1578 tree lhstype
= TREE_TYPE (lhs
);
1579 tree lhsinner
= VECTOR_TYPE_P (lhstype
) ? TREE_TYPE (lhstype
) : lhstype
;
1583 /* If this is not a signed operation, don't instrument anything here.
1584 Also punt on bit-fields. */
1585 if (!INTEGRAL_TYPE_P (lhsinner
)
1586 || TYPE_OVERFLOW_WRAPS (lhsinner
)
1587 || GET_MODE_BITSIZE (TYPE_MODE (lhsinner
)) != TYPE_PRECISION (lhsinner
))
1598 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1599 a
= gimple_assign_rhs1 (stmt
);
1600 b
= gimple_assign_rhs2 (stmt
);
1601 g
= gimple_build_call_internal (code
== PLUS_EXPR
1602 ? IFN_UBSAN_CHECK_ADD
1603 : code
== MINUS_EXPR
1604 ? IFN_UBSAN_CHECK_SUB
1605 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1606 gimple_call_set_lhs (g
, lhs
);
1607 gsi_replace (&gsi
, g
, true);
1610 /* Represent i = -u;
1612 i = UBSAN_CHECK_SUB (0, u); */
1613 a
= build_zero_cst (lhstype
);
1614 b
= gimple_assign_rhs1 (stmt
);
1615 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1616 gimple_call_set_lhs (g
, lhs
);
1617 gsi_replace (&gsi
, g
, true);
1620 /* Transform i = ABS_EXPR<u>;
1622 _N = UBSAN_CHECK_SUB (0, u);
1623 i = ABS_EXPR<_N>; */
1624 a
= build_zero_cst (lhstype
);
1625 b
= gimple_assign_rhs1 (stmt
);
1626 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1627 a
= make_ssa_name (lhstype
);
1628 gimple_call_set_lhs (g
, a
);
1629 gimple_set_location (g
, gimple_location (stmt
));
1630 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1631 gimple_assign_set_rhs1 (stmt
, a
);
1639 /* Instrument loads from (non-bitfield) bool and C++ enum values
1640 to check if the memory value is outside of the range of the valid
1644 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1646 gimple
*stmt
= gsi_stmt (*gsi
);
1647 tree rhs
= gimple_assign_rhs1 (stmt
);
1648 tree type
= TREE_TYPE (rhs
);
1649 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1651 if (TREE_CODE (type
) == BOOLEAN_TYPE
1652 && sanitize_flags_p (SANITIZE_BOOL
))
1654 minv
= boolean_false_node
;
1655 maxv
= boolean_true_node
;
1657 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1658 && sanitize_flags_p (SANITIZE_ENUM
)
1659 && TREE_TYPE (type
) != NULL_TREE
1660 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1661 && (TYPE_PRECISION (TREE_TYPE (type
))
1662 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1664 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1665 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1670 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1671 HOST_WIDE_INT bitsize
, bitpos
;
1674 int volatilep
= 0, reversep
, unsignedp
= 0;
1675 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1676 &unsignedp
, &reversep
, &volatilep
);
1677 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1679 if ((VAR_P (base
) && DECL_HARD_REGISTER (base
))
1680 || (bitpos
% modebitsize
) != 0
1681 || bitsize
!= modebitsize
1682 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1683 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1686 bool ends_bb
= stmt_ends_bb_p (stmt
);
1687 location_t loc
= gimple_location (stmt
);
1688 tree lhs
= gimple_assign_lhs (stmt
);
1689 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1690 tree atype
= reference_alias_ptr_type (rhs
);
1691 gimple
*g
= gimple_build_assign (make_ssa_name (ptype
),
1692 build_fold_addr_expr (rhs
));
1693 gimple_set_location (g
, loc
);
1694 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1695 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1696 build_int_cst (atype
, 0));
1697 tree urhs
= make_ssa_name (utype
);
1700 gimple_assign_set_lhs (stmt
, urhs
);
1701 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1702 gimple_set_location (g
, loc
);
1703 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1704 gsi_insert_on_edge_immediate (e
, g
);
1705 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1707 *gsi
= gsi_for_stmt (g
);
1712 g
= gimple_build_assign (urhs
, mem
);
1713 gimple_set_location (g
, loc
);
1714 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1716 minv
= fold_convert (utype
, minv
);
1717 maxv
= fold_convert (utype
, maxv
);
1718 if (!integer_zerop (minv
))
1720 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1721 gimple_set_location (g
, loc
);
1722 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1725 gimple_stmt_iterator gsi2
= *gsi
;
1726 basic_block then_bb
, fallthru_bb
;
1727 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1728 &then_bb
, &fallthru_bb
);
1729 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1730 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1731 NULL_TREE
, NULL_TREE
);
1732 gimple_set_location (g
, loc
);
1733 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1737 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1741 gsi2
= gsi_after_labels (then_bb
);
1742 if (flag_sanitize_undefined_trap_on_error
)
1743 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1746 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1747 ubsan_type_descriptor (type
), NULL_TREE
,
1749 data
= build_fold_addr_expr_loc (loc
, data
);
1750 enum built_in_function bcode
1751 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1752 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1753 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1754 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1755 tree fn
= builtin_decl_explicit (bcode
);
1757 tree val
= ubsan_encode_value (urhs
, UBSAN_ENCODE_VALUE_GIMPLE
);
1758 val
= force_gimple_operand_gsi (&gsi2
, val
, true, NULL_TREE
, true,
1760 g
= gimple_build_call (fn
, 2, data
, val
);
1762 gimple_set_location (g
, loc
);
1763 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1764 ubsan_create_edge (g
);
1765 *gsi
= gsi_for_stmt (stmt
);
1768 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1769 new style handlers. Libubsan uses heuristics to destinguish between old and
1770 new styles and relies on these properties for filename:
1772 a) Location's filename must not be NULL.
1773 b) Location's filename must not be equal to "".
1774 c) Location's filename must not be equal to "\1".
1775 d) First two bytes of filename must not contain '\xff' symbol. */
1778 ubsan_use_new_style_p (location_t loc
)
1780 if (loc
== UNKNOWN_LOCATION
)
1783 expanded_location xloc
= expand_location (loc
);
1784 if (xloc
.file
== NULL
|| strncmp (xloc
.file
, "\1", 2) == 0
1785 || xloc
.file
[0] == '\0' || xloc
.file
[0] == '\xff'
1786 || xloc
.file
[1] == '\xff')
1792 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1793 destination, EXPR is floating-point expression. */
1796 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
)
1798 tree expr_type
= TREE_TYPE (expr
);
1799 tree t
, tt
, fn
, min
, max
;
1800 machine_mode mode
= TYPE_MODE (expr_type
);
1801 int prec
= TYPE_PRECISION (type
);
1802 bool uns_p
= TYPE_UNSIGNED (type
);
1803 if (loc
== UNKNOWN_LOCATION
)
1804 loc
= input_location
;
1806 /* Float to integer conversion first truncates toward zero, so
1807 even signed char c = 127.875f; is not problematic.
1808 Therefore, we should complain only if EXPR is unordered or smaller
1809 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1810 TYPE_MAX_VALUE + 1.0. */
1811 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1813 /* For maximum, TYPE_MAX_VALUE might not be representable
1814 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1815 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1816 either representable or infinity. */
1817 REAL_VALUE_TYPE maxval
= dconst1
;
1818 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1819 real_convert (&maxval
, mode
, &maxval
);
1820 max
= build_real (expr_type
, maxval
);
1822 /* For unsigned, assume -1.0 is always representable. */
1824 min
= build_minus_one_cst (expr_type
);
1827 /* TYPE_MIN_VALUE is generally representable (or -inf),
1828 but TYPE_MIN_VALUE - 1.0 might not be. */
1829 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1830 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1831 real_convert (&minval
, mode
, &minval
);
1832 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1833 real_convert (&minval2
, mode
, &minval2
);
1834 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1835 && !real_isinf (&minval
))
1837 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1838 rounds to TYPE_MIN_VALUE, we need to subtract
1839 more. As REAL_MODE_FORMAT (mode)->p is the number
1840 of base digits, we want to subtract a number that
1841 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1842 times smaller than minval. */
1844 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1845 SET_REAL_EXP (&minval2
,
1846 REAL_EXP (&minval2
) + prec
- 1
1847 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1848 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1849 real_convert (&minval2
, mode
, &minval2
);
1851 min
= build_real (expr_type
, minval2
);
1854 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1856 /* For _Decimal128 up to 34 decimal digits, - sign,
1857 dot, e, exponent. */
1860 int p
= REAL_MODE_FORMAT (mode
)->p
;
1861 REAL_VALUE_TYPE maxval
, minval
;
1863 /* Use mpfr_snprintf rounding to compute the smallest
1864 representable decimal number greater or equal than
1865 1 << (prec - !uns_p). */
1866 mpfr_init2 (m
, prec
+ 2);
1867 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1868 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1869 decimal_real_from_string (&maxval
, buf
);
1870 max
= build_real (expr_type
, maxval
);
1872 /* For unsigned, assume -1.0 is always representable. */
1874 min
= build_minus_one_cst (expr_type
);
1877 /* Use mpfr_snprintf rounding to compute the largest
1878 representable decimal number less or equal than
1879 (-1 << (prec - 1)) - 1. */
1880 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1881 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1882 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1883 decimal_real_from_string (&minval
, buf
);
1884 min
= build_real (expr_type
, minval
);
1891 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1892 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1893 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
);
1894 if (integer_zerop (t
))
1897 if (flag_sanitize_undefined_trap_on_error
)
1898 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1901 location_t
*loc_ptr
= NULL
;
1902 unsigned num_locations
= 0;
1903 /* Figure out if we can propagate location to ubsan_data and use new
1904 style handlers in libubsan. */
1905 if (ubsan_use_new_style_p (loc
))
1910 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1911 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data",
1912 num_locations
, loc_ptr
,
1913 ubsan_type_descriptor (expr_type
),
1914 ubsan_type_descriptor (type
), NULL_TREE
,
1916 enum built_in_function bcode
1917 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1918 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1919 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1920 fn
= builtin_decl_explicit (bcode
);
1921 fn
= build_call_expr_loc (loc
, fn
, 2,
1922 build_fold_addr_expr_loc (loc
, data
),
1923 ubsan_encode_value (expr
));
1926 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1929 /* Instrument values passed to function arguments with nonnull attribute. */
1932 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1934 gimple
*stmt
= gsi_stmt (*gsi
);
1936 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1937 while for nonnull sanitization it is clear. */
1938 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1939 flag_delete_null_pointer_checks
= 1;
1940 loc
[0] = gimple_location (stmt
);
1941 loc
[1] = UNKNOWN_LOCATION
;
1942 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1944 tree arg
= gimple_call_arg (stmt
, i
);
1945 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1946 && infer_nonnull_range_by_attribute (stmt
, arg
))
1949 if (!is_gimple_val (arg
))
1951 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1952 gimple_set_location (g
, loc
[0]);
1953 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1954 arg
= gimple_assign_lhs (g
);
1957 basic_block then_bb
, fallthru_bb
;
1958 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1959 &then_bb
, &fallthru_bb
);
1960 g
= gimple_build_cond (EQ_EXPR
, arg
,
1961 build_zero_cst (TREE_TYPE (arg
)),
1962 NULL_TREE
, NULL_TREE
);
1963 gimple_set_location (g
, loc
[0]);
1964 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1966 *gsi
= gsi_after_labels (then_bb
);
1967 if (flag_sanitize_undefined_trap_on_error
)
1968 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1971 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1973 build_int_cst (integer_type_node
,
1976 data
= build_fold_addr_expr_loc (loc
[0], data
);
1977 enum built_in_function bcode
1978 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1979 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1980 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1981 tree fn
= builtin_decl_explicit (bcode
);
1983 g
= gimple_build_call (fn
, 1, data
);
1985 gimple_set_location (g
, loc
[0]);
1986 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1987 ubsan_create_edge (g
);
1989 *gsi
= gsi_for_stmt (stmt
);
1991 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1994 /* Instrument returns in functions with returns_nonnull attribute. */
1997 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1999 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
2001 tree arg
= gimple_return_retval (stmt
);
2002 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
2003 while for nonnull return sanitization it is clear. */
2004 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
2005 flag_delete_null_pointer_checks
= 1;
2006 loc
[0] = gimple_location (stmt
);
2007 loc
[1] = UNKNOWN_LOCATION
;
2009 && POINTER_TYPE_P (TREE_TYPE (arg
))
2010 && is_gimple_val (arg
)
2011 && infer_nonnull_range_by_attribute (stmt
, arg
))
2013 basic_block then_bb
, fallthru_bb
;
2014 *gsi
= create_cond_insert_point (gsi
, true, false, true,
2015 &then_bb
, &fallthru_bb
);
2016 gimple
*g
= gimple_build_cond (EQ_EXPR
, arg
,
2017 build_zero_cst (TREE_TYPE (arg
)),
2018 NULL_TREE
, NULL_TREE
);
2019 gimple_set_location (g
, loc
[0]);
2020 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
2022 *gsi
= gsi_after_labels (then_bb
);
2023 if (flag_sanitize_undefined_trap_on_error
)
2024 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
2027 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
2028 2, loc
, NULL_TREE
, NULL_TREE
);
2029 data
= build_fold_addr_expr_loc (loc
[0], data
);
2030 enum built_in_function bcode
2031 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
2032 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
2033 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
2034 tree fn
= builtin_decl_explicit (bcode
);
2036 g
= gimple_build_call (fn
, 1, data
);
2038 gimple_set_location (g
, loc
[0]);
2039 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
2040 ubsan_create_edge (g
);
2041 *gsi
= gsi_for_stmt (stmt
);
2043 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
2046 /* Instrument memory references. Here we check whether the pointer
2047 points to an out-of-bounds location. */
2050 instrument_object_size (gimple_stmt_iterator
*gsi
, tree t
, bool is_lhs
)
2052 gimple
*stmt
= gsi_stmt (*gsi
);
2053 location_t loc
= gimple_location (stmt
);
2055 tree index
= NULL_TREE
;
2056 HOST_WIDE_INT size_in_bytes
;
2058 type
= TREE_TYPE (t
);
2059 if (VOID_TYPE_P (type
))
2062 switch (TREE_CODE (t
))
2065 if (TREE_CODE (t
) == COMPONENT_REF
2066 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
2068 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
2069 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
2070 repr
, TREE_OPERAND (t
, 2));
2074 index
= TREE_OPERAND (t
, 1);
2086 size_in_bytes
= int_size_in_bytes (type
);
2087 if (size_in_bytes
<= 0)
2090 HOST_WIDE_INT bitsize
, bitpos
;
2093 int volatilep
= 0, reversep
, unsignedp
= 0;
2094 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
2095 &unsignedp
, &reversep
, &volatilep
);
2097 if (bitpos
% BITS_PER_UNIT
!= 0
2098 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
2101 bool decl_p
= DECL_P (inner
);
2105 if (DECL_REGISTER (inner
))
2109 else if (TREE_CODE (inner
) == MEM_REF
)
2110 base
= TREE_OPERAND (inner
, 0);
2113 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
2115 while (TREE_CODE (base
) == SSA_NAME
)
2117 gimple
*def_stmt
= SSA_NAME_DEF_STMT (base
);
2118 if (gimple_assign_ssa_name_copy_p (def_stmt
)
2119 || (gimple_assign_cast_p (def_stmt
)
2120 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
2121 || (is_gimple_assign (def_stmt
)
2122 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
2124 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
2125 if (TREE_CODE (rhs1
) == SSA_NAME
2126 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
2135 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
2139 tree base_addr
= base
;
2140 gimple
*bos_stmt
= NULL
;
2142 base_addr
= build1 (ADDR_EXPR
,
2143 build_pointer_type (TREE_TYPE (base
)), base
);
2144 unsigned HOST_WIDE_INT size
;
2145 if (compute_builtin_object_size (base_addr
, 0, &size
))
2146 sizet
= build_int_cst (sizetype
, size
);
2149 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
2150 loc
= input_location
;
2151 /* Generate __builtin_object_size call. */
2152 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
2153 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
2155 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
2157 /* If the call above didn't end up being an integer constant, go one
2158 statement back and get the __builtin_object_size stmt. Save it,
2159 we might need it later. */
2160 if (SSA_VAR_P (sizet
))
2163 bos_stmt
= gsi_stmt (*gsi
);
2165 /* Move on to where we were. */
2172 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
2174 /* ptr + sizeof (*ptr) - base */
2175 t
= fold_build2 (MINUS_EXPR
, sizetype
,
2176 fold_convert (pointer_sized_int_node
, ptr
),
2177 fold_convert (pointer_sized_int_node
, base_addr
));
2178 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
2180 /* Perhaps we can omit the check. */
2181 if (TREE_CODE (t
) == INTEGER_CST
2182 && TREE_CODE (sizet
) == INTEGER_CST
2183 && tree_int_cst_le (t
, sizet
))
2186 if (index
!= NULL_TREE
2187 && TREE_CODE (index
) == SSA_NAME
2188 && TREE_CODE (sizet
) == INTEGER_CST
)
2190 gimple
*def
= SSA_NAME_DEF_STMT (index
);
2191 if (is_gimple_assign (def
)
2192 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
2193 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
2195 tree cst
= gimple_assign_rhs2 (def
);
2196 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
2197 TYPE_SIZE_UNIT (type
));
2198 if (tree_int_cst_sgn (cst
) >= 0
2199 && tree_int_cst_lt (cst
, sz
))
2204 if (bos_stmt
&& gimple_call_builtin_p (bos_stmt
, BUILT_IN_OBJECT_SIZE
))
2205 ubsan_create_edge (bos_stmt
);
2207 /* We have to emit the check. */
2208 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
2210 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
2212 tree ckind
= build_int_cst (unsigned_char_type_node
,
2213 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
2214 gimple
*g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
2215 ptr
, t
, sizet
, ckind
);
2216 gimple_set_location (g
, loc
);
2217 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
2222 const pass_data pass_data_ubsan
=
2224 GIMPLE_PASS
, /* type */
2226 OPTGROUP_NONE
, /* optinfo_flags */
2227 TV_TREE_UBSAN
, /* tv_id */
2228 ( PROP_cfg
| PROP_ssa
), /* properties_required */
2229 0, /* properties_provided */
2230 0, /* properties_destroyed */
2231 0, /* todo_flags_start */
2232 TODO_update_ssa
, /* todo_flags_finish */
2235 class pass_ubsan
: public gimple_opt_pass
2238 pass_ubsan (gcc::context
*ctxt
)
2239 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
2242 /* opt_pass methods: */
2243 virtual bool gate (function
*)
2245 return sanitize_flags_p ((SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
2246 | SANITIZE_BOOL
| SANITIZE_ENUM
2247 | SANITIZE_ALIGNMENT
2248 | SANITIZE_NONNULL_ATTRIBUTE
2249 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
2250 | SANITIZE_OBJECT_SIZE
2251 | SANITIZE_POINTER_OVERFLOW
));
2254 virtual unsigned int execute (function
*);
2256 }; // class pass_ubsan
2259 pass_ubsan::execute (function
*fun
)
2262 gimple_stmt_iterator gsi
;
2263 unsigned int ret
= 0;
2265 initialize_sanitizer_builtins ();
2267 FOR_EACH_BB_FN (bb
, fun
)
2269 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
2271 gimple
*stmt
= gsi_stmt (gsi
);
2272 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
2278 if ((sanitize_flags_p (SANITIZE_SI_OVERFLOW
, fun
->decl
))
2279 && is_gimple_assign (stmt
))
2280 instrument_si_overflow (gsi
);
2282 if (sanitize_flags_p (SANITIZE_NULL
| SANITIZE_ALIGNMENT
, fun
->decl
))
2284 if (gimple_store_p (stmt
))
2285 instrument_null (gsi
, gimple_get_lhs (stmt
), true);
2286 if (gimple_assign_single_p (stmt
))
2287 instrument_null (gsi
, gimple_assign_rhs1 (stmt
), false);
2288 if (is_gimple_call (stmt
))
2290 unsigned args_num
= gimple_call_num_args (stmt
);
2291 for (unsigned i
= 0; i
< args_num
; ++i
)
2293 tree arg
= gimple_call_arg (stmt
, i
);
2294 if (is_gimple_reg (arg
) || is_gimple_min_invariant (arg
))
2296 instrument_null (gsi
, arg
, false);
2301 if (sanitize_flags_p (SANITIZE_BOOL
| SANITIZE_ENUM
, fun
->decl
)
2302 && gimple_assign_load_p (stmt
))
2304 instrument_bool_enum_load (&gsi
);
2305 bb
= gimple_bb (stmt
);
2308 if (sanitize_flags_p (SANITIZE_NONNULL_ATTRIBUTE
, fun
->decl
)
2309 && is_gimple_call (stmt
)
2310 && !gimple_call_internal_p (stmt
))
2312 instrument_nonnull_arg (&gsi
);
2313 bb
= gimple_bb (stmt
);
2316 if (sanitize_flags_p (SANITIZE_RETURNS_NONNULL_ATTRIBUTE
, fun
->decl
)
2317 && gimple_code (stmt
) == GIMPLE_RETURN
)
2319 instrument_nonnull_return (&gsi
);
2320 bb
= gimple_bb (stmt
);
2323 if (sanitize_flags_p (SANITIZE_OBJECT_SIZE
, fun
->decl
))
2325 if (gimple_store_p (stmt
))
2326 instrument_object_size (&gsi
, gimple_get_lhs (stmt
), true);
2327 if (gimple_assign_load_p (stmt
))
2328 instrument_object_size (&gsi
, gimple_assign_rhs1 (stmt
),
2330 if (is_gimple_call (stmt
))
2332 unsigned args_num
= gimple_call_num_args (stmt
);
2333 for (unsigned i
= 0; i
< args_num
; ++i
)
2335 tree arg
= gimple_call_arg (stmt
, i
);
2336 if (is_gimple_reg (arg
) || is_gimple_min_invariant (arg
))
2338 instrument_object_size (&gsi
, arg
, false);
2343 if (sanitize_flags_p (SANITIZE_POINTER_OVERFLOW
, fun
->decl
))
2345 if (is_gimple_assign (stmt
)
2346 && gimple_assign_rhs_code (stmt
) == POINTER_PLUS_EXPR
)
2347 instrument_pointer_overflow (&gsi
,
2348 gimple_assign_rhs1 (stmt
),
2349 gimple_assign_rhs2 (stmt
));
2350 if (gimple_store_p (stmt
))
2351 maybe_instrument_pointer_overflow (&gsi
,
2352 gimple_get_lhs (stmt
));
2353 if (gimple_assign_single_p (stmt
))
2354 maybe_instrument_pointer_overflow (&gsi
,
2355 gimple_assign_rhs1 (stmt
));
2356 if (is_gimple_call (stmt
))
2358 unsigned args_num
= gimple_call_num_args (stmt
);
2359 for (unsigned i
= 0; i
< args_num
; ++i
)
2361 tree arg
= gimple_call_arg (stmt
, i
);
2362 if (is_gimple_reg (arg
))
2364 maybe_instrument_pointer_overflow (&gsi
, arg
);
2371 if (gimple_purge_dead_eh_edges (bb
))
2372 ret
= TODO_cleanup_cfg
;
2380 make_pass_ubsan (gcc::context
*ctxt
)
2382 return new pass_ubsan (ctxt
);
2385 #include "gt-ubsan.h"