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"
33 #include "tree-pass.h"
34 #include "tree-ssa-alias.h"
35 #include "tree-pretty-print.h"
36 #include "internal-fn.h"
37 #include "gimple-expr.h"
39 #include "gimple-iterator.h"
40 #include "gimple-ssa.h"
41 #include "gimple-walk.h"
48 #include "c-family/c-common.h"
51 #include "tree-ssanames.h"
53 #include "gimplify-me.h"
58 #include "tree-object-size.h"
60 /* Map from a tree to a VAR_DECL tree. */
62 struct GTY(()) tree_type_map
{
63 struct tree_map_base type
;
67 #define tree_type_map_eq tree_map_base_eq
68 #define tree_type_map_marked_p tree_map_base_marked_p
70 /* Hash from a tree in a tree_type_map. */
73 tree_type_map_hash (const void *item
)
75 return TYPE_UID (((const struct tree_type_map
*)item
)->type
.from
);
78 static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map
)))
79 htab_t decl_tree_for_type
;
81 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
84 decl_for_type_lookup (tree type
)
86 /* If the hash table is not initialized yet, create it now. */
87 if (decl_tree_for_type
== NULL
)
89 decl_tree_for_type
= htab_create_ggc (10, tree_type_map_hash
,
91 /* That also means we don't have to bother with the lookup. */
95 struct tree_type_map
*h
, in
;
98 h
= (struct tree_type_map
*)
99 htab_find_with_hash (decl_tree_for_type
, &in
, TYPE_UID (type
));
100 return h
? h
->decl
: NULL_TREE
;
103 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
106 decl_for_type_insert (tree type
, tree decl
)
108 struct tree_type_map
*h
;
111 h
= ggc_alloc
<tree_type_map
> ();
114 slot
= htab_find_slot_with_hash (decl_tree_for_type
, h
, TYPE_UID (type
),
116 *(struct tree_type_map
**) slot
= h
;
119 /* Helper routine, which encodes a value in the pointer_sized_int_node.
120 Arguments with precision <= POINTER_SIZE are passed directly,
121 the rest is passed by reference. T is a value we are to encode.
122 IN_EXPAND_P is true if this function is called during expansion. */
125 ubsan_encode_value (tree t
, bool in_expand_p
)
127 tree type
= TREE_TYPE (t
);
128 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
129 if (bitsize
<= POINTER_SIZE
)
130 switch (TREE_CODE (type
))
135 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
138 tree itype
= build_nonstandard_integer_type (bitsize
, true);
139 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
140 return fold_convert (pointer_sized_int_node
, t
);
147 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
149 /* The reason for this is that we don't want to pessimize
150 code by making vars unnecessarily addressable. */
151 tree var
= create_tmp_var (type
, NULL
);
152 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
156 = assign_stack_temp_for_type (TYPE_MODE (type
),
157 GET_MODE_SIZE (TYPE_MODE (type
)),
159 SET_DECL_RTL (var
, mem
);
160 expand_assignment (var
, t
, false);
161 return build_fold_addr_expr (var
);
163 t
= build_fold_addr_expr (var
);
164 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
167 return build_fold_addr_expr (t
);
172 struct __ubsan_type_descriptor
174 unsigned short __typekind;
175 unsigned short __typeinfo;
181 ubsan_type_descriptor_type (void)
183 static const char *field_names
[3]
184 = { "__typekind", "__typeinfo", "__typename" };
186 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
187 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
189 ret
= make_node (RECORD_TYPE
);
190 for (int i
= 0; i
< 3; i
++)
192 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
193 get_identifier (field_names
[i
]),
194 (i
== 2) ? flex_arr_type
195 : short_unsigned_type_node
);
196 DECL_CONTEXT (fields
[i
]) = ret
;
198 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
200 TYPE_FIELDS (ret
) = fields
[0];
201 TYPE_NAME (ret
) = get_identifier ("__ubsan_type_descriptor");
206 /* Cached ubsan_get_source_location_type () return value. */
207 static GTY(()) tree ubsan_source_location_type
;
210 struct __ubsan_source_location
212 const char *__filename;
214 unsigned int __column;
219 ubsan_get_source_location_type (void)
221 static const char *field_names
[3]
222 = { "__filename", "__line", "__column" };
224 if (ubsan_source_location_type
)
225 return ubsan_source_location_type
;
227 tree const_char_type
= build_qualified_type (char_type_node
,
230 ret
= make_node (RECORD_TYPE
);
231 for (int i
= 0; i
< 3; i
++)
233 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
234 get_identifier (field_names
[i
]),
235 (i
== 0) ? build_pointer_type (const_char_type
)
236 : unsigned_type_node
);
237 DECL_CONTEXT (fields
[i
]) = ret
;
239 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
241 TYPE_FIELDS (ret
) = fields
[0];
242 TYPE_NAME (ret
) = get_identifier ("__ubsan_source_location");
244 ubsan_source_location_type
= ret
;
248 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
249 type with its fields filled from a location_t LOC. */
252 ubsan_source_location (location_t loc
)
254 expanded_location xloc
;
255 tree type
= ubsan_get_source_location_type ();
257 xloc
= expand_location (loc
);
259 if (xloc
.file
== NULL
)
261 str
= build_int_cst (ptr_type_node
, 0);
267 /* Fill in the values from LOC. */
268 size_t len
= strlen (xloc
.file
);
269 str
= build_string (len
+ 1, xloc
.file
);
270 TREE_TYPE (str
) = build_array_type (char_type_node
,
271 build_index_type (size_int (len
)));
272 TREE_READONLY (str
) = 1;
273 TREE_STATIC (str
) = 1;
274 str
= build_fold_addr_expr (str
);
276 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
277 build_int_cst (unsigned_type_node
,
278 xloc
.line
), NULL_TREE
,
279 build_int_cst (unsigned_type_node
,
281 TREE_CONSTANT (ctor
) = 1;
282 TREE_STATIC (ctor
) = 1;
287 /* This routine returns a magic number for TYPE. */
289 static unsigned short
290 get_ubsan_type_info_for_type (tree type
)
292 gcc_assert (TYPE_SIZE (type
) && tree_fits_uhwi_p (TYPE_SIZE (type
)));
293 if (TREE_CODE (type
) == REAL_TYPE
)
294 return tree_to_uhwi (TYPE_SIZE (type
));
295 else if (INTEGRAL_TYPE_P (type
))
297 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
298 gcc_assert (prec
!= -1);
299 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
305 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
306 descriptor. It first looks into the hash table; if not found,
307 create the VAR_DECL, put it into the hash table and return the
308 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
309 an enum controlling how we want to print the type. */
312 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
314 /* See through any typedefs. */
315 type
= TYPE_MAIN_VARIANT (type
);
317 tree decl
= decl_for_type_lookup (type
);
318 /* It is possible that some of the earlier created DECLs were found
319 unused, in that case they weren't emitted and varpool_node::get
320 returns NULL node on them. But now we really need them. Thus,
322 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
323 return build_fold_addr_expr (decl
);
325 tree dtype
= ubsan_type_descriptor_type ();
327 const char *tname
= NULL
;
329 unsigned char deref_depth
= 0;
330 unsigned short tkind
, tinfo
;
332 /* Get the name of the type, or the name of the pointer type. */
333 if (pstyle
== UBSAN_PRINT_POINTER
)
335 gcc_assert (POINTER_TYPE_P (type
));
336 type2
= TREE_TYPE (type
);
338 /* Remove any '*' operators from TYPE. */
339 while (POINTER_TYPE_P (type2
))
340 deref_depth
++, type2
= TREE_TYPE (type2
);
342 if (TREE_CODE (type2
) == METHOD_TYPE
)
343 type2
= TYPE_METHOD_BASETYPE (type2
);
346 /* If an array, get its type. */
347 type2
= strip_array_types (type2
);
349 if (pstyle
== UBSAN_PRINT_ARRAY
)
351 while (POINTER_TYPE_P (type2
))
352 deref_depth
++, type2
= TREE_TYPE (type2
);
355 if (TYPE_NAME (type2
) != NULL
)
357 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
358 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
359 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
360 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
364 /* We weren't able to determine the type name. */
367 /* Decorate the type name with '', '*', "struct", or "union". */
368 pretty_name
= (char *) alloca (strlen (tname
) + 16 + deref_depth
);
369 if (pstyle
== UBSAN_PRINT_POINTER
)
371 int pos
= sprintf (pretty_name
, "'%s%s%s%s%s%s%s",
372 TYPE_VOLATILE (type2
) ? "volatile " : "",
373 TYPE_READONLY (type2
) ? "const " : "",
374 TYPE_RESTRICT (type2
) ? "restrict " : "",
375 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
376 TREE_CODE (type2
) == RECORD_TYPE
378 : TREE_CODE (type2
) == UNION_TYPE
379 ? "union " : "", tname
,
380 deref_depth
== 0 ? "" : " ");
381 while (deref_depth
-- > 0)
382 pretty_name
[pos
++] = '*';
383 pretty_name
[pos
++] = '\'';
384 pretty_name
[pos
] = '\0';
386 else if (pstyle
== UBSAN_PRINT_ARRAY
)
388 /* Pretty print the array dimensions. */
389 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
391 int pos
= sprintf (pretty_name
, "'%s ", tname
);
392 while (deref_depth
-- > 0)
393 pretty_name
[pos
++] = '*';
394 while (TREE_CODE (t
) == ARRAY_TYPE
)
396 pretty_name
[pos
++] = '[';
397 tree dom
= TYPE_DOMAIN (t
);
398 if (dom
&& TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
399 pos
+= sprintf (&pretty_name
[pos
], HOST_WIDE_INT_PRINT_DEC
,
400 tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1);
402 /* ??? We can't determine the variable name; print VLA unspec. */
403 pretty_name
[pos
++] = '*';
404 pretty_name
[pos
++] = ']';
407 pretty_name
[pos
++] = '\'';
408 pretty_name
[pos
] = '\0';
410 /* Save the tree with stripped types. */
414 sprintf (pretty_name
, "'%s'", tname
);
416 switch (TREE_CODE (type
))
424 /* FIXME: libubsan right now only supports float, double and
425 long double type formats. */
426 if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
)
427 || TYPE_MODE (type
) == TYPE_MODE (double_type_node
)
428 || TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
437 tinfo
= get_ubsan_type_info_for_type (type
);
439 /* Create a new VAR_DECL of type descriptor. */
441 static unsigned int type_var_id_num
;
442 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
443 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
445 TREE_STATIC (decl
) = 1;
446 TREE_PUBLIC (decl
) = 0;
447 DECL_ARTIFICIAL (decl
) = 1;
448 DECL_IGNORED_P (decl
) = 1;
449 DECL_EXTERNAL (decl
) = 0;
451 size_t len
= strlen (pretty_name
);
452 tree str
= build_string (len
+ 1, pretty_name
);
453 TREE_TYPE (str
) = build_array_type (char_type_node
,
454 build_index_type (size_int (len
)));
455 TREE_READONLY (str
) = 1;
456 TREE_STATIC (str
) = 1;
457 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
458 build_int_cst (short_unsigned_type_node
,
460 build_int_cst (short_unsigned_type_node
,
461 tinfo
), NULL_TREE
, str
);
462 TREE_CONSTANT (ctor
) = 1;
463 TREE_STATIC (ctor
) = 1;
464 DECL_INITIAL (decl
) = ctor
;
465 varpool_node::finalize_decl (decl
);
467 /* Save the VAR_DECL into the hash table. */
468 decl_for_type_insert (type
, decl
);
470 return build_fold_addr_expr (decl
);
473 /* Create a structure for the ubsan library. NAME is a name of the new
474 structure. LOCCNT is number of locations, PLOC points to array of
475 locations. The arguments in ... are of __ubsan_type_descriptor type
476 and there are at most two of them, followed by NULL_TREE, followed
477 by optional extra arguments and another NULL_TREE. */
480 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
485 vec
<tree
, va_gc
> *saved_args
= NULL
;
489 /* Firstly, create a pointer to type descriptor type. */
490 tree td_type
= ubsan_type_descriptor_type ();
491 TYPE_READONLY (td_type
) = 1;
492 td_type
= build_pointer_type (td_type
);
494 /* Create the structure type. */
495 ret
= make_node (RECORD_TYPE
);
496 for (j
= 0; j
< loccnt
; j
++)
498 gcc_checking_assert (i
< 2);
499 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
500 ubsan_get_source_location_type ());
501 DECL_CONTEXT (fields
[i
]) = ret
;
503 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
507 va_start (args
, ploc
);
508 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
509 i
++, t
= va_arg (args
, tree
))
511 gcc_checking_assert (i
< 4);
512 /* Save the tree arguments for later use. */
513 vec_safe_push (saved_args
, t
);
514 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
516 DECL_CONTEXT (fields
[i
]) = ret
;
518 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
521 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
522 i
++, t
= va_arg (args
, tree
))
524 gcc_checking_assert (i
< 6);
525 /* Save the tree arguments for later use. */
526 vec_safe_push (saved_args
, t
);
527 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
529 DECL_CONTEXT (fields
[i
]) = ret
;
531 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
535 TYPE_FIELDS (ret
) = fields
[0];
536 TYPE_NAME (ret
) = get_identifier (name
);
539 /* Now, fill in the type. */
541 static unsigned int ubsan_var_id_num
;
542 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
543 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
545 TREE_STATIC (var
) = 1;
546 TREE_PUBLIC (var
) = 0;
547 DECL_ARTIFICIAL (var
) = 1;
548 DECL_IGNORED_P (var
) = 1;
549 DECL_EXTERNAL (var
) = 0;
551 vec
<constructor_elt
, va_gc
> *v
;
553 tree ctor
= build_constructor (ret
, v
);
555 /* If desirable, set the __ubsan_source_location element. */
556 for (j
= 0; j
< loccnt
; j
++)
558 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
559 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
562 size_t nelts
= vec_safe_length (saved_args
);
563 for (i
= 0; i
< nelts
; i
++)
565 t
= (*saved_args
)[i
];
566 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
569 TREE_CONSTANT (ctor
) = 1;
570 TREE_STATIC (ctor
) = 1;
571 DECL_INITIAL (var
) = ctor
;
572 varpool_node::finalize_decl (var
);
577 /* Instrument the __builtin_unreachable call. We just call the libubsan
581 ubsan_instrument_unreachable (location_t loc
)
583 if (flag_sanitize_undefined_trap_on_error
)
584 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
586 initialize_sanitizer_builtins ();
587 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
, NULL_TREE
,
589 tree t
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
590 return build_call_expr_loc (loc
, t
, 1, build_fold_addr_expr_loc (loc
, data
));
593 /* Return true if T is a call to a libubsan routine. */
596 is_ubsan_builtin_p (tree t
)
598 return TREE_CODE (t
) == FUNCTION_DECL
599 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
600 "__builtin___ubsan_", 18) == 0;
603 /* Expand the UBSAN_BOUNDS special builtin function. */
606 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
608 gimple stmt
= gsi_stmt (*gsi
);
609 location_t loc
= gimple_location (stmt
);
610 gcc_assert (gimple_call_num_args (stmt
) == 3);
612 /* Pick up the arguments of the UBSAN_BOUNDS call. */
613 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
614 tree index
= gimple_call_arg (stmt
, 1);
615 tree orig_index_type
= TREE_TYPE (index
);
616 tree bound
= gimple_call_arg (stmt
, 2);
618 gimple_stmt_iterator gsi_orig
= *gsi
;
620 /* Create condition "if (index > bound)". */
621 basic_block then_bb
, fallthru_bb
;
622 gimple_stmt_iterator cond_insert_point
623 = create_cond_insert_point (gsi
, false, false, true,
624 &then_bb
, &fallthru_bb
);
625 index
= fold_convert (TREE_TYPE (bound
), index
);
626 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
628 false, GSI_NEW_STMT
);
629 gimple g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
630 gimple_set_location (g
, loc
);
631 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
633 /* Generate __ubsan_handle_out_of_bounds call. */
634 *gsi
= gsi_after_labels (then_bb
);
635 if (flag_sanitize_undefined_trap_on_error
)
636 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
640 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
641 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
642 ubsan_type_descriptor (orig_index_type
),
643 NULL_TREE
, NULL_TREE
);
644 data
= build_fold_addr_expr_loc (loc
, data
);
645 enum built_in_function bcode
646 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
647 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
648 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
649 tree fn
= builtin_decl_explicit (bcode
);
650 tree val
= force_gimple_operand_gsi (gsi
, ubsan_encode_value (index
),
651 true, NULL_TREE
, true,
653 g
= gimple_build_call (fn
, 2, data
, val
);
655 gimple_set_location (g
, loc
);
656 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
658 /* Get rid of the UBSAN_BOUNDS call from the IR. */
659 unlink_stmt_vdef (stmt
);
660 gsi_remove (&gsi_orig
, true);
662 /* Point GSI to next logical statement. */
663 *gsi
= gsi_start_bb (fallthru_bb
);
667 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
668 argument which is a constant, because the middle-end treats pointer
669 conversions as useless and therefore the type of the first argument
670 could be changed to any other pointer type. */
673 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
675 gimple_stmt_iterator gsi
= *gsip
;
676 gimple stmt
= gsi_stmt (gsi
);
677 location_t loc
= gimple_location (stmt
);
678 gcc_assert (gimple_call_num_args (stmt
) == 3);
679 tree ptr
= gimple_call_arg (stmt
, 0);
680 tree ckind
= gimple_call_arg (stmt
, 1);
681 tree align
= gimple_call_arg (stmt
, 2);
682 tree check_align
= NULL_TREE
;
685 basic_block cur_bb
= gsi_bb (gsi
);
688 if (!integer_zerop (align
))
690 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
691 if (compare_tree_int (align
, ptralign
) == 1)
693 check_align
= make_ssa_name (pointer_sized_int_node
, NULL
);
694 g
= gimple_build_assign_with_ops (NOP_EXPR
, check_align
,
696 gimple_set_location (g
, loc
);
697 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
700 check_null
= (flag_sanitize
& SANITIZE_NULL
) != 0;
702 if (check_align
== NULL_TREE
&& !check_null
)
704 gsi_remove (gsip
, true);
705 /* Unlink the UBSAN_NULLs vops before replacing it. */
706 unlink_stmt_vdef (stmt
);
710 /* Split the original block holding the pointer dereference. */
711 edge e
= split_block (cur_bb
, stmt
);
713 /* Get a hold on the 'condition block', the 'then block' and the
715 basic_block cond_bb
= e
->src
;
716 basic_block fallthru_bb
= e
->dest
;
717 basic_block then_bb
= create_empty_bb (cond_bb
);
718 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
719 loops_state_set (LOOPS_NEED_FIXUP
);
721 /* Make an edge coming from the 'cond block' into the 'then block';
722 this edge is unlikely taken, so set up the probability accordingly. */
723 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
724 e
->probability
= PROB_VERY_UNLIKELY
;
726 /* Connect 'then block' with the 'else block'. This is needed
727 as the ubsan routines we call in the 'then block' are not noreturn.
728 The 'then block' only has one outcoming edge. */
729 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
731 /* Set up the fallthrough basic block. */
732 e
= find_edge (cond_bb
, fallthru_bb
);
733 e
->flags
= EDGE_FALSE_VALUE
;
734 e
->count
= cond_bb
->count
;
735 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
737 /* Update dominance info for the newly created then_bb; note that
738 fallthru_bb's dominance info has already been updated by
740 if (dom_info_available_p (CDI_DOMINATORS
))
741 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
743 /* Put the ubsan builtin call into the newly created BB. */
744 if (flag_sanitize_undefined_trap_on_error
)
745 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
748 enum built_in_function bcode
749 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
750 | (check_null
? SANITIZE_NULL
: 0)))
751 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
752 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
753 tree fn
= builtin_decl_implicit (bcode
);
755 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
756 ubsan_type_descriptor (TREE_TYPE (ckind
),
757 UBSAN_PRINT_POINTER
),
760 fold_convert (unsigned_char_type_node
, ckind
),
762 data
= build_fold_addr_expr_loc (loc
, data
);
763 g
= gimple_build_call (fn
, 2, data
,
764 check_align
? check_align
765 : build_zero_cst (pointer_sized_int_node
));
767 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
768 gimple_set_location (g
, loc
);
769 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
771 /* Unlink the UBSAN_NULLs vops before replacing it. */
772 unlink_stmt_vdef (stmt
);
776 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
777 NULL_TREE
, NULL_TREE
);
778 gimple_set_location (g
, loc
);
780 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
781 gsi_replace (&gsi
, g
, false);
788 /* Split the block with the condition again. */
789 e
= split_block (cond_bb
, stmt
);
790 basic_block cond1_bb
= e
->src
;
791 basic_block cond2_bb
= e
->dest
;
793 /* Make an edge coming from the 'cond1 block' into the 'then block';
794 this edge is unlikely taken, so set up the probability
796 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
797 e
->probability
= PROB_VERY_UNLIKELY
;
799 /* Set up the fallthrough basic block. */
800 e
= find_edge (cond1_bb
, cond2_bb
);
801 e
->flags
= EDGE_FALSE_VALUE
;
802 e
->count
= cond1_bb
->count
;
803 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
805 /* Update dominance info. */
806 if (dom_info_available_p (CDI_DOMINATORS
))
808 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
809 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
812 gsi2
= gsi_start_bb (cond2_bb
);
815 tree mask
= build_int_cst (pointer_sized_int_node
,
816 tree_to_uhwi (align
) - 1);
817 g
= gimple_build_assign_with_ops (BIT_AND_EXPR
,
818 make_ssa_name (pointer_sized_int_node
,
821 gimple_set_location (g
, loc
);
823 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
825 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
827 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
828 build_int_cst (pointer_sized_int_node
, 0),
829 NULL_TREE
, NULL_TREE
);
830 gimple_set_location (g
, loc
);
832 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
834 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
835 gsi_replace (&gsi
, g
, false);
840 /* Expand UBSAN_OBJECT_SIZE internal call. */
843 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
845 gimple stmt
= gsi_stmt (*gsi
);
846 location_t loc
= gimple_location (stmt
);
847 gcc_assert (gimple_call_num_args (stmt
) == 4);
849 tree ptr
= gimple_call_arg (stmt
, 0);
850 tree offset
= gimple_call_arg (stmt
, 1);
851 tree size
= gimple_call_arg (stmt
, 2);
852 tree ckind
= gimple_call_arg (stmt
, 3);
853 gimple_stmt_iterator gsi_orig
= *gsi
;
856 /* See if we can discard the check. */
857 if (TREE_CODE (size
) != INTEGER_CST
858 || integer_all_onesp (size
))
859 /* Yes, __builtin_object_size couldn't determine the
863 /* if (offset > objsize) */
864 basic_block then_bb
, fallthru_bb
;
865 gimple_stmt_iterator cond_insert_point
866 = create_cond_insert_point (gsi
, false, false, true,
867 &then_bb
, &fallthru_bb
);
868 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
869 gimple_set_location (g
, loc
);
870 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
872 /* Generate __ubsan_handle_type_mismatch call. */
873 *gsi
= gsi_after_labels (then_bb
);
874 if (flag_sanitize_undefined_trap_on_error
)
875 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
879 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
880 ubsan_type_descriptor (TREE_TYPE (ptr
),
881 UBSAN_PRINT_POINTER
),
883 build_zero_cst (pointer_sized_int_node
),
886 data
= build_fold_addr_expr_loc (loc
, data
);
887 enum built_in_function bcode
888 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
889 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
890 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
891 tree p
= make_ssa_name (pointer_sized_int_node
, NULL
);
892 g
= gimple_build_assign_with_ops (NOP_EXPR
, p
, ptr
, NULL_TREE
);
893 gimple_set_location (g
, loc
);
894 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
895 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
897 gimple_set_location (g
, loc
);
898 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
900 /* Point GSI to next logical statement. */
901 *gsi
= gsi_start_bb (fallthru_bb
);
904 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
905 unlink_stmt_vdef (stmt
);
906 gsi_remove (&gsi_orig
, true);
907 return gsi_end_p (*gsi
);
910 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
911 whether the pointer is on the left hand side of the assignment. */
914 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
917 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
918 unsigned int align
= 0;
919 if (flag_sanitize
& SANITIZE_ALIGNMENT
)
921 align
= min_align_of_type (TREE_TYPE (base
));
925 if (align
== 0 && (flag_sanitize
& SANITIZE_NULL
) == 0)
927 tree t
= TREE_OPERAND (base
, 0);
928 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
930 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t
))) && mem
!= base
)
931 ikind
= UBSAN_MEMBER_ACCESS
;
932 tree kind
= build_int_cst (TREE_TYPE (t
), ikind
);
933 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
934 gimple g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
935 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
936 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
939 /* Perform the pointer instrumentation. */
942 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
944 gimple stmt
= gsi_stmt (gsi
);
945 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
946 tree base
= get_base_address (t
);
947 const enum tree_code code
= TREE_CODE (base
);
949 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
950 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
953 /* Build an ubsan builtin call for the signed-integer-overflow
954 sanitization. CODE says what kind of builtin are we building,
955 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
956 are operands of the binary operation. */
959 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
962 if (flag_sanitize_undefined_trap_on_error
)
963 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
965 tree data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
966 ubsan_type_descriptor (lhstype
), NULL_TREE
,
968 enum built_in_function fn_code
;
973 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
974 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
975 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
978 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
979 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
980 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
983 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
984 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
985 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
988 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
989 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
990 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
995 tree fn
= builtin_decl_explicit (fn_code
);
996 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
997 build_fold_addr_expr_loc (loc
, data
),
998 ubsan_encode_value (op0
, true),
999 op1
? ubsan_encode_value (op1
, true)
1003 /* Perform the signed integer instrumentation. GSI is the iterator
1004 pointing at statement we are trying to instrument. */
1007 instrument_si_overflow (gimple_stmt_iterator gsi
)
1009 gimple stmt
= gsi_stmt (gsi
);
1010 tree_code code
= gimple_assign_rhs_code (stmt
);
1011 tree lhs
= gimple_assign_lhs (stmt
);
1012 tree lhstype
= TREE_TYPE (lhs
);
1016 /* If this is not a signed operation, don't instrument anything here.
1017 Also punt on bit-fields. */
1018 if (!INTEGRAL_TYPE_P (lhstype
)
1019 || TYPE_OVERFLOW_WRAPS (lhstype
)
1020 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
1031 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1032 a
= gimple_assign_rhs1 (stmt
);
1033 b
= gimple_assign_rhs2 (stmt
);
1034 g
= gimple_build_call_internal (code
== PLUS_EXPR
1035 ? IFN_UBSAN_CHECK_ADD
1036 : code
== MINUS_EXPR
1037 ? IFN_UBSAN_CHECK_SUB
1038 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1039 gimple_call_set_lhs (g
, lhs
);
1040 gsi_replace (&gsi
, g
, false);
1043 /* Represent i = -u;
1045 i = UBSAN_CHECK_SUB (0, u); */
1046 a
= build_int_cst (lhstype
, 0);
1047 b
= gimple_assign_rhs1 (stmt
);
1048 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1049 gimple_call_set_lhs (g
, lhs
);
1050 gsi_replace (&gsi
, g
, false);
1053 /* Transform i = ABS_EXPR<u>;
1055 _N = UBSAN_CHECK_SUB (0, u);
1056 i = ABS_EXPR<_N>; */
1057 a
= build_int_cst (lhstype
, 0);
1058 b
= gimple_assign_rhs1 (stmt
);
1059 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1060 a
= make_ssa_name (lhstype
, NULL
);
1061 gimple_call_set_lhs (g
, a
);
1062 gimple_set_location (g
, gimple_location (stmt
));
1063 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1064 gimple_assign_set_rhs1 (stmt
, a
);
1072 /* Instrument loads from (non-bitfield) bool and C++ enum values
1073 to check if the memory value is outside of the range of the valid
1077 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1079 gimple stmt
= gsi_stmt (*gsi
);
1080 tree rhs
= gimple_assign_rhs1 (stmt
);
1081 tree type
= TREE_TYPE (rhs
);
1082 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1084 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
1086 minv
= boolean_false_node
;
1087 maxv
= boolean_true_node
;
1089 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1090 && (flag_sanitize
& SANITIZE_ENUM
)
1091 && TREE_TYPE (type
) != NULL_TREE
1092 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1093 && (TYPE_PRECISION (TREE_TYPE (type
))
1094 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1096 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1097 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1102 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1103 HOST_WIDE_INT bitsize
, bitpos
;
1105 enum machine_mode mode
;
1106 int volatilep
= 0, unsignedp
= 0;
1107 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1108 &unsignedp
, &volatilep
, false);
1109 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1111 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
1112 || (bitpos
% modebitsize
) != 0
1113 || bitsize
!= modebitsize
1114 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1115 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1118 location_t loc
= gimple_location (stmt
);
1119 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1120 tree atype
= reference_alias_ptr_type (rhs
);
1121 gimple g
= gimple_build_assign (make_ssa_name (ptype
, NULL
),
1122 build_fold_addr_expr (rhs
));
1123 gimple_set_location (g
, loc
);
1124 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1125 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1126 build_int_cst (atype
, 0));
1127 tree urhs
= make_ssa_name (utype
, NULL
);
1128 g
= gimple_build_assign (urhs
, mem
);
1129 gimple_set_location (g
, loc
);
1130 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1131 minv
= fold_convert (utype
, minv
);
1132 maxv
= fold_convert (utype
, maxv
);
1133 if (!integer_zerop (minv
))
1135 g
= gimple_build_assign_with_ops (MINUS_EXPR
,
1136 make_ssa_name (utype
, NULL
),
1138 gimple_set_location (g
, loc
);
1139 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1142 gimple_stmt_iterator gsi2
= *gsi
;
1143 basic_block then_bb
, fallthru_bb
;
1144 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1145 &then_bb
, &fallthru_bb
);
1146 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1147 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1148 NULL_TREE
, NULL_TREE
);
1149 gimple_set_location (g
, loc
);
1150 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1152 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
, NULL_TREE
);
1155 gsi2
= gsi_after_labels (then_bb
);
1156 if (flag_sanitize_undefined_trap_on_error
)
1157 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1160 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1161 ubsan_type_descriptor (type
), NULL_TREE
,
1163 data
= build_fold_addr_expr_loc (loc
, data
);
1164 enum built_in_function bcode
1165 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1166 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1167 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1168 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1169 tree fn
= builtin_decl_explicit (bcode
);
1171 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
1172 true, NULL_TREE
, true,
1174 g
= gimple_build_call (fn
, 2, data
, val
);
1176 gimple_set_location (g
, loc
);
1177 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1178 *gsi
= gsi_for_stmt (stmt
);
1181 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1182 destination, EXPR is floating-point expression. */
1185 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
)
1187 tree expr_type
= TREE_TYPE (expr
);
1188 tree t
, tt
, fn
, min
, max
;
1189 enum machine_mode mode
= TYPE_MODE (expr_type
);
1190 int prec
= TYPE_PRECISION (type
);
1191 bool uns_p
= TYPE_UNSIGNED (type
);
1193 /* Float to integer conversion first truncates toward zero, so
1194 even signed char c = 127.875f; is not problematic.
1195 Therefore, we should complain only if EXPR is unordered or smaller
1196 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1197 TYPE_MAX_VALUE + 1.0. */
1198 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1200 /* For maximum, TYPE_MAX_VALUE might not be representable
1201 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1202 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1203 either representable or infinity. */
1204 REAL_VALUE_TYPE maxval
= dconst1
;
1205 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1206 real_convert (&maxval
, mode
, &maxval
);
1207 max
= build_real (expr_type
, maxval
);
1209 /* For unsigned, assume -1.0 is always representable. */
1211 min
= build_minus_one_cst (expr_type
);
1214 /* TYPE_MIN_VALUE is generally representable (or -inf),
1215 but TYPE_MIN_VALUE - 1.0 might not be. */
1216 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1217 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1218 real_convert (&minval
, mode
, &minval
);
1219 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1220 real_convert (&minval2
, mode
, &minval2
);
1221 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1222 && !real_isinf (&minval
))
1224 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1225 rounds to TYPE_MIN_VALUE, we need to subtract
1226 more. As REAL_MODE_FORMAT (mode)->p is the number
1227 of base digits, we want to subtract a number that
1228 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1229 times smaller than minval. */
1231 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1232 SET_REAL_EXP (&minval2
,
1233 REAL_EXP (&minval2
) + prec
- 1
1234 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1235 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1236 real_convert (&minval2
, mode
, &minval2
);
1238 min
= build_real (expr_type
, minval2
);
1241 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1243 /* For _Decimal128 up to 34 decimal digits, - sign,
1244 dot, e, exponent. */
1247 int p
= REAL_MODE_FORMAT (mode
)->p
;
1248 REAL_VALUE_TYPE maxval
, minval
;
1250 /* Use mpfr_snprintf rounding to compute the smallest
1251 representable decimal number greater or equal than
1252 1 << (prec - !uns_p). */
1253 mpfr_init2 (m
, prec
+ 2);
1254 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1255 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1256 decimal_real_from_string (&maxval
, buf
);
1257 max
= build_real (expr_type
, maxval
);
1259 /* For unsigned, assume -1.0 is always representable. */
1261 min
= build_minus_one_cst (expr_type
);
1264 /* Use mpfr_snprintf rounding to compute the largest
1265 representable decimal number less or equal than
1266 (-1 << (prec - 1)) - 1. */
1267 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1268 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1269 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1270 decimal_real_from_string (&minval
, buf
);
1271 min
= build_real (expr_type
, minval
);
1278 if (flag_sanitize_undefined_trap_on_error
)
1279 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1282 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1283 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1284 NULL
, ubsan_type_descriptor (expr_type
),
1285 ubsan_type_descriptor (type
), NULL_TREE
,
1287 enum built_in_function bcode
1288 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1289 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1290 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1291 fn
= builtin_decl_explicit (bcode
);
1292 fn
= build_call_expr_loc (loc
, fn
, 2,
1293 build_fold_addr_expr_loc (loc
, data
),
1294 ubsan_encode_value (expr
, false));
1297 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1298 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1299 return fold_build3 (COND_EXPR
, void_type_node
,
1300 fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
),
1301 fn
, integer_zero_node
);
1304 /* Instrument values passed to function arguments with nonnull attribute. */
1307 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1309 gimple stmt
= gsi_stmt (*gsi
);
1311 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1312 while for nonnull sanitization it is clear. */
1313 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1314 flag_delete_null_pointer_checks
= 1;
1315 loc
[0] = gimple_location (stmt
);
1316 loc
[1] = UNKNOWN_LOCATION
;
1317 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1319 tree arg
= gimple_call_arg (stmt
, i
);
1320 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1321 && infer_nonnull_range (stmt
, arg
, false, true))
1324 if (!is_gimple_val (arg
))
1326 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
), NULL
),
1328 gimple_set_location (g
, loc
[0]);
1329 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1330 arg
= gimple_assign_lhs (g
);
1333 basic_block then_bb
, fallthru_bb
;
1334 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1335 &then_bb
, &fallthru_bb
);
1336 g
= gimple_build_cond (EQ_EXPR
, arg
,
1337 build_zero_cst (TREE_TYPE (arg
)),
1338 NULL_TREE
, NULL_TREE
);
1339 gimple_set_location (g
, loc
[0]);
1340 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1342 *gsi
= gsi_after_labels (then_bb
);
1343 if (flag_sanitize_undefined_trap_on_error
)
1344 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1347 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1349 build_int_cst (integer_type_node
,
1352 data
= build_fold_addr_expr_loc (loc
[0], data
);
1353 enum built_in_function bcode
1354 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1355 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1356 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1357 tree fn
= builtin_decl_explicit (bcode
);
1359 g
= gimple_build_call (fn
, 1, data
);
1361 gimple_set_location (g
, loc
[0]);
1362 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1364 *gsi
= gsi_for_stmt (stmt
);
1366 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1369 /* Instrument returns in functions with returns_nonnull attribute. */
1372 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1374 gimple stmt
= gsi_stmt (*gsi
);
1376 tree arg
= gimple_return_retval (stmt
);
1377 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1378 while for nonnull return sanitization it is clear. */
1379 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1380 flag_delete_null_pointer_checks
= 1;
1381 loc
[0] = gimple_location (stmt
);
1382 loc
[1] = UNKNOWN_LOCATION
;
1384 && POINTER_TYPE_P (TREE_TYPE (arg
))
1385 && is_gimple_val (arg
)
1386 && infer_nonnull_range (stmt
, arg
, false, true))
1388 basic_block then_bb
, fallthru_bb
;
1389 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1390 &then_bb
, &fallthru_bb
);
1391 gimple g
= gimple_build_cond (EQ_EXPR
, arg
,
1392 build_zero_cst (TREE_TYPE (arg
)),
1393 NULL_TREE
, NULL_TREE
);
1394 gimple_set_location (g
, loc
[0]);
1395 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1397 *gsi
= gsi_after_labels (then_bb
);
1398 if (flag_sanitize_undefined_trap_on_error
)
1399 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1402 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
1403 2, loc
, NULL_TREE
, NULL_TREE
);
1404 data
= build_fold_addr_expr_loc (loc
[0], data
);
1405 enum built_in_function bcode
1406 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1407 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1408 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
1409 tree fn
= builtin_decl_explicit (bcode
);
1411 g
= gimple_build_call (fn
, 1, data
);
1413 gimple_set_location (g
, loc
[0]);
1414 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1415 *gsi
= gsi_for_stmt (stmt
);
1417 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1420 /* Instrument memory references. Here we check whether the pointer
1421 points to an out-of-bounds location. */
1424 instrument_object_size (gimple_stmt_iterator
*gsi
, bool is_lhs
)
1426 gimple stmt
= gsi_stmt (*gsi
);
1427 location_t loc
= gimple_location (stmt
);
1428 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
1430 HOST_WIDE_INT size_in_bytes
;
1432 type
= TREE_TYPE (t
);
1433 if (VOID_TYPE_P (type
))
1436 switch (TREE_CODE (t
))
1439 if (TREE_CODE (t
) == COMPONENT_REF
1440 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
1442 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
1443 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
1458 size_in_bytes
= int_size_in_bytes (type
);
1459 if (size_in_bytes
<= 0)
1462 HOST_WIDE_INT bitsize
, bitpos
;
1464 enum machine_mode mode
;
1465 int volatilep
= 0, unsignedp
= 0;
1466 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1467 &unsignedp
, &volatilep
, false);
1469 if (bitpos
% BITS_PER_UNIT
!= 0
1470 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
1473 bool decl_p
= DECL_P (inner
);
1474 tree base
= decl_p
? inner
: TREE_OPERAND (inner
, 0);
1475 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
1477 while (TREE_CODE (base
) == SSA_NAME
)
1479 gimple def_stmt
= SSA_NAME_DEF_STMT (base
);
1480 if (gimple_assign_ssa_name_copy_p (def_stmt
)
1481 || (gimple_assign_cast_p (def_stmt
)
1482 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
1483 || (is_gimple_assign (def_stmt
)
1484 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
1485 base
= gimple_assign_rhs1 (def_stmt
);
1490 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1494 tree base_addr
= base
;
1496 base_addr
= build1 (ADDR_EXPR
,
1497 build_pointer_type (TREE_TYPE (base
)), base
);
1498 unsigned HOST_WIDE_INT size
= compute_builtin_object_size (base_addr
, 0);
1499 if (size
!= (unsigned HOST_WIDE_INT
) -1)
1500 sizet
= build_int_cst (sizetype
, size
);
1503 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
1504 loc
= input_location
;
1505 /* Generate __builtin_object_size call. */
1506 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
1507 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
1509 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
1515 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1517 /* ptr + sizeof (*ptr) - base */
1518 t
= fold_build2 (MINUS_EXPR
, sizetype
,
1519 fold_convert (pointer_sized_int_node
, ptr
),
1520 fold_convert (pointer_sized_int_node
, base_addr
));
1521 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
1523 /* Perhaps we can omit the check. */
1524 if (TREE_CODE (t
) == INTEGER_CST
1525 && TREE_CODE (sizet
) == INTEGER_CST
1526 && tree_int_cst_le (t
, sizet
))
1529 /* Nope. Emit the check. */
1530 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1532 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
1534 tree ckind
= build_int_cst (unsigned_char_type_node
,
1535 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
1536 gimple g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
1537 ptr
, t
, sizet
, ckind
);
1538 gimple_set_location (g
, loc
);
1539 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1544 const pass_data pass_data_ubsan
=
1546 GIMPLE_PASS
, /* type */
1548 OPTGROUP_NONE
, /* optinfo_flags */
1549 TV_TREE_UBSAN
, /* tv_id */
1550 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1551 0, /* properties_provided */
1552 0, /* properties_destroyed */
1553 0, /* todo_flags_start */
1554 TODO_update_ssa
, /* todo_flags_finish */
1557 class pass_ubsan
: public gimple_opt_pass
1560 pass_ubsan (gcc::context
*ctxt
)
1561 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1564 /* opt_pass methods: */
1565 virtual bool gate (function
*)
1567 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1568 | SANITIZE_BOOL
| SANITIZE_ENUM
1569 | SANITIZE_ALIGNMENT
1570 | SANITIZE_NONNULL_ATTRIBUTE
1571 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1572 | SANITIZE_OBJECT_SIZE
)
1573 && current_function_decl
!= NULL_TREE
1574 && !lookup_attribute ("no_sanitize_undefined",
1575 DECL_ATTRIBUTES (current_function_decl
));
1578 virtual unsigned int execute (function
*);
1580 }; // class pass_ubsan
1583 pass_ubsan::execute (function
*fun
)
1586 gimple_stmt_iterator gsi
;
1588 initialize_sanitizer_builtins ();
1590 FOR_EACH_BB_FN (bb
, fun
)
1592 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1594 gimple stmt
= gsi_stmt (gsi
);
1595 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
1601 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
1602 && is_gimple_assign (stmt
))
1603 instrument_si_overflow (gsi
);
1605 if (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1607 if (gimple_store_p (stmt
))
1608 instrument_null (gsi
, true);
1609 if (gimple_assign_load_p (stmt
))
1610 instrument_null (gsi
, false);
1613 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
1614 && gimple_assign_load_p (stmt
))
1616 instrument_bool_enum_load (&gsi
);
1617 bb
= gimple_bb (stmt
);
1620 if ((flag_sanitize
& SANITIZE_NONNULL_ATTRIBUTE
)
1621 && is_gimple_call (stmt
)
1622 && !gimple_call_internal_p (stmt
))
1624 instrument_nonnull_arg (&gsi
);
1625 bb
= gimple_bb (stmt
);
1628 if ((flag_sanitize
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1629 && gimple_code (stmt
) == GIMPLE_RETURN
)
1631 instrument_nonnull_return (&gsi
);
1632 bb
= gimple_bb (stmt
);
1635 if (flag_sanitize
& SANITIZE_OBJECT_SIZE
)
1637 if (gimple_store_p (stmt
))
1638 instrument_object_size (&gsi
, true);
1639 if (gimple_assign_load_p (stmt
))
1640 instrument_object_size (&gsi
, false);
1652 make_pass_ubsan (gcc::context
*ctxt
)
1654 return new pass_ubsan (ctxt
);
1657 #include "gt-ubsan.h"