1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2014 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"
25 #include "stor-layout.h"
26 #include "stringpool.h"
28 #include "dominance.h"
31 #include "basic-block.h"
34 #include "plugin-api.h"
40 #include "hard-reg-set.h"
45 #include "tree-pass.h"
46 #include "tree-ssa-alias.h"
47 #include "tree-pretty-print.h"
48 #include "internal-fn.h"
49 #include "gimple-expr.h"
51 #include "gimple-iterator.h"
52 #include "gimple-ssa.h"
53 #include "gimple-walk.h"
59 #include "c-family/c-common.h"
62 #include "tree-ssanames.h"
64 #include "gimplify-me.h"
69 #include "tree-object-size.h"
72 /* Map from a tree to a VAR_DECL tree. */
74 struct GTY((for_user
)) tree_type_map
{
75 struct tree_map_base type
;
79 struct tree_type_map_cache_hasher
: ggc_cache_hasher
<tree_type_map
*>
81 static inline hashval_t
82 hash (tree_type_map
*t
)
84 return TYPE_UID (t
->type
.from
);
88 equal (tree_type_map
*a
, tree_type_map
*b
)
90 return a
->type
.from
== b
->type
.from
;
94 handle_cache_entry (tree_type_map
*&m
)
96 extern void gt_ggc_mx (tree_type_map
*&);
97 if (m
== HTAB_EMPTY_ENTRY
|| m
== HTAB_DELETED_ENTRY
)
99 else if (ggc_marked_p (m
->type
.from
))
102 m
= static_cast<tree_type_map
*> (HTAB_DELETED_ENTRY
);
107 hash_table
<tree_type_map_cache_hasher
> *decl_tree_for_type
;
109 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
112 decl_for_type_lookup (tree type
)
114 /* If the hash table is not initialized yet, create it now. */
115 if (decl_tree_for_type
== NULL
)
118 = hash_table
<tree_type_map_cache_hasher
>::create_ggc (10);
119 /* That also means we don't have to bother with the lookup. */
123 struct tree_type_map
*h
, in
;
126 h
= decl_tree_for_type
->find_with_hash (&in
, TYPE_UID (type
));
127 return h
? h
->decl
: NULL_TREE
;
130 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
133 decl_for_type_insert (tree type
, tree decl
)
135 struct tree_type_map
*h
;
137 h
= ggc_alloc
<tree_type_map
> ();
140 *decl_tree_for_type
->find_slot_with_hash (h
, TYPE_UID (type
), INSERT
) = h
;
143 /* Helper routine, which encodes a value in the pointer_sized_int_node.
144 Arguments with precision <= POINTER_SIZE are passed directly,
145 the rest is passed by reference. T is a value we are to encode.
146 IN_EXPAND_P is true if this function is called during expansion. */
149 ubsan_encode_value (tree t
, bool in_expand_p
)
151 tree type
= TREE_TYPE (t
);
152 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
153 if (bitsize
<= POINTER_SIZE
)
154 switch (TREE_CODE (type
))
159 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
162 tree itype
= build_nonstandard_integer_type (bitsize
, true);
163 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
164 return fold_convert (pointer_sized_int_node
, t
);
171 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
173 /* The reason for this is that we don't want to pessimize
174 code by making vars unnecessarily addressable. */
175 tree var
= create_tmp_var (type
);
176 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
180 = assign_stack_temp_for_type (TYPE_MODE (type
),
181 GET_MODE_SIZE (TYPE_MODE (type
)),
183 SET_DECL_RTL (var
, mem
);
184 expand_assignment (var
, t
, false);
185 return build_fold_addr_expr (var
);
187 t
= build_fold_addr_expr (var
);
188 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
191 return build_fold_addr_expr (t
);
195 /* Cached ubsan_get_type_descriptor_type () return value. */
196 static GTY(()) tree ubsan_type_descriptor_type
;
199 struct __ubsan_type_descriptor
201 unsigned short __typekind;
202 unsigned short __typeinfo;
208 ubsan_get_type_descriptor_type (void)
210 static const char *field_names
[3]
211 = { "__typekind", "__typeinfo", "__typename" };
214 if (ubsan_type_descriptor_type
)
215 return ubsan_type_descriptor_type
;
217 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
218 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
220 ret
= make_node (RECORD_TYPE
);
221 for (int i
= 0; i
< 3; i
++)
223 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
224 get_identifier (field_names
[i
]),
225 (i
== 2) ? flex_arr_type
226 : short_unsigned_type_node
);
227 DECL_CONTEXT (fields
[i
]) = ret
;
229 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
231 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
232 get_identifier ("__ubsan_type_descriptor"),
234 DECL_IGNORED_P (type_decl
) = 1;
235 DECL_ARTIFICIAL (type_decl
) = 1;
236 TYPE_FIELDS (ret
) = fields
[0];
237 TYPE_NAME (ret
) = type_decl
;
238 TYPE_STUB_DECL (ret
) = type_decl
;
240 ubsan_type_descriptor_type
= ret
;
244 /* Cached ubsan_get_source_location_type () return value. */
245 static GTY(()) tree ubsan_source_location_type
;
248 struct __ubsan_source_location
250 const char *__filename;
252 unsigned int __column;
257 ubsan_get_source_location_type (void)
259 static const char *field_names
[3]
260 = { "__filename", "__line", "__column" };
262 if (ubsan_source_location_type
)
263 return ubsan_source_location_type
;
265 tree const_char_type
= build_qualified_type (char_type_node
,
268 ret
= make_node (RECORD_TYPE
);
269 for (int i
= 0; i
< 3; i
++)
271 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
272 get_identifier (field_names
[i
]),
273 (i
== 0) ? build_pointer_type (const_char_type
)
274 : unsigned_type_node
);
275 DECL_CONTEXT (fields
[i
]) = ret
;
277 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
279 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
280 get_identifier ("__ubsan_source_location"),
282 DECL_IGNORED_P (type_decl
) = 1;
283 DECL_ARTIFICIAL (type_decl
) = 1;
284 TYPE_FIELDS (ret
) = fields
[0];
285 TYPE_NAME (ret
) = type_decl
;
286 TYPE_STUB_DECL (ret
) = type_decl
;
288 ubsan_source_location_type
= ret
;
292 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
293 type with its fields filled from a location_t LOC. */
296 ubsan_source_location (location_t loc
)
298 expanded_location xloc
;
299 tree type
= ubsan_get_source_location_type ();
301 xloc
= expand_location (loc
);
303 if (xloc
.file
== NULL
)
305 str
= build_int_cst (ptr_type_node
, 0);
311 /* Fill in the values from LOC. */
312 size_t len
= strlen (xloc
.file
);
313 str
= build_string (len
+ 1, xloc
.file
);
314 TREE_TYPE (str
) = build_array_type (char_type_node
,
315 build_index_type (size_int (len
)));
316 TREE_READONLY (str
) = 1;
317 TREE_STATIC (str
) = 1;
318 str
= build_fold_addr_expr (str
);
320 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
321 build_int_cst (unsigned_type_node
,
322 xloc
.line
), NULL_TREE
,
323 build_int_cst (unsigned_type_node
,
325 TREE_CONSTANT (ctor
) = 1;
326 TREE_STATIC (ctor
) = 1;
331 /* This routine returns a magic number for TYPE. */
333 static unsigned short
334 get_ubsan_type_info_for_type (tree type
)
336 gcc_assert (TYPE_SIZE (type
) && tree_fits_uhwi_p (TYPE_SIZE (type
)));
337 if (TREE_CODE (type
) == REAL_TYPE
)
338 return tree_to_uhwi (TYPE_SIZE (type
));
339 else if (INTEGRAL_TYPE_P (type
))
341 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
342 gcc_assert (prec
!= -1);
343 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
349 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
350 descriptor. It first looks into the hash table; if not found,
351 create the VAR_DECL, put it into the hash table and return the
352 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
353 an enum controlling how we want to print the type. */
356 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
358 /* See through any typedefs. */
359 type
= TYPE_MAIN_VARIANT (type
);
361 tree decl
= decl_for_type_lookup (type
);
362 /* It is possible that some of the earlier created DECLs were found
363 unused, in that case they weren't emitted and varpool_node::get
364 returns NULL node on them. But now we really need them. Thus,
366 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
367 return build_fold_addr_expr (decl
);
369 tree dtype
= ubsan_get_type_descriptor_type ();
371 const char *tname
= NULL
;
373 unsigned char deref_depth
= 0;
374 unsigned short tkind
, tinfo
;
376 /* Get the name of the type, or the name of the pointer type. */
377 if (pstyle
== UBSAN_PRINT_POINTER
)
379 gcc_assert (POINTER_TYPE_P (type
));
380 type2
= TREE_TYPE (type
);
382 /* Remove any '*' operators from TYPE. */
383 while (POINTER_TYPE_P (type2
))
384 deref_depth
++, type2
= TREE_TYPE (type2
);
386 if (TREE_CODE (type2
) == METHOD_TYPE
)
387 type2
= TYPE_METHOD_BASETYPE (type2
);
390 /* If an array, get its type. */
391 type2
= strip_array_types (type2
);
393 if (pstyle
== UBSAN_PRINT_ARRAY
)
395 while (POINTER_TYPE_P (type2
))
396 deref_depth
++, type2
= TREE_TYPE (type2
);
399 if (TYPE_NAME (type2
) != NULL
)
401 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
402 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
403 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
404 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
408 /* We weren't able to determine the type name. */
411 /* Decorate the type name with '', '*', "struct", or "union". */
412 pretty_name
= (char *) alloca (strlen (tname
) + 16 + deref_depth
);
413 if (pstyle
== UBSAN_PRINT_POINTER
)
415 int pos
= sprintf (pretty_name
, "'%s%s%s%s%s%s%s",
416 TYPE_VOLATILE (type2
) ? "volatile " : "",
417 TYPE_READONLY (type2
) ? "const " : "",
418 TYPE_RESTRICT (type2
) ? "restrict " : "",
419 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
420 TREE_CODE (type2
) == RECORD_TYPE
422 : TREE_CODE (type2
) == UNION_TYPE
423 ? "union " : "", tname
,
424 deref_depth
== 0 ? "" : " ");
425 while (deref_depth
-- > 0)
426 pretty_name
[pos
++] = '*';
427 pretty_name
[pos
++] = '\'';
428 pretty_name
[pos
] = '\0';
430 else if (pstyle
== UBSAN_PRINT_ARRAY
)
432 /* Pretty print the array dimensions. */
433 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
435 int pos
= sprintf (pretty_name
, "'%s ", tname
);
436 while (deref_depth
-- > 0)
437 pretty_name
[pos
++] = '*';
438 while (TREE_CODE (t
) == ARRAY_TYPE
)
440 pretty_name
[pos
++] = '[';
441 tree dom
= TYPE_DOMAIN (t
);
442 if (dom
&& TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
443 pos
+= sprintf (&pretty_name
[pos
], HOST_WIDE_INT_PRINT_DEC
,
444 tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1);
446 /* ??? We can't determine the variable name; print VLA unspec. */
447 pretty_name
[pos
++] = '*';
448 pretty_name
[pos
++] = ']';
451 pretty_name
[pos
++] = '\'';
452 pretty_name
[pos
] = '\0';
454 /* Save the tree with stripped types. */
458 sprintf (pretty_name
, "'%s'", tname
);
460 switch (TREE_CODE (type
))
468 /* FIXME: libubsan right now only supports float, double and
469 long double type formats. */
470 if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
)
471 || TYPE_MODE (type
) == TYPE_MODE (double_type_node
)
472 || TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
481 tinfo
= get_ubsan_type_info_for_type (type
);
483 /* Create a new VAR_DECL of type descriptor. */
485 static unsigned int type_var_id_num
;
486 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
487 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
489 TREE_STATIC (decl
) = 1;
490 TREE_PUBLIC (decl
) = 0;
491 DECL_ARTIFICIAL (decl
) = 1;
492 DECL_IGNORED_P (decl
) = 1;
493 DECL_EXTERNAL (decl
) = 0;
495 size_t len
= strlen (pretty_name
);
496 tree str
= build_string (len
+ 1, pretty_name
);
497 TREE_TYPE (str
) = build_array_type (char_type_node
,
498 build_index_type (size_int (len
)));
499 TREE_READONLY (str
) = 1;
500 TREE_STATIC (str
) = 1;
501 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
502 build_int_cst (short_unsigned_type_node
,
504 build_int_cst (short_unsigned_type_node
,
505 tinfo
), NULL_TREE
, str
);
506 TREE_CONSTANT (ctor
) = 1;
507 TREE_STATIC (ctor
) = 1;
508 DECL_INITIAL (decl
) = ctor
;
509 varpool_node::finalize_decl (decl
);
511 /* Save the VAR_DECL into the hash table. */
512 decl_for_type_insert (type
, decl
);
514 return build_fold_addr_expr (decl
);
517 /* Create a structure for the ubsan library. NAME is a name of the new
518 structure. LOCCNT is number of locations, PLOC points to array of
519 locations. The arguments in ... are of __ubsan_type_descriptor type
520 and there are at most two of them, followed by NULL_TREE, followed
521 by optional extra arguments and another NULL_TREE. */
524 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
529 vec
<tree
, va_gc
> *saved_args
= NULL
;
533 /* Firstly, create a pointer to type descriptor type. */
534 tree td_type
= ubsan_get_type_descriptor_type ();
535 td_type
= build_pointer_type (td_type
);
537 /* Create the structure type. */
538 ret
= make_node (RECORD_TYPE
);
539 for (j
= 0; j
< loccnt
; j
++)
541 gcc_checking_assert (i
< 2);
542 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
543 ubsan_get_source_location_type ());
544 DECL_CONTEXT (fields
[i
]) = ret
;
546 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
550 va_start (args
, ploc
);
551 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
552 i
++, t
= va_arg (args
, tree
))
554 gcc_checking_assert (i
< 4);
555 /* Save the tree arguments for later use. */
556 vec_safe_push (saved_args
, t
);
557 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
559 DECL_CONTEXT (fields
[i
]) = ret
;
561 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
564 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
565 i
++, t
= va_arg (args
, tree
))
567 gcc_checking_assert (i
< 6);
568 /* Save the tree arguments for later use. */
569 vec_safe_push (saved_args
, t
);
570 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
572 DECL_CONTEXT (fields
[i
]) = ret
;
574 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
578 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
579 get_identifier (name
), ret
);
580 DECL_IGNORED_P (type_decl
) = 1;
581 DECL_ARTIFICIAL (type_decl
) = 1;
582 TYPE_FIELDS (ret
) = fields
[0];
583 TYPE_NAME (ret
) = type_decl
;
584 TYPE_STUB_DECL (ret
) = type_decl
;
587 /* Now, fill in the type. */
589 static unsigned int ubsan_var_id_num
;
590 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
591 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
593 TREE_STATIC (var
) = 1;
594 TREE_PUBLIC (var
) = 0;
595 DECL_ARTIFICIAL (var
) = 1;
596 DECL_IGNORED_P (var
) = 1;
597 DECL_EXTERNAL (var
) = 0;
599 vec
<constructor_elt
, va_gc
> *v
;
601 tree ctor
= build_constructor (ret
, v
);
603 /* If desirable, set the __ubsan_source_location element. */
604 for (j
= 0; j
< loccnt
; j
++)
606 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
607 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
610 size_t nelts
= vec_safe_length (saved_args
);
611 for (i
= 0; i
< nelts
; i
++)
613 t
= (*saved_args
)[i
];
614 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
617 TREE_CONSTANT (ctor
) = 1;
618 TREE_STATIC (ctor
) = 1;
619 DECL_INITIAL (var
) = ctor
;
620 varpool_node::finalize_decl (var
);
625 /* Instrument the __builtin_unreachable call. We just call the libubsan
629 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
632 location_t loc
= gimple_location (gsi_stmt (*gsi
));
634 if (flag_sanitize_undefined_trap_on_error
)
635 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
638 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
639 NULL_TREE
, NULL_TREE
);
640 data
= build_fold_addr_expr_loc (loc
, data
);
642 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
643 g
= gimple_build_call (fn
, 1, data
);
645 gimple_set_location (g
, loc
);
646 gsi_replace (gsi
, g
, false);
650 /* Return true if T is a call to a libubsan routine. */
653 is_ubsan_builtin_p (tree t
)
655 return TREE_CODE (t
) == FUNCTION_DECL
656 && DECL_BUILT_IN_CLASS (t
) == BUILT_IN_NORMAL
657 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
658 "__builtin___ubsan_", 18) == 0;
661 /* Expand the UBSAN_BOUNDS special builtin function. */
664 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
666 gimple stmt
= gsi_stmt (*gsi
);
667 location_t loc
= gimple_location (stmt
);
668 gcc_assert (gimple_call_num_args (stmt
) == 3);
670 /* Pick up the arguments of the UBSAN_BOUNDS call. */
671 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
672 tree index
= gimple_call_arg (stmt
, 1);
673 tree orig_index_type
= TREE_TYPE (index
);
674 tree bound
= gimple_call_arg (stmt
, 2);
676 gimple_stmt_iterator gsi_orig
= *gsi
;
678 /* Create condition "if (index > bound)". */
679 basic_block then_bb
, fallthru_bb
;
680 gimple_stmt_iterator cond_insert_point
681 = create_cond_insert_point (gsi
, false, false, true,
682 &then_bb
, &fallthru_bb
);
683 index
= fold_convert (TREE_TYPE (bound
), index
);
684 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
686 false, GSI_NEW_STMT
);
687 gimple g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
688 gimple_set_location (g
, loc
);
689 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
691 /* Generate __ubsan_handle_out_of_bounds call. */
692 *gsi
= gsi_after_labels (then_bb
);
693 if (flag_sanitize_undefined_trap_on_error
)
694 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
698 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
699 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
700 ubsan_type_descriptor (orig_index_type
),
701 NULL_TREE
, NULL_TREE
);
702 data
= build_fold_addr_expr_loc (loc
, data
);
703 enum built_in_function bcode
704 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
705 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
706 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
707 tree fn
= builtin_decl_explicit (bcode
);
708 tree val
= force_gimple_operand_gsi (gsi
, ubsan_encode_value (index
),
709 true, NULL_TREE
, true,
711 g
= gimple_build_call (fn
, 2, data
, val
);
713 gimple_set_location (g
, loc
);
714 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
716 /* Get rid of the UBSAN_BOUNDS call from the IR. */
717 unlink_stmt_vdef (stmt
);
718 gsi_remove (&gsi_orig
, true);
720 /* Point GSI to next logical statement. */
721 *gsi
= gsi_start_bb (fallthru_bb
);
725 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
726 argument which is a constant, because the middle-end treats pointer
727 conversions as useless and therefore the type of the first argument
728 could be changed to any other pointer type. */
731 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
733 gimple_stmt_iterator gsi
= *gsip
;
734 gimple stmt
= gsi_stmt (gsi
);
735 location_t loc
= gimple_location (stmt
);
736 gcc_assert (gimple_call_num_args (stmt
) == 3);
737 tree ptr
= gimple_call_arg (stmt
, 0);
738 tree ckind
= gimple_call_arg (stmt
, 1);
739 tree align
= gimple_call_arg (stmt
, 2);
740 tree check_align
= NULL_TREE
;
743 basic_block cur_bb
= gsi_bb (gsi
);
746 if (!integer_zerop (align
))
748 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
749 if (compare_tree_int (align
, ptralign
) == 1)
751 check_align
= make_ssa_name (pointer_sized_int_node
);
752 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
753 gimple_set_location (g
, loc
);
754 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
757 check_null
= (flag_sanitize
& SANITIZE_NULL
) != 0;
759 if (check_align
== NULL_TREE
&& !check_null
)
761 gsi_remove (gsip
, true);
762 /* Unlink the UBSAN_NULLs vops before replacing it. */
763 unlink_stmt_vdef (stmt
);
767 /* Split the original block holding the pointer dereference. */
768 edge e
= split_block (cur_bb
, stmt
);
770 /* Get a hold on the 'condition block', the 'then block' and the
772 basic_block cond_bb
= e
->src
;
773 basic_block fallthru_bb
= e
->dest
;
774 basic_block then_bb
= create_empty_bb (cond_bb
);
775 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
776 loops_state_set (LOOPS_NEED_FIXUP
);
778 /* Make an edge coming from the 'cond block' into the 'then block';
779 this edge is unlikely taken, so set up the probability accordingly. */
780 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
781 e
->probability
= PROB_VERY_UNLIKELY
;
783 /* Connect 'then block' with the 'else block'. This is needed
784 as the ubsan routines we call in the 'then block' are not noreturn.
785 The 'then block' only has one outcoming edge. */
786 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
788 /* Set up the fallthrough basic block. */
789 e
= find_edge (cond_bb
, fallthru_bb
);
790 e
->flags
= EDGE_FALSE_VALUE
;
791 e
->count
= cond_bb
->count
;
792 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
794 /* Update dominance info for the newly created then_bb; note that
795 fallthru_bb's dominance info has already been updated by
797 if (dom_info_available_p (CDI_DOMINATORS
))
798 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
800 /* Put the ubsan builtin call into the newly created BB. */
801 if (flag_sanitize_undefined_trap_on_error
)
802 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
805 enum built_in_function bcode
806 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
807 | (check_null
? SANITIZE_NULL
: 0)))
808 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
809 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
810 tree fn
= builtin_decl_implicit (bcode
);
812 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
813 ubsan_type_descriptor (TREE_TYPE (ckind
),
814 UBSAN_PRINT_POINTER
),
817 fold_convert (unsigned_char_type_node
, ckind
),
819 data
= build_fold_addr_expr_loc (loc
, data
);
820 g
= gimple_build_call (fn
, 2, data
,
821 check_align
? check_align
822 : build_zero_cst (pointer_sized_int_node
));
824 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
825 gimple_set_location (g
, loc
);
826 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
828 /* Unlink the UBSAN_NULLs vops before replacing it. */
829 unlink_stmt_vdef (stmt
);
833 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
834 NULL_TREE
, NULL_TREE
);
835 gimple_set_location (g
, loc
);
837 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
838 gsi_replace (&gsi
, g
, false);
845 /* Split the block with the condition again. */
846 e
= split_block (cond_bb
, stmt
);
847 basic_block cond1_bb
= e
->src
;
848 basic_block cond2_bb
= e
->dest
;
850 /* Make an edge coming from the 'cond1 block' into the 'then block';
851 this edge is unlikely taken, so set up the probability
853 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
854 e
->probability
= PROB_VERY_UNLIKELY
;
856 /* Set up the fallthrough basic block. */
857 e
= find_edge (cond1_bb
, cond2_bb
);
858 e
->flags
= EDGE_FALSE_VALUE
;
859 e
->count
= cond1_bb
->count
;
860 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
862 /* Update dominance info. */
863 if (dom_info_available_p (CDI_DOMINATORS
))
865 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
866 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
869 gsi2
= gsi_start_bb (cond2_bb
);
872 tree mask
= build_int_cst (pointer_sized_int_node
,
873 tree_to_uhwi (align
) - 1);
874 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
875 BIT_AND_EXPR
, check_align
, mask
);
876 gimple_set_location (g
, loc
);
878 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
880 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
882 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
883 build_int_cst (pointer_sized_int_node
, 0),
884 NULL_TREE
, NULL_TREE
);
885 gimple_set_location (g
, loc
);
887 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
889 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
890 gsi_replace (&gsi
, g
, false);
895 /* Expand UBSAN_OBJECT_SIZE internal call. */
898 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
900 gimple stmt
= gsi_stmt (*gsi
);
901 location_t loc
= gimple_location (stmt
);
902 gcc_assert (gimple_call_num_args (stmt
) == 4);
904 tree ptr
= gimple_call_arg (stmt
, 0);
905 tree offset
= gimple_call_arg (stmt
, 1);
906 tree size
= gimple_call_arg (stmt
, 2);
907 tree ckind
= gimple_call_arg (stmt
, 3);
908 gimple_stmt_iterator gsi_orig
= *gsi
;
911 /* See if we can discard the check. */
912 if (TREE_CODE (size
) != INTEGER_CST
913 || integer_all_onesp (size
))
914 /* Yes, __builtin_object_size couldn't determine the
918 /* if (offset > objsize) */
919 basic_block then_bb
, fallthru_bb
;
920 gimple_stmt_iterator cond_insert_point
921 = create_cond_insert_point (gsi
, false, false, true,
922 &then_bb
, &fallthru_bb
);
923 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
924 gimple_set_location (g
, loc
);
925 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
927 /* Generate __ubsan_handle_type_mismatch call. */
928 *gsi
= gsi_after_labels (then_bb
);
929 if (flag_sanitize_undefined_trap_on_error
)
930 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
934 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
935 ubsan_type_descriptor (TREE_TYPE (ptr
),
936 UBSAN_PRINT_POINTER
),
938 build_zero_cst (pointer_sized_int_node
),
941 data
= build_fold_addr_expr_loc (loc
, data
);
942 enum built_in_function bcode
943 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
944 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
945 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
946 tree p
= make_ssa_name (pointer_sized_int_node
);
947 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
948 gimple_set_location (g
, loc
);
949 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
950 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
952 gimple_set_location (g
, loc
);
953 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
955 /* Point GSI to next logical statement. */
956 *gsi
= gsi_start_bb (fallthru_bb
);
959 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
960 unlink_stmt_vdef (stmt
);
961 gsi_remove (&gsi_orig
, true);
962 return gsi_end_p (*gsi
);
965 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
966 whether the pointer is on the left hand side of the assignment. */
969 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
972 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
973 unsigned int align
= 0;
974 if (flag_sanitize
& SANITIZE_ALIGNMENT
)
976 align
= min_align_of_type (TREE_TYPE (base
));
980 if (align
== 0 && (flag_sanitize
& SANITIZE_NULL
) == 0)
982 tree t
= TREE_OPERAND (base
, 0);
983 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
985 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t
))) && mem
!= base
)
986 ikind
= UBSAN_MEMBER_ACCESS
;
987 tree kind
= build_int_cst (TREE_TYPE (t
), ikind
);
988 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
989 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
990 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
991 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
994 /* Perform the pointer instrumentation. */
997 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
999 gimple stmt
= gsi_stmt (gsi
);
1000 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1001 tree base
= get_base_address (t
);
1002 const enum tree_code code
= TREE_CODE (base
);
1004 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1005 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1008 /* Build an ubsan builtin call for the signed-integer-overflow
1009 sanitization. CODE says what kind of builtin are we building,
1010 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1011 are operands of the binary operation. */
1014 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1017 if (flag_sanitize_undefined_trap_on_error
)
1018 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1020 tree data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1021 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1023 enum built_in_function fn_code
;
1028 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1029 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1030 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1033 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1034 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1035 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1038 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1039 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1040 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1043 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1044 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1045 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1050 tree fn
= builtin_decl_explicit (fn_code
);
1051 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1052 build_fold_addr_expr_loc (loc
, data
),
1053 ubsan_encode_value (op0
, true),
1054 op1
? ubsan_encode_value (op1
, true)
1058 /* Perform the signed integer instrumentation. GSI is the iterator
1059 pointing at statement we are trying to instrument. */
1062 instrument_si_overflow (gimple_stmt_iterator gsi
)
1064 gimple stmt
= gsi_stmt (gsi
);
1065 tree_code code
= gimple_assign_rhs_code (stmt
);
1066 tree lhs
= gimple_assign_lhs (stmt
);
1067 tree lhstype
= TREE_TYPE (lhs
);
1071 /* If this is not a signed operation, don't instrument anything here.
1072 Also punt on bit-fields. */
1073 if (!INTEGRAL_TYPE_P (lhstype
)
1074 || TYPE_OVERFLOW_WRAPS (lhstype
)
1075 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
1086 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1087 a
= gimple_assign_rhs1 (stmt
);
1088 b
= gimple_assign_rhs2 (stmt
);
1089 g
= gimple_build_call_internal (code
== PLUS_EXPR
1090 ? IFN_UBSAN_CHECK_ADD
1091 : code
== MINUS_EXPR
1092 ? IFN_UBSAN_CHECK_SUB
1093 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1094 gimple_call_set_lhs (g
, lhs
);
1095 gsi_replace (&gsi
, g
, false);
1098 /* Represent i = -u;
1100 i = UBSAN_CHECK_SUB (0, u); */
1101 a
= build_int_cst (lhstype
, 0);
1102 b
= gimple_assign_rhs1 (stmt
);
1103 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1104 gimple_call_set_lhs (g
, lhs
);
1105 gsi_replace (&gsi
, g
, false);
1108 /* Transform i = ABS_EXPR<u>;
1110 _N = UBSAN_CHECK_SUB (0, u);
1111 i = ABS_EXPR<_N>; */
1112 a
= build_int_cst (lhstype
, 0);
1113 b
= gimple_assign_rhs1 (stmt
);
1114 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1115 a
= make_ssa_name (lhstype
);
1116 gimple_call_set_lhs (g
, a
);
1117 gimple_set_location (g
, gimple_location (stmt
));
1118 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1119 gimple_assign_set_rhs1 (stmt
, a
);
1127 /* Instrument loads from (non-bitfield) bool and C++ enum values
1128 to check if the memory value is outside of the range of the valid
1132 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1134 gimple stmt
= gsi_stmt (*gsi
);
1135 tree rhs
= gimple_assign_rhs1 (stmt
);
1136 tree type
= TREE_TYPE (rhs
);
1137 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1139 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
1141 minv
= boolean_false_node
;
1142 maxv
= boolean_true_node
;
1144 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1145 && (flag_sanitize
& SANITIZE_ENUM
)
1146 && TREE_TYPE (type
) != NULL_TREE
1147 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1148 && (TYPE_PRECISION (TREE_TYPE (type
))
1149 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1151 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1152 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1157 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1158 HOST_WIDE_INT bitsize
, bitpos
;
1161 int volatilep
= 0, unsignedp
= 0;
1162 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1163 &unsignedp
, &volatilep
, false);
1164 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1166 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
1167 || (bitpos
% modebitsize
) != 0
1168 || bitsize
!= modebitsize
1169 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1170 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1173 bool can_throw
= stmt_could_throw_p (stmt
);
1174 location_t loc
= gimple_location (stmt
);
1175 tree lhs
= gimple_assign_lhs (stmt
);
1176 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1177 tree atype
= reference_alias_ptr_type (rhs
);
1178 gimple g
= gimple_build_assign (make_ssa_name (ptype
),
1179 build_fold_addr_expr (rhs
));
1180 gimple_set_location (g
, loc
);
1181 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1182 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1183 build_int_cst (atype
, 0));
1184 tree urhs
= make_ssa_name (utype
);
1187 gimple_assign_set_lhs (stmt
, urhs
);
1188 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1189 gimple_set_location (g
, loc
);
1190 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1191 gsi_insert_on_edge_immediate (e
, g
);
1192 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1194 *gsi
= gsi_for_stmt (g
);
1199 g
= gimple_build_assign (urhs
, mem
);
1200 gimple_set_location (g
, loc
);
1201 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1203 minv
= fold_convert (utype
, minv
);
1204 maxv
= fold_convert (utype
, maxv
);
1205 if (!integer_zerop (minv
))
1207 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1208 gimple_set_location (g
, loc
);
1209 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1212 gimple_stmt_iterator gsi2
= *gsi
;
1213 basic_block then_bb
, fallthru_bb
;
1214 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1215 &then_bb
, &fallthru_bb
);
1216 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1217 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1218 NULL_TREE
, NULL_TREE
);
1219 gimple_set_location (g
, loc
);
1220 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1224 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1228 gsi2
= gsi_after_labels (then_bb
);
1229 if (flag_sanitize_undefined_trap_on_error
)
1230 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1233 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1234 ubsan_type_descriptor (type
), NULL_TREE
,
1236 data
= build_fold_addr_expr_loc (loc
, data
);
1237 enum built_in_function bcode
1238 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1239 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1240 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1241 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1242 tree fn
= builtin_decl_explicit (bcode
);
1244 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
1245 true, NULL_TREE
, true,
1247 g
= gimple_build_call (fn
, 2, data
, val
);
1249 gimple_set_location (g
, loc
);
1250 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1251 *gsi
= gsi_for_stmt (stmt
);
1254 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1255 destination, EXPR is floating-point expression. */
1258 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
)
1260 tree expr_type
= TREE_TYPE (expr
);
1261 tree t
, tt
, fn
, min
, max
;
1262 machine_mode mode
= TYPE_MODE (expr_type
);
1263 int prec
= TYPE_PRECISION (type
);
1264 bool uns_p
= TYPE_UNSIGNED (type
);
1266 /* Float to integer conversion first truncates toward zero, so
1267 even signed char c = 127.875f; is not problematic.
1268 Therefore, we should complain only if EXPR is unordered or smaller
1269 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1270 TYPE_MAX_VALUE + 1.0. */
1271 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1273 /* For maximum, TYPE_MAX_VALUE might not be representable
1274 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1275 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1276 either representable or infinity. */
1277 REAL_VALUE_TYPE maxval
= dconst1
;
1278 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1279 real_convert (&maxval
, mode
, &maxval
);
1280 max
= build_real (expr_type
, maxval
);
1282 /* For unsigned, assume -1.0 is always representable. */
1284 min
= build_minus_one_cst (expr_type
);
1287 /* TYPE_MIN_VALUE is generally representable (or -inf),
1288 but TYPE_MIN_VALUE - 1.0 might not be. */
1289 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1290 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1291 real_convert (&minval
, mode
, &minval
);
1292 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1293 real_convert (&minval2
, mode
, &minval2
);
1294 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1295 && !real_isinf (&minval
))
1297 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1298 rounds to TYPE_MIN_VALUE, we need to subtract
1299 more. As REAL_MODE_FORMAT (mode)->p is the number
1300 of base digits, we want to subtract a number that
1301 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1302 times smaller than minval. */
1304 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1305 SET_REAL_EXP (&minval2
,
1306 REAL_EXP (&minval2
) + prec
- 1
1307 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1308 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1309 real_convert (&minval2
, mode
, &minval2
);
1311 min
= build_real (expr_type
, minval2
);
1314 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1316 /* For _Decimal128 up to 34 decimal digits, - sign,
1317 dot, e, exponent. */
1320 int p
= REAL_MODE_FORMAT (mode
)->p
;
1321 REAL_VALUE_TYPE maxval
, minval
;
1323 /* Use mpfr_snprintf rounding to compute the smallest
1324 representable decimal number greater or equal than
1325 1 << (prec - !uns_p). */
1326 mpfr_init2 (m
, prec
+ 2);
1327 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1328 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1329 decimal_real_from_string (&maxval
, buf
);
1330 max
= build_real (expr_type
, maxval
);
1332 /* For unsigned, assume -1.0 is always representable. */
1334 min
= build_minus_one_cst (expr_type
);
1337 /* Use mpfr_snprintf rounding to compute the largest
1338 representable decimal number less or equal than
1339 (-1 << (prec - 1)) - 1. */
1340 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1341 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1342 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1343 decimal_real_from_string (&minval
, buf
);
1344 min
= build_real (expr_type
, minval
);
1351 if (flag_sanitize_undefined_trap_on_error
)
1352 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1355 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1356 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1357 NULL
, ubsan_type_descriptor (expr_type
),
1358 ubsan_type_descriptor (type
), NULL_TREE
,
1360 enum built_in_function bcode
1361 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1362 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1363 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1364 fn
= builtin_decl_explicit (bcode
);
1365 fn
= build_call_expr_loc (loc
, fn
, 2,
1366 build_fold_addr_expr_loc (loc
, data
),
1367 ubsan_encode_value (expr
, false));
1370 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1371 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1372 return fold_build3 (COND_EXPR
, void_type_node
,
1373 fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
),
1374 fn
, integer_zero_node
);
1377 /* Instrument values passed to function arguments with nonnull attribute. */
1380 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1382 gimple stmt
= gsi_stmt (*gsi
);
1384 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1385 while for nonnull sanitization it is clear. */
1386 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1387 flag_delete_null_pointer_checks
= 1;
1388 loc
[0] = gimple_location (stmt
);
1389 loc
[1] = UNKNOWN_LOCATION
;
1390 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1392 tree arg
= gimple_call_arg (stmt
, i
);
1393 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1394 && infer_nonnull_range (stmt
, arg
, false, true))
1397 if (!is_gimple_val (arg
))
1399 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1400 gimple_set_location (g
, loc
[0]);
1401 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1402 arg
= gimple_assign_lhs (g
);
1405 basic_block then_bb
, fallthru_bb
;
1406 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1407 &then_bb
, &fallthru_bb
);
1408 g
= gimple_build_cond (EQ_EXPR
, arg
,
1409 build_zero_cst (TREE_TYPE (arg
)),
1410 NULL_TREE
, NULL_TREE
);
1411 gimple_set_location (g
, loc
[0]);
1412 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1414 *gsi
= gsi_after_labels (then_bb
);
1415 if (flag_sanitize_undefined_trap_on_error
)
1416 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1419 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1421 build_int_cst (integer_type_node
,
1424 data
= build_fold_addr_expr_loc (loc
[0], data
);
1425 enum built_in_function bcode
1426 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1427 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1428 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1429 tree fn
= builtin_decl_explicit (bcode
);
1431 g
= gimple_build_call (fn
, 1, data
);
1433 gimple_set_location (g
, loc
[0]);
1434 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1436 *gsi
= gsi_for_stmt (stmt
);
1438 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1441 /* Instrument returns in functions with returns_nonnull attribute. */
1444 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1446 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
1448 tree arg
= gimple_return_retval (stmt
);
1449 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1450 while for nonnull return sanitization it is clear. */
1451 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1452 flag_delete_null_pointer_checks
= 1;
1453 loc
[0] = gimple_location (stmt
);
1454 loc
[1] = UNKNOWN_LOCATION
;
1456 && POINTER_TYPE_P (TREE_TYPE (arg
))
1457 && is_gimple_val (arg
)
1458 && infer_nonnull_range (stmt
, arg
, false, true))
1460 basic_block then_bb
, fallthru_bb
;
1461 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1462 &then_bb
, &fallthru_bb
);
1463 gimple g
= gimple_build_cond (EQ_EXPR
, arg
,
1464 build_zero_cst (TREE_TYPE (arg
)),
1465 NULL_TREE
, NULL_TREE
);
1466 gimple_set_location (g
, loc
[0]);
1467 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1469 *gsi
= gsi_after_labels (then_bb
);
1470 if (flag_sanitize_undefined_trap_on_error
)
1471 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1474 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
1475 2, loc
, NULL_TREE
, NULL_TREE
);
1476 data
= build_fold_addr_expr_loc (loc
[0], data
);
1477 enum built_in_function bcode
1478 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1479 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1480 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
1481 tree fn
= builtin_decl_explicit (bcode
);
1483 g
= gimple_build_call (fn
, 1, data
);
1485 gimple_set_location (g
, loc
[0]);
1486 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1487 *gsi
= gsi_for_stmt (stmt
);
1489 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1492 /* Instrument memory references. Here we check whether the pointer
1493 points to an out-of-bounds location. */
1496 instrument_object_size (gimple_stmt_iterator
*gsi
, bool is_lhs
)
1498 gimple stmt
= gsi_stmt (*gsi
);
1499 location_t loc
= gimple_location (stmt
);
1500 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1502 tree index
= NULL_TREE
;
1503 HOST_WIDE_INT size_in_bytes
;
1505 type
= TREE_TYPE (t
);
1506 if (VOID_TYPE_P (type
))
1509 switch (TREE_CODE (t
))
1512 if (TREE_CODE (t
) == COMPONENT_REF
1513 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
1515 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
1516 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
1521 index
= TREE_OPERAND (t
, 1);
1533 size_in_bytes
= int_size_in_bytes (type
);
1534 if (size_in_bytes
<= 0)
1537 HOST_WIDE_INT bitsize
, bitpos
;
1540 int volatilep
= 0, unsignedp
= 0;
1541 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1542 &unsignedp
, &volatilep
, false);
1544 if (bitpos
% BITS_PER_UNIT
!= 0
1545 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
1548 bool decl_p
= DECL_P (inner
);
1552 else if (TREE_CODE (inner
) == MEM_REF
)
1553 base
= TREE_OPERAND (inner
, 0);
1556 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
1558 while (TREE_CODE (base
) == SSA_NAME
)
1560 gimple def_stmt
= SSA_NAME_DEF_STMT (base
);
1561 if (gimple_assign_ssa_name_copy_p (def_stmt
)
1562 || (gimple_assign_cast_p (def_stmt
)
1563 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
1564 || (is_gimple_assign (def_stmt
)
1565 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
1567 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
1568 if (TREE_CODE (rhs1
) == SSA_NAME
1569 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
1578 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1582 tree base_addr
= base
;
1584 base_addr
= build1 (ADDR_EXPR
,
1585 build_pointer_type (TREE_TYPE (base
)), base
);
1586 unsigned HOST_WIDE_INT size
= compute_builtin_object_size (base_addr
, 0);
1587 if (size
!= (unsigned HOST_WIDE_INT
) -1)
1588 sizet
= build_int_cst (sizetype
, size
);
1591 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
1592 loc
= input_location
;
1593 /* Generate __builtin_object_size call. */
1594 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
1595 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
1597 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
1603 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1605 /* ptr + sizeof (*ptr) - base */
1606 t
= fold_build2 (MINUS_EXPR
, sizetype
,
1607 fold_convert (pointer_sized_int_node
, ptr
),
1608 fold_convert (pointer_sized_int_node
, base_addr
));
1609 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
1611 /* Perhaps we can omit the check. */
1612 if (TREE_CODE (t
) == INTEGER_CST
1613 && TREE_CODE (sizet
) == INTEGER_CST
1614 && tree_int_cst_le (t
, sizet
))
1617 if (index
!= NULL_TREE
1618 && TREE_CODE (index
) == SSA_NAME
1619 && TREE_CODE (sizet
) == INTEGER_CST
)
1621 gimple def
= SSA_NAME_DEF_STMT (index
);
1622 if (is_gimple_assign (def
)
1623 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
1624 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
1626 tree cst
= gimple_assign_rhs2 (def
);
1627 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
1628 TYPE_SIZE_UNIT (type
));
1629 if (tree_int_cst_sgn (cst
) >= 0
1630 && tree_int_cst_lt (cst
, sz
))
1635 /* Nope. Emit the check. */
1636 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1638 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
1640 tree ckind
= build_int_cst (unsigned_char_type_node
,
1641 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
1642 gimple g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
1643 ptr
, t
, sizet
, ckind
);
1644 gimple_set_location (g
, loc
);
1645 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1650 const pass_data pass_data_ubsan
=
1652 GIMPLE_PASS
, /* type */
1654 OPTGROUP_NONE
, /* optinfo_flags */
1655 TV_TREE_UBSAN
, /* tv_id */
1656 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1657 0, /* properties_provided */
1658 0, /* properties_destroyed */
1659 0, /* todo_flags_start */
1660 TODO_update_ssa
, /* todo_flags_finish */
1663 class pass_ubsan
: public gimple_opt_pass
1666 pass_ubsan (gcc::context
*ctxt
)
1667 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1670 /* opt_pass methods: */
1671 virtual bool gate (function
*)
1673 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1674 | SANITIZE_BOOL
| SANITIZE_ENUM
1675 | SANITIZE_ALIGNMENT
1676 | SANITIZE_NONNULL_ATTRIBUTE
1677 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1678 | SANITIZE_OBJECT_SIZE
)
1679 && current_function_decl
!= NULL_TREE
1680 && !lookup_attribute ("no_sanitize_undefined",
1681 DECL_ATTRIBUTES (current_function_decl
));
1684 virtual unsigned int execute (function
*);
1686 }; // class pass_ubsan
1689 pass_ubsan::execute (function
*fun
)
1692 gimple_stmt_iterator gsi
;
1694 initialize_sanitizer_builtins ();
1696 FOR_EACH_BB_FN (bb
, fun
)
1698 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1700 gimple stmt
= gsi_stmt (gsi
);
1701 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
1707 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
1708 && is_gimple_assign (stmt
))
1709 instrument_si_overflow (gsi
);
1711 if (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1713 if (gimple_store_p (stmt
))
1714 instrument_null (gsi
, true);
1715 if (gimple_assign_load_p (stmt
))
1716 instrument_null (gsi
, false);
1719 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
1720 && gimple_assign_load_p (stmt
))
1722 instrument_bool_enum_load (&gsi
);
1723 bb
= gimple_bb (stmt
);
1726 if ((flag_sanitize
& SANITIZE_NONNULL_ATTRIBUTE
)
1727 && is_gimple_call (stmt
)
1728 && !gimple_call_internal_p (stmt
))
1730 instrument_nonnull_arg (&gsi
);
1731 bb
= gimple_bb (stmt
);
1734 if ((flag_sanitize
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1735 && gimple_code (stmt
) == GIMPLE_RETURN
)
1737 instrument_nonnull_return (&gsi
);
1738 bb
= gimple_bb (stmt
);
1741 if (flag_sanitize
& SANITIZE_OBJECT_SIZE
)
1743 if (gimple_store_p (stmt
))
1744 instrument_object_size (&gsi
, true);
1745 if (gimple_assign_load_p (stmt
))
1746 instrument_object_size (&gsi
, false);
1758 make_pass_ubsan (gcc::context
*ctxt
)
1760 return new pass_ubsan (ctxt
);
1763 #include "gt-ubsan.h"