1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2015 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
27 #include "double-int.h"
35 #include "fold-const.h"
36 #include "stor-layout.h"
37 #include "stringpool.h"
39 #include "dominance.h"
42 #include "basic-block.h"
45 #include "plugin-api.h"
47 #include "hard-reg-set.h"
52 #include "tree-pass.h"
53 #include "tree-ssa-alias.h"
54 #include "tree-pretty-print.h"
55 #include "internal-fn.h"
56 #include "gimple-expr.h"
58 #include "gimple-iterator.h"
59 #include "gimple-ssa.h"
60 #include "gimple-walk.h"
66 #include "c-family/c-common.h"
69 #include "tree-ssanames.h"
71 #include "gimplify-me.h"
76 #include "tree-object-size.h"
79 /* Map from a tree to a VAR_DECL tree. */
81 struct GTY((for_user
)) tree_type_map
{
82 struct tree_map_base type
;
86 struct tree_type_map_cache_hasher
: ggc_cache_hasher
<tree_type_map
*>
88 static inline hashval_t
89 hash (tree_type_map
*t
)
91 return TYPE_UID (t
->type
.from
);
95 equal (tree_type_map
*a
, tree_type_map
*b
)
97 return a
->type
.from
== b
->type
.from
;
101 handle_cache_entry (tree_type_map
*&m
)
103 extern void gt_ggc_mx (tree_type_map
*&);
104 if (m
== HTAB_EMPTY_ENTRY
|| m
== HTAB_DELETED_ENTRY
)
106 else if (ggc_marked_p (m
->type
.from
))
109 m
= static_cast<tree_type_map
*> (HTAB_DELETED_ENTRY
);
114 hash_table
<tree_type_map_cache_hasher
> *decl_tree_for_type
;
116 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
119 decl_for_type_lookup (tree type
)
121 /* If the hash table is not initialized yet, create it now. */
122 if (decl_tree_for_type
== NULL
)
125 = hash_table
<tree_type_map_cache_hasher
>::create_ggc (10);
126 /* That also means we don't have to bother with the lookup. */
130 struct tree_type_map
*h
, in
;
133 h
= decl_tree_for_type
->find_with_hash (&in
, TYPE_UID (type
));
134 return h
? h
->decl
: NULL_TREE
;
137 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
140 decl_for_type_insert (tree type
, tree decl
)
142 struct tree_type_map
*h
;
144 h
= ggc_alloc
<tree_type_map
> ();
147 *decl_tree_for_type
->find_slot_with_hash (h
, TYPE_UID (type
), INSERT
) = h
;
150 /* Helper routine, which encodes a value in the pointer_sized_int_node.
151 Arguments with precision <= POINTER_SIZE are passed directly,
152 the rest is passed by reference. T is a value we are to encode.
153 IN_EXPAND_P is true if this function is called during expansion. */
156 ubsan_encode_value (tree t
, bool in_expand_p
)
158 tree type
= TREE_TYPE (t
);
159 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
160 if (bitsize
<= POINTER_SIZE
)
161 switch (TREE_CODE (type
))
166 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
169 tree itype
= build_nonstandard_integer_type (bitsize
, true);
170 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
171 return fold_convert (pointer_sized_int_node
, t
);
178 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
180 /* The reason for this is that we don't want to pessimize
181 code by making vars unnecessarily addressable. */
182 tree var
= create_tmp_var (type
);
183 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
187 = assign_stack_temp_for_type (TYPE_MODE (type
),
188 GET_MODE_SIZE (TYPE_MODE (type
)),
190 SET_DECL_RTL (var
, mem
);
191 expand_assignment (var
, t
, false);
192 return build_fold_addr_expr (var
);
194 t
= build_fold_addr_expr (var
);
195 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
198 return build_fold_addr_expr (t
);
202 /* Cached ubsan_get_type_descriptor_type () return value. */
203 static GTY(()) tree ubsan_type_descriptor_type
;
206 struct __ubsan_type_descriptor
208 unsigned short __typekind;
209 unsigned short __typeinfo;
215 ubsan_get_type_descriptor_type (void)
217 static const char *field_names
[3]
218 = { "__typekind", "__typeinfo", "__typename" };
221 if (ubsan_type_descriptor_type
)
222 return ubsan_type_descriptor_type
;
224 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
225 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
227 ret
= make_node (RECORD_TYPE
);
228 for (int i
= 0; i
< 3; i
++)
230 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
231 get_identifier (field_names
[i
]),
232 (i
== 2) ? flex_arr_type
233 : short_unsigned_type_node
);
234 DECL_CONTEXT (fields
[i
]) = ret
;
236 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
238 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
239 get_identifier ("__ubsan_type_descriptor"),
241 DECL_IGNORED_P (type_decl
) = 1;
242 DECL_ARTIFICIAL (type_decl
) = 1;
243 TYPE_FIELDS (ret
) = fields
[0];
244 TYPE_NAME (ret
) = type_decl
;
245 TYPE_STUB_DECL (ret
) = type_decl
;
247 ubsan_type_descriptor_type
= ret
;
251 /* Cached ubsan_get_source_location_type () return value. */
252 static GTY(()) tree ubsan_source_location_type
;
255 struct __ubsan_source_location
257 const char *__filename;
259 unsigned int __column;
264 ubsan_get_source_location_type (void)
266 static const char *field_names
[3]
267 = { "__filename", "__line", "__column" };
269 if (ubsan_source_location_type
)
270 return ubsan_source_location_type
;
272 tree const_char_type
= build_qualified_type (char_type_node
,
275 ret
= make_node (RECORD_TYPE
);
276 for (int i
= 0; i
< 3; i
++)
278 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
279 get_identifier (field_names
[i
]),
280 (i
== 0) ? build_pointer_type (const_char_type
)
281 : unsigned_type_node
);
282 DECL_CONTEXT (fields
[i
]) = ret
;
284 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
286 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
287 get_identifier ("__ubsan_source_location"),
289 DECL_IGNORED_P (type_decl
) = 1;
290 DECL_ARTIFICIAL (type_decl
) = 1;
291 TYPE_FIELDS (ret
) = fields
[0];
292 TYPE_NAME (ret
) = type_decl
;
293 TYPE_STUB_DECL (ret
) = type_decl
;
295 ubsan_source_location_type
= ret
;
299 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
300 type with its fields filled from a location_t LOC. */
303 ubsan_source_location (location_t loc
)
305 expanded_location xloc
;
306 tree type
= ubsan_get_source_location_type ();
308 xloc
= expand_location (loc
);
310 if (xloc
.file
== NULL
)
312 str
= build_int_cst (ptr_type_node
, 0);
318 /* Fill in the values from LOC. */
319 size_t len
= strlen (xloc
.file
);
320 str
= build_string (len
+ 1, xloc
.file
);
321 TREE_TYPE (str
) = build_array_type (char_type_node
,
322 build_index_type (size_int (len
)));
323 TREE_READONLY (str
) = 1;
324 TREE_STATIC (str
) = 1;
325 str
= build_fold_addr_expr (str
);
327 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
328 build_int_cst (unsigned_type_node
,
329 xloc
.line
), NULL_TREE
,
330 build_int_cst (unsigned_type_node
,
332 TREE_CONSTANT (ctor
) = 1;
333 TREE_STATIC (ctor
) = 1;
338 /* This routine returns a magic number for TYPE. */
340 static unsigned short
341 get_ubsan_type_info_for_type (tree type
)
343 gcc_assert (TYPE_SIZE (type
) && tree_fits_uhwi_p (TYPE_SIZE (type
)));
344 if (TREE_CODE (type
) == REAL_TYPE
)
345 return tree_to_uhwi (TYPE_SIZE (type
));
346 else if (INTEGRAL_TYPE_P (type
))
348 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
349 gcc_assert (prec
!= -1);
350 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
356 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
357 descriptor. It first looks into the hash table; if not found,
358 create the VAR_DECL, put it into the hash table and return the
359 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
360 an enum controlling how we want to print the type. */
363 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
365 /* See through any typedefs. */
366 type
= TYPE_MAIN_VARIANT (type
);
368 tree decl
= decl_for_type_lookup (type
);
369 /* It is possible that some of the earlier created DECLs were found
370 unused, in that case they weren't emitted and varpool_node::get
371 returns NULL node on them. But now we really need them. Thus,
373 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
374 return build_fold_addr_expr (decl
);
376 tree dtype
= ubsan_get_type_descriptor_type ();
378 const char *tname
= NULL
;
380 unsigned char deref_depth
= 0;
381 unsigned short tkind
, tinfo
;
383 /* Get the name of the type, or the name of the pointer type. */
384 if (pstyle
== UBSAN_PRINT_POINTER
)
386 gcc_assert (POINTER_TYPE_P (type
));
387 type2
= TREE_TYPE (type
);
389 /* Remove any '*' operators from TYPE. */
390 while (POINTER_TYPE_P (type2
))
391 deref_depth
++, type2
= TREE_TYPE (type2
);
393 if (TREE_CODE (type2
) == METHOD_TYPE
)
394 type2
= TYPE_METHOD_BASETYPE (type2
);
397 /* If an array, get its type. */
398 type2
= strip_array_types (type2
);
400 if (pstyle
== UBSAN_PRINT_ARRAY
)
402 while (POINTER_TYPE_P (type2
))
403 deref_depth
++, type2
= TREE_TYPE (type2
);
406 if (TYPE_NAME (type2
) != NULL
)
408 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
409 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
410 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
411 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
415 /* We weren't able to determine the type name. */
418 /* Decorate the type name with '', '*', "struct", or "union". */
419 pretty_name
= (char *) alloca (strlen (tname
) + 16 + deref_depth
);
420 if (pstyle
== UBSAN_PRINT_POINTER
)
422 int pos
= sprintf (pretty_name
, "'%s%s%s%s%s%s%s",
423 TYPE_VOLATILE (type2
) ? "volatile " : "",
424 TYPE_READONLY (type2
) ? "const " : "",
425 TYPE_RESTRICT (type2
) ? "restrict " : "",
426 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
427 TREE_CODE (type2
) == RECORD_TYPE
429 : TREE_CODE (type2
) == UNION_TYPE
430 ? "union " : "", tname
,
431 deref_depth
== 0 ? "" : " ");
432 while (deref_depth
-- > 0)
433 pretty_name
[pos
++] = '*';
434 pretty_name
[pos
++] = '\'';
435 pretty_name
[pos
] = '\0';
437 else if (pstyle
== UBSAN_PRINT_ARRAY
)
439 /* Pretty print the array dimensions. */
440 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
442 int pos
= sprintf (pretty_name
, "'%s ", tname
);
443 while (deref_depth
-- > 0)
444 pretty_name
[pos
++] = '*';
445 while (TREE_CODE (t
) == ARRAY_TYPE
)
447 pretty_name
[pos
++] = '[';
448 tree dom
= TYPE_DOMAIN (t
);
449 if (dom
&& TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
450 pos
+= sprintf (&pretty_name
[pos
], HOST_WIDE_INT_PRINT_DEC
,
451 tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1);
453 /* ??? We can't determine the variable name; print VLA unspec. */
454 pretty_name
[pos
++] = '*';
455 pretty_name
[pos
++] = ']';
458 pretty_name
[pos
++] = '\'';
459 pretty_name
[pos
] = '\0';
461 /* Save the tree with stripped types. */
465 sprintf (pretty_name
, "'%s'", tname
);
467 switch (TREE_CODE (type
))
475 /* FIXME: libubsan right now only supports float, double and
476 long double type formats. */
477 if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
)
478 || TYPE_MODE (type
) == TYPE_MODE (double_type_node
)
479 || TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
488 tinfo
= get_ubsan_type_info_for_type (type
);
490 /* Create a new VAR_DECL of type descriptor. */
492 static unsigned int type_var_id_num
;
493 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
494 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
496 TREE_STATIC (decl
) = 1;
497 TREE_PUBLIC (decl
) = 0;
498 DECL_ARTIFICIAL (decl
) = 1;
499 DECL_IGNORED_P (decl
) = 1;
500 DECL_EXTERNAL (decl
) = 0;
502 size_t len
= strlen (pretty_name
);
503 tree str
= build_string (len
+ 1, pretty_name
);
504 TREE_TYPE (str
) = build_array_type (char_type_node
,
505 build_index_type (size_int (len
)));
506 TREE_READONLY (str
) = 1;
507 TREE_STATIC (str
) = 1;
508 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
509 build_int_cst (short_unsigned_type_node
,
511 build_int_cst (short_unsigned_type_node
,
512 tinfo
), NULL_TREE
, str
);
513 TREE_CONSTANT (ctor
) = 1;
514 TREE_STATIC (ctor
) = 1;
515 DECL_INITIAL (decl
) = ctor
;
516 varpool_node::finalize_decl (decl
);
518 /* Save the VAR_DECL into the hash table. */
519 decl_for_type_insert (type
, decl
);
521 return build_fold_addr_expr (decl
);
524 /* Create a structure for the ubsan library. NAME is a name of the new
525 structure. LOCCNT is number of locations, PLOC points to array of
526 locations. The arguments in ... are of __ubsan_type_descriptor type
527 and there are at most two of them, followed by NULL_TREE, followed
528 by optional extra arguments and another NULL_TREE. */
531 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
536 vec
<tree
, va_gc
> *saved_args
= NULL
;
540 /* Firstly, create a pointer to type descriptor type. */
541 tree td_type
= ubsan_get_type_descriptor_type ();
542 td_type
= build_pointer_type (td_type
);
544 /* Create the structure type. */
545 ret
= make_node (RECORD_TYPE
);
546 for (j
= 0; j
< loccnt
; j
++)
548 gcc_checking_assert (i
< 2);
549 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
550 ubsan_get_source_location_type ());
551 DECL_CONTEXT (fields
[i
]) = ret
;
553 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
557 va_start (args
, ploc
);
558 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
559 i
++, t
= va_arg (args
, tree
))
561 gcc_checking_assert (i
< 4);
562 /* Save the tree arguments for later use. */
563 vec_safe_push (saved_args
, t
);
564 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
566 DECL_CONTEXT (fields
[i
]) = ret
;
568 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
571 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
572 i
++, t
= va_arg (args
, tree
))
574 gcc_checking_assert (i
< 6);
575 /* Save the tree arguments for later use. */
576 vec_safe_push (saved_args
, t
);
577 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
579 DECL_CONTEXT (fields
[i
]) = ret
;
581 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
585 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
586 get_identifier (name
), ret
);
587 DECL_IGNORED_P (type_decl
) = 1;
588 DECL_ARTIFICIAL (type_decl
) = 1;
589 TYPE_FIELDS (ret
) = fields
[0];
590 TYPE_NAME (ret
) = type_decl
;
591 TYPE_STUB_DECL (ret
) = type_decl
;
594 /* Now, fill in the type. */
596 static unsigned int ubsan_var_id_num
;
597 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
598 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
600 TREE_STATIC (var
) = 1;
601 TREE_PUBLIC (var
) = 0;
602 DECL_ARTIFICIAL (var
) = 1;
603 DECL_IGNORED_P (var
) = 1;
604 DECL_EXTERNAL (var
) = 0;
606 vec
<constructor_elt
, va_gc
> *v
;
608 tree ctor
= build_constructor (ret
, v
);
610 /* If desirable, set the __ubsan_source_location element. */
611 for (j
= 0; j
< loccnt
; j
++)
613 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
614 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
617 size_t nelts
= vec_safe_length (saved_args
);
618 for (i
= 0; i
< nelts
; i
++)
620 t
= (*saved_args
)[i
];
621 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
624 TREE_CONSTANT (ctor
) = 1;
625 TREE_STATIC (ctor
) = 1;
626 DECL_INITIAL (var
) = ctor
;
627 varpool_node::finalize_decl (var
);
632 /* Instrument the __builtin_unreachable call. We just call the libubsan
636 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
639 location_t loc
= gimple_location (gsi_stmt (*gsi
));
641 if (flag_sanitize_undefined_trap_on_error
)
642 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
645 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
646 NULL_TREE
, NULL_TREE
);
647 data
= build_fold_addr_expr_loc (loc
, data
);
649 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
650 g
= gimple_build_call (fn
, 1, data
);
652 gimple_set_location (g
, loc
);
653 gsi_replace (gsi
, g
, false);
657 /* Return true if T is a call to a libubsan routine. */
660 is_ubsan_builtin_p (tree t
)
662 return TREE_CODE (t
) == FUNCTION_DECL
663 && DECL_BUILT_IN_CLASS (t
) == BUILT_IN_NORMAL
664 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
665 "__builtin___ubsan_", 18) == 0;
668 /* Expand the UBSAN_BOUNDS special builtin function. */
671 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
673 gimple stmt
= gsi_stmt (*gsi
);
674 location_t loc
= gimple_location (stmt
);
675 gcc_assert (gimple_call_num_args (stmt
) == 3);
677 /* Pick up the arguments of the UBSAN_BOUNDS call. */
678 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
679 tree index
= gimple_call_arg (stmt
, 1);
680 tree orig_index_type
= TREE_TYPE (index
);
681 tree bound
= gimple_call_arg (stmt
, 2);
683 gimple_stmt_iterator gsi_orig
= *gsi
;
685 /* Create condition "if (index > bound)". */
686 basic_block then_bb
, fallthru_bb
;
687 gimple_stmt_iterator cond_insert_point
688 = create_cond_insert_point (gsi
, false, false, true,
689 &then_bb
, &fallthru_bb
);
690 index
= fold_convert (TREE_TYPE (bound
), index
);
691 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
693 false, GSI_NEW_STMT
);
694 gimple g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
695 gimple_set_location (g
, loc
);
696 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
698 /* Generate __ubsan_handle_out_of_bounds call. */
699 *gsi
= gsi_after_labels (then_bb
);
700 if (flag_sanitize_undefined_trap_on_error
)
701 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
705 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
706 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
707 ubsan_type_descriptor (orig_index_type
),
708 NULL_TREE
, NULL_TREE
);
709 data
= build_fold_addr_expr_loc (loc
, data
);
710 enum built_in_function bcode
711 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
712 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
713 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
714 tree fn
= builtin_decl_explicit (bcode
);
715 tree val
= force_gimple_operand_gsi (gsi
, ubsan_encode_value (index
),
716 true, NULL_TREE
, true,
718 g
= gimple_build_call (fn
, 2, data
, val
);
720 gimple_set_location (g
, loc
);
721 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
723 /* Get rid of the UBSAN_BOUNDS call from the IR. */
724 unlink_stmt_vdef (stmt
);
725 gsi_remove (&gsi_orig
, true);
727 /* Point GSI to next logical statement. */
728 *gsi
= gsi_start_bb (fallthru_bb
);
732 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
733 argument which is a constant, because the middle-end treats pointer
734 conversions as useless and therefore the type of the first argument
735 could be changed to any other pointer type. */
738 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
740 gimple_stmt_iterator gsi
= *gsip
;
741 gimple stmt
= gsi_stmt (gsi
);
742 location_t loc
= gimple_location (stmt
);
743 gcc_assert (gimple_call_num_args (stmt
) == 3);
744 tree ptr
= gimple_call_arg (stmt
, 0);
745 tree ckind
= gimple_call_arg (stmt
, 1);
746 tree align
= gimple_call_arg (stmt
, 2);
747 tree check_align
= NULL_TREE
;
750 basic_block cur_bb
= gsi_bb (gsi
);
753 if (!integer_zerop (align
))
755 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
756 if (compare_tree_int (align
, ptralign
) == 1)
758 check_align
= make_ssa_name (pointer_sized_int_node
);
759 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
760 gimple_set_location (g
, loc
);
761 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
764 check_null
= (flag_sanitize
& SANITIZE_NULL
) != 0;
766 if (check_align
== NULL_TREE
&& !check_null
)
768 gsi_remove (gsip
, true);
769 /* Unlink the UBSAN_NULLs vops before replacing it. */
770 unlink_stmt_vdef (stmt
);
774 /* Split the original block holding the pointer dereference. */
775 edge e
= split_block (cur_bb
, stmt
);
777 /* Get a hold on the 'condition block', the 'then block' and the
779 basic_block cond_bb
= e
->src
;
780 basic_block fallthru_bb
= e
->dest
;
781 basic_block then_bb
= create_empty_bb (cond_bb
);
782 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
783 loops_state_set (LOOPS_NEED_FIXUP
);
785 /* Make an edge coming from the 'cond block' into the 'then block';
786 this edge is unlikely taken, so set up the probability accordingly. */
787 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
788 e
->probability
= PROB_VERY_UNLIKELY
;
790 /* Connect 'then block' with the 'else block'. This is needed
791 as the ubsan routines we call in the 'then block' are not noreturn.
792 The 'then block' only has one outcoming edge. */
793 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
795 /* Set up the fallthrough basic block. */
796 e
= find_edge (cond_bb
, fallthru_bb
);
797 e
->flags
= EDGE_FALSE_VALUE
;
798 e
->count
= cond_bb
->count
;
799 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
801 /* Update dominance info for the newly created then_bb; note that
802 fallthru_bb's dominance info has already been updated by
804 if (dom_info_available_p (CDI_DOMINATORS
))
805 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
807 /* Put the ubsan builtin call into the newly created BB. */
808 if (flag_sanitize_undefined_trap_on_error
)
809 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
812 enum built_in_function bcode
813 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
814 | (check_null
? SANITIZE_NULL
: 0)))
815 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
816 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
817 tree fn
= builtin_decl_implicit (bcode
);
819 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
820 ubsan_type_descriptor (TREE_TYPE (ckind
),
821 UBSAN_PRINT_POINTER
),
824 fold_convert (unsigned_char_type_node
, ckind
),
826 data
= build_fold_addr_expr_loc (loc
, data
);
827 g
= gimple_build_call (fn
, 2, data
,
828 check_align
? check_align
829 : build_zero_cst (pointer_sized_int_node
));
831 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
832 gimple_set_location (g
, loc
);
833 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
835 /* Unlink the UBSAN_NULLs vops before replacing it. */
836 unlink_stmt_vdef (stmt
);
840 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
841 NULL_TREE
, NULL_TREE
);
842 gimple_set_location (g
, loc
);
844 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
845 gsi_replace (&gsi
, g
, false);
852 /* Split the block with the condition again. */
853 e
= split_block (cond_bb
, stmt
);
854 basic_block cond1_bb
= e
->src
;
855 basic_block cond2_bb
= e
->dest
;
857 /* Make an edge coming from the 'cond1 block' into the 'then block';
858 this edge is unlikely taken, so set up the probability
860 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
861 e
->probability
= PROB_VERY_UNLIKELY
;
863 /* Set up the fallthrough basic block. */
864 e
= find_edge (cond1_bb
, cond2_bb
);
865 e
->flags
= EDGE_FALSE_VALUE
;
866 e
->count
= cond1_bb
->count
;
867 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
869 /* Update dominance info. */
870 if (dom_info_available_p (CDI_DOMINATORS
))
872 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
873 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
876 gsi2
= gsi_start_bb (cond2_bb
);
879 tree mask
= build_int_cst (pointer_sized_int_node
,
880 tree_to_uhwi (align
) - 1);
881 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
882 BIT_AND_EXPR
, check_align
, mask
);
883 gimple_set_location (g
, loc
);
885 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
887 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
889 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
890 build_int_cst (pointer_sized_int_node
, 0),
891 NULL_TREE
, NULL_TREE
);
892 gimple_set_location (g
, loc
);
894 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
896 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
897 gsi_replace (&gsi
, g
, false);
902 /* Expand UBSAN_OBJECT_SIZE internal call. */
905 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
907 gimple stmt
= gsi_stmt (*gsi
);
908 location_t loc
= gimple_location (stmt
);
909 gcc_assert (gimple_call_num_args (stmt
) == 4);
911 tree ptr
= gimple_call_arg (stmt
, 0);
912 tree offset
= gimple_call_arg (stmt
, 1);
913 tree size
= gimple_call_arg (stmt
, 2);
914 tree ckind
= gimple_call_arg (stmt
, 3);
915 gimple_stmt_iterator gsi_orig
= *gsi
;
918 /* See if we can discard the check. */
919 if (TREE_CODE (size
) != INTEGER_CST
920 || integer_all_onesp (size
))
921 /* Yes, __builtin_object_size couldn't determine the
925 /* if (offset > objsize) */
926 basic_block then_bb
, fallthru_bb
;
927 gimple_stmt_iterator cond_insert_point
928 = create_cond_insert_point (gsi
, false, false, true,
929 &then_bb
, &fallthru_bb
);
930 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
931 gimple_set_location (g
, loc
);
932 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
934 /* Generate __ubsan_handle_type_mismatch call. */
935 *gsi
= gsi_after_labels (then_bb
);
936 if (flag_sanitize_undefined_trap_on_error
)
937 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
941 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
942 ubsan_type_descriptor (TREE_TYPE (ptr
),
943 UBSAN_PRINT_POINTER
),
945 build_zero_cst (pointer_sized_int_node
),
948 data
= build_fold_addr_expr_loc (loc
, data
);
949 enum built_in_function bcode
950 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
951 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
952 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
953 tree p
= make_ssa_name (pointer_sized_int_node
);
954 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
955 gimple_set_location (g
, loc
);
956 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
957 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
959 gimple_set_location (g
, loc
);
960 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
962 /* Point GSI to next logical statement. */
963 *gsi
= gsi_start_bb (fallthru_bb
);
966 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
967 unlink_stmt_vdef (stmt
);
968 gsi_remove (&gsi_orig
, true);
969 return gsi_end_p (*gsi
);
972 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
973 whether the pointer is on the left hand side of the assignment. */
976 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
979 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
980 unsigned int align
= 0;
981 if (flag_sanitize
& SANITIZE_ALIGNMENT
)
983 align
= min_align_of_type (TREE_TYPE (base
));
987 if (align
== 0 && (flag_sanitize
& SANITIZE_NULL
) == 0)
989 tree t
= TREE_OPERAND (base
, 0);
990 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
992 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t
))) && mem
!= base
)
993 ikind
= UBSAN_MEMBER_ACCESS
;
994 tree kind
= build_int_cst (TREE_TYPE (t
), ikind
);
995 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
996 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
997 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
998 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
1001 /* Perform the pointer instrumentation. */
1004 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
1006 gimple stmt
= gsi_stmt (gsi
);
1007 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1008 tree base
= get_base_address (t
);
1009 const enum tree_code code
= TREE_CODE (base
);
1011 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1012 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1015 /* Build an ubsan builtin call for the signed-integer-overflow
1016 sanitization. CODE says what kind of builtin are we building,
1017 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1018 are operands of the binary operation. */
1021 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1024 if (flag_sanitize_undefined_trap_on_error
)
1025 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1027 tree data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1028 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1030 enum built_in_function fn_code
;
1035 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1036 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1037 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1040 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1041 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1042 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1045 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1046 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1047 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1050 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1051 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1052 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1057 tree fn
= builtin_decl_explicit (fn_code
);
1058 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1059 build_fold_addr_expr_loc (loc
, data
),
1060 ubsan_encode_value (op0
, true),
1061 op1
? ubsan_encode_value (op1
, true)
1065 /* Perform the signed integer instrumentation. GSI is the iterator
1066 pointing at statement we are trying to instrument. */
1069 instrument_si_overflow (gimple_stmt_iterator gsi
)
1071 gimple stmt
= gsi_stmt (gsi
);
1072 tree_code code
= gimple_assign_rhs_code (stmt
);
1073 tree lhs
= gimple_assign_lhs (stmt
);
1074 tree lhstype
= TREE_TYPE (lhs
);
1078 /* If this is not a signed operation, don't instrument anything here.
1079 Also punt on bit-fields. */
1080 if (!INTEGRAL_TYPE_P (lhstype
)
1081 || TYPE_OVERFLOW_WRAPS (lhstype
)
1082 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
1093 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1094 a
= gimple_assign_rhs1 (stmt
);
1095 b
= gimple_assign_rhs2 (stmt
);
1096 g
= gimple_build_call_internal (code
== PLUS_EXPR
1097 ? IFN_UBSAN_CHECK_ADD
1098 : code
== MINUS_EXPR
1099 ? IFN_UBSAN_CHECK_SUB
1100 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1101 gimple_call_set_lhs (g
, lhs
);
1102 gsi_replace (&gsi
, g
, false);
1105 /* Represent i = -u;
1107 i = UBSAN_CHECK_SUB (0, u); */
1108 a
= build_int_cst (lhstype
, 0);
1109 b
= gimple_assign_rhs1 (stmt
);
1110 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1111 gimple_call_set_lhs (g
, lhs
);
1112 gsi_replace (&gsi
, g
, false);
1115 /* Transform i = ABS_EXPR<u>;
1117 _N = UBSAN_CHECK_SUB (0, u);
1118 i = ABS_EXPR<_N>; */
1119 a
= build_int_cst (lhstype
, 0);
1120 b
= gimple_assign_rhs1 (stmt
);
1121 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1122 a
= make_ssa_name (lhstype
);
1123 gimple_call_set_lhs (g
, a
);
1124 gimple_set_location (g
, gimple_location (stmt
));
1125 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1126 gimple_assign_set_rhs1 (stmt
, a
);
1134 /* Instrument loads from (non-bitfield) bool and C++ enum values
1135 to check if the memory value is outside of the range of the valid
1139 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1141 gimple stmt
= gsi_stmt (*gsi
);
1142 tree rhs
= gimple_assign_rhs1 (stmt
);
1143 tree type
= TREE_TYPE (rhs
);
1144 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1146 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
1148 minv
= boolean_false_node
;
1149 maxv
= boolean_true_node
;
1151 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1152 && (flag_sanitize
& SANITIZE_ENUM
)
1153 && TREE_TYPE (type
) != NULL_TREE
1154 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1155 && (TYPE_PRECISION (TREE_TYPE (type
))
1156 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1158 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1159 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1164 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1165 HOST_WIDE_INT bitsize
, bitpos
;
1168 int volatilep
= 0, unsignedp
= 0;
1169 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1170 &unsignedp
, &volatilep
, false);
1171 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1173 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
1174 || (bitpos
% modebitsize
) != 0
1175 || bitsize
!= modebitsize
1176 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1177 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1180 bool can_throw
= stmt_could_throw_p (stmt
);
1181 location_t loc
= gimple_location (stmt
);
1182 tree lhs
= gimple_assign_lhs (stmt
);
1183 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1184 tree atype
= reference_alias_ptr_type (rhs
);
1185 gimple g
= gimple_build_assign (make_ssa_name (ptype
),
1186 build_fold_addr_expr (rhs
));
1187 gimple_set_location (g
, loc
);
1188 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1189 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1190 build_int_cst (atype
, 0));
1191 tree urhs
= make_ssa_name (utype
);
1194 gimple_assign_set_lhs (stmt
, urhs
);
1195 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1196 gimple_set_location (g
, loc
);
1197 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1198 gsi_insert_on_edge_immediate (e
, g
);
1199 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1201 *gsi
= gsi_for_stmt (g
);
1206 g
= gimple_build_assign (urhs
, mem
);
1207 gimple_set_location (g
, loc
);
1208 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1210 minv
= fold_convert (utype
, minv
);
1211 maxv
= fold_convert (utype
, maxv
);
1212 if (!integer_zerop (minv
))
1214 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1215 gimple_set_location (g
, loc
);
1216 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1219 gimple_stmt_iterator gsi2
= *gsi
;
1220 basic_block then_bb
, fallthru_bb
;
1221 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1222 &then_bb
, &fallthru_bb
);
1223 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1224 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1225 NULL_TREE
, NULL_TREE
);
1226 gimple_set_location (g
, loc
);
1227 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1231 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1235 gsi2
= gsi_after_labels (then_bb
);
1236 if (flag_sanitize_undefined_trap_on_error
)
1237 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1240 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1241 ubsan_type_descriptor (type
), NULL_TREE
,
1243 data
= build_fold_addr_expr_loc (loc
, data
);
1244 enum built_in_function bcode
1245 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1246 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1247 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1248 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1249 tree fn
= builtin_decl_explicit (bcode
);
1251 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
1252 true, NULL_TREE
, true,
1254 g
= gimple_build_call (fn
, 2, data
, val
);
1256 gimple_set_location (g
, loc
);
1257 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1258 *gsi
= gsi_for_stmt (stmt
);
1261 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1262 destination, EXPR is floating-point expression. ARG is what to pass
1263 the libubsan call as value, often EXPR itself. */
1266 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
, tree arg
)
1268 tree expr_type
= TREE_TYPE (expr
);
1269 tree t
, tt
, fn
, min
, max
;
1270 machine_mode mode
= TYPE_MODE (expr_type
);
1271 int prec
= TYPE_PRECISION (type
);
1272 bool uns_p
= TYPE_UNSIGNED (type
);
1274 /* Float to integer conversion first truncates toward zero, so
1275 even signed char c = 127.875f; is not problematic.
1276 Therefore, we should complain only if EXPR is unordered or smaller
1277 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1278 TYPE_MAX_VALUE + 1.0. */
1279 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1281 /* For maximum, TYPE_MAX_VALUE might not be representable
1282 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1283 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1284 either representable or infinity. */
1285 REAL_VALUE_TYPE maxval
= dconst1
;
1286 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1287 real_convert (&maxval
, mode
, &maxval
);
1288 max
= build_real (expr_type
, maxval
);
1290 /* For unsigned, assume -1.0 is always representable. */
1292 min
= build_minus_one_cst (expr_type
);
1295 /* TYPE_MIN_VALUE is generally representable (or -inf),
1296 but TYPE_MIN_VALUE - 1.0 might not be. */
1297 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1298 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1299 real_convert (&minval
, mode
, &minval
);
1300 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1301 real_convert (&minval2
, mode
, &minval2
);
1302 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1303 && !real_isinf (&minval
))
1305 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1306 rounds to TYPE_MIN_VALUE, we need to subtract
1307 more. As REAL_MODE_FORMAT (mode)->p is the number
1308 of base digits, we want to subtract a number that
1309 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1310 times smaller than minval. */
1312 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1313 SET_REAL_EXP (&minval2
,
1314 REAL_EXP (&minval2
) + prec
- 1
1315 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1316 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1317 real_convert (&minval2
, mode
, &minval2
);
1319 min
= build_real (expr_type
, minval2
);
1322 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1324 /* For _Decimal128 up to 34 decimal digits, - sign,
1325 dot, e, exponent. */
1328 int p
= REAL_MODE_FORMAT (mode
)->p
;
1329 REAL_VALUE_TYPE maxval
, minval
;
1331 /* Use mpfr_snprintf rounding to compute the smallest
1332 representable decimal number greater or equal than
1333 1 << (prec - !uns_p). */
1334 mpfr_init2 (m
, prec
+ 2);
1335 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1336 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1337 decimal_real_from_string (&maxval
, buf
);
1338 max
= build_real (expr_type
, maxval
);
1340 /* For unsigned, assume -1.0 is always representable. */
1342 min
= build_minus_one_cst (expr_type
);
1345 /* Use mpfr_snprintf rounding to compute the largest
1346 representable decimal number less or equal than
1347 (-1 << (prec - 1)) - 1. */
1348 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1349 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1350 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1351 decimal_real_from_string (&minval
, buf
);
1352 min
= build_real (expr_type
, minval
);
1359 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1360 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1361 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
);
1362 if (integer_zerop (t
))
1365 if (flag_sanitize_undefined_trap_on_error
)
1366 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1369 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1370 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1371 NULL
, ubsan_type_descriptor (expr_type
),
1372 ubsan_type_descriptor (type
), NULL_TREE
,
1374 enum built_in_function bcode
1375 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1376 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1377 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1378 fn
= builtin_decl_explicit (bcode
);
1379 fn
= build_call_expr_loc (loc
, fn
, 2,
1380 build_fold_addr_expr_loc (loc
, data
),
1381 ubsan_encode_value (arg
, false));
1384 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1387 /* Instrument values passed to function arguments with nonnull attribute. */
1390 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1392 gimple stmt
= gsi_stmt (*gsi
);
1394 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1395 while for nonnull sanitization it is clear. */
1396 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1397 flag_delete_null_pointer_checks
= 1;
1398 loc
[0] = gimple_location (stmt
);
1399 loc
[1] = UNKNOWN_LOCATION
;
1400 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1402 tree arg
= gimple_call_arg (stmt
, i
);
1403 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1404 && infer_nonnull_range (stmt
, arg
, false, true))
1407 if (!is_gimple_val (arg
))
1409 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1410 gimple_set_location (g
, loc
[0]);
1411 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1412 arg
= gimple_assign_lhs (g
);
1415 basic_block then_bb
, fallthru_bb
;
1416 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1417 &then_bb
, &fallthru_bb
);
1418 g
= gimple_build_cond (EQ_EXPR
, arg
,
1419 build_zero_cst (TREE_TYPE (arg
)),
1420 NULL_TREE
, NULL_TREE
);
1421 gimple_set_location (g
, loc
[0]);
1422 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1424 *gsi
= gsi_after_labels (then_bb
);
1425 if (flag_sanitize_undefined_trap_on_error
)
1426 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1429 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1431 build_int_cst (integer_type_node
,
1434 data
= build_fold_addr_expr_loc (loc
[0], data
);
1435 enum built_in_function bcode
1436 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1437 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1438 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1439 tree fn
= builtin_decl_explicit (bcode
);
1441 g
= gimple_build_call (fn
, 1, data
);
1443 gimple_set_location (g
, loc
[0]);
1444 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1446 *gsi
= gsi_for_stmt (stmt
);
1448 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1451 /* Instrument returns in functions with returns_nonnull attribute. */
1454 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1456 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
1458 tree arg
= gimple_return_retval (stmt
);
1459 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1460 while for nonnull return sanitization it is clear. */
1461 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1462 flag_delete_null_pointer_checks
= 1;
1463 loc
[0] = gimple_location (stmt
);
1464 loc
[1] = UNKNOWN_LOCATION
;
1466 && POINTER_TYPE_P (TREE_TYPE (arg
))
1467 && is_gimple_val (arg
)
1468 && infer_nonnull_range (stmt
, arg
, false, true))
1470 basic_block then_bb
, fallthru_bb
;
1471 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1472 &then_bb
, &fallthru_bb
);
1473 gimple g
= gimple_build_cond (EQ_EXPR
, arg
,
1474 build_zero_cst (TREE_TYPE (arg
)),
1475 NULL_TREE
, NULL_TREE
);
1476 gimple_set_location (g
, loc
[0]);
1477 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1479 *gsi
= gsi_after_labels (then_bb
);
1480 if (flag_sanitize_undefined_trap_on_error
)
1481 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1484 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
1485 2, loc
, NULL_TREE
, NULL_TREE
);
1486 data
= build_fold_addr_expr_loc (loc
[0], data
);
1487 enum built_in_function bcode
1488 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1489 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1490 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
1491 tree fn
= builtin_decl_explicit (bcode
);
1493 g
= gimple_build_call (fn
, 1, data
);
1495 gimple_set_location (g
, loc
[0]);
1496 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1497 *gsi
= gsi_for_stmt (stmt
);
1499 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1502 /* Instrument memory references. Here we check whether the pointer
1503 points to an out-of-bounds location. */
1506 instrument_object_size (gimple_stmt_iterator
*gsi
, bool is_lhs
)
1508 gimple stmt
= gsi_stmt (*gsi
);
1509 location_t loc
= gimple_location (stmt
);
1510 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1512 tree index
= NULL_TREE
;
1513 HOST_WIDE_INT size_in_bytes
;
1515 type
= TREE_TYPE (t
);
1516 if (VOID_TYPE_P (type
))
1519 switch (TREE_CODE (t
))
1522 if (TREE_CODE (t
) == COMPONENT_REF
1523 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
1525 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
1526 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
1531 index
= TREE_OPERAND (t
, 1);
1543 size_in_bytes
= int_size_in_bytes (type
);
1544 if (size_in_bytes
<= 0)
1547 HOST_WIDE_INT bitsize
, bitpos
;
1550 int volatilep
= 0, unsignedp
= 0;
1551 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1552 &unsignedp
, &volatilep
, false);
1554 if (bitpos
% BITS_PER_UNIT
!= 0
1555 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
1558 bool decl_p
= DECL_P (inner
);
1562 else if (TREE_CODE (inner
) == MEM_REF
)
1563 base
= TREE_OPERAND (inner
, 0);
1566 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
1568 while (TREE_CODE (base
) == SSA_NAME
)
1570 gimple def_stmt
= SSA_NAME_DEF_STMT (base
);
1571 if (gimple_assign_ssa_name_copy_p (def_stmt
)
1572 || (gimple_assign_cast_p (def_stmt
)
1573 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
1574 || (is_gimple_assign (def_stmt
)
1575 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
1577 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
1578 if (TREE_CODE (rhs1
) == SSA_NAME
1579 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
1588 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1592 tree base_addr
= base
;
1594 base_addr
= build1 (ADDR_EXPR
,
1595 build_pointer_type (TREE_TYPE (base
)), base
);
1596 unsigned HOST_WIDE_INT size
= compute_builtin_object_size (base_addr
, 0);
1597 if (size
!= (unsigned HOST_WIDE_INT
) -1)
1598 sizet
= build_int_cst (sizetype
, size
);
1601 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
1602 loc
= input_location
;
1603 /* Generate __builtin_object_size call. */
1604 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
1605 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
1607 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
1613 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1615 /* ptr + sizeof (*ptr) - base */
1616 t
= fold_build2 (MINUS_EXPR
, sizetype
,
1617 fold_convert (pointer_sized_int_node
, ptr
),
1618 fold_convert (pointer_sized_int_node
, base_addr
));
1619 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
1621 /* Perhaps we can omit the check. */
1622 if (TREE_CODE (t
) == INTEGER_CST
1623 && TREE_CODE (sizet
) == INTEGER_CST
1624 && tree_int_cst_le (t
, sizet
))
1627 if (index
!= NULL_TREE
1628 && TREE_CODE (index
) == SSA_NAME
1629 && TREE_CODE (sizet
) == INTEGER_CST
)
1631 gimple def
= SSA_NAME_DEF_STMT (index
);
1632 if (is_gimple_assign (def
)
1633 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
1634 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
1636 tree cst
= gimple_assign_rhs2 (def
);
1637 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
1638 TYPE_SIZE_UNIT (type
));
1639 if (tree_int_cst_sgn (cst
) >= 0
1640 && tree_int_cst_lt (cst
, sz
))
1645 /* Nope. Emit the check. */
1646 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1648 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
1650 tree ckind
= build_int_cst (unsigned_char_type_node
,
1651 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
1652 gimple g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
1653 ptr
, t
, sizet
, ckind
);
1654 gimple_set_location (g
, loc
);
1655 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1658 /* True if we want to play UBSan games in the current function. */
1661 do_ubsan_in_current_function ()
1663 return (current_function_decl
!= NULL_TREE
1664 && !lookup_attribute ("no_sanitize_undefined",
1665 DECL_ATTRIBUTES (current_function_decl
)));
1670 const pass_data pass_data_ubsan
=
1672 GIMPLE_PASS
, /* type */
1674 OPTGROUP_NONE
, /* optinfo_flags */
1675 TV_TREE_UBSAN
, /* tv_id */
1676 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1677 0, /* properties_provided */
1678 0, /* properties_destroyed */
1679 0, /* todo_flags_start */
1680 TODO_update_ssa
, /* todo_flags_finish */
1683 class pass_ubsan
: public gimple_opt_pass
1686 pass_ubsan (gcc::context
*ctxt
)
1687 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1690 /* opt_pass methods: */
1691 virtual bool gate (function
*)
1693 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1694 | SANITIZE_BOOL
| SANITIZE_ENUM
1695 | SANITIZE_ALIGNMENT
1696 | SANITIZE_NONNULL_ATTRIBUTE
1697 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1698 | SANITIZE_OBJECT_SIZE
)
1699 && do_ubsan_in_current_function ();
1702 virtual unsigned int execute (function
*);
1704 }; // class pass_ubsan
1707 pass_ubsan::execute (function
*fun
)
1710 gimple_stmt_iterator gsi
;
1712 initialize_sanitizer_builtins ();
1714 FOR_EACH_BB_FN (bb
, fun
)
1716 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1718 gimple stmt
= gsi_stmt (gsi
);
1719 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
1725 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
1726 && is_gimple_assign (stmt
))
1727 instrument_si_overflow (gsi
);
1729 if (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1731 if (gimple_store_p (stmt
))
1732 instrument_null (gsi
, true);
1733 if (gimple_assign_load_p (stmt
))
1734 instrument_null (gsi
, false);
1737 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
1738 && gimple_assign_load_p (stmt
))
1740 instrument_bool_enum_load (&gsi
);
1741 bb
= gimple_bb (stmt
);
1744 if ((flag_sanitize
& SANITIZE_NONNULL_ATTRIBUTE
)
1745 && is_gimple_call (stmt
)
1746 && !gimple_call_internal_p (stmt
))
1748 instrument_nonnull_arg (&gsi
);
1749 bb
= gimple_bb (stmt
);
1752 if ((flag_sanitize
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1753 && gimple_code (stmt
) == GIMPLE_RETURN
)
1755 instrument_nonnull_return (&gsi
);
1756 bb
= gimple_bb (stmt
);
1759 if (flag_sanitize
& SANITIZE_OBJECT_SIZE
)
1761 if (gimple_store_p (stmt
))
1762 instrument_object_size (&gsi
, true);
1763 if (gimple_assign_load_p (stmt
))
1764 instrument_object_size (&gsi
, false);
1776 make_pass_ubsan (gcc::context
*ctxt
)
1778 return new pass_ubsan (ctxt
);
1781 #include "gt-ubsan.h"