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 "tree-pass.h"
29 #include "tree-ssa-alias.h"
30 #include "tree-pretty-print.h"
31 #include "internal-fn.h"
32 #include "gimple-expr.h"
34 #include "gimple-iterator.h"
35 #include "gimple-ssa.h"
36 #include "gimple-walk.h"
43 #include "c-family/c-common.h"
46 #include "tree-ssanames.h"
48 #include "gimplify-me.h"
50 /* Map from a tree to a VAR_DECL tree. */
52 struct GTY(()) tree_type_map
{
53 struct tree_map_base type
;
57 #define tree_type_map_eq tree_map_base_eq
58 #define tree_type_map_marked_p tree_map_base_marked_p
60 /* Hash from a tree in a tree_type_map. */
63 tree_type_map_hash (const void *item
)
65 return TYPE_UID (((const struct tree_type_map
*)item
)->type
.from
);
68 static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map
)))
69 htab_t decl_tree_for_type
;
71 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
74 decl_for_type_lookup (tree type
)
76 /* If the hash table is not initialized yet, create it now. */
77 if (decl_tree_for_type
== NULL
)
79 decl_tree_for_type
= htab_create_ggc (10, tree_type_map_hash
,
81 /* That also means we don't have to bother with the lookup. */
85 struct tree_type_map
*h
, in
;
88 h
= (struct tree_type_map
*)
89 htab_find_with_hash (decl_tree_for_type
, &in
, TYPE_UID (type
));
90 return h
? h
->decl
: NULL_TREE
;
93 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
96 decl_for_type_insert (tree type
, tree decl
)
98 struct tree_type_map
*h
;
101 h
= ggc_alloc_tree_type_map ();
104 slot
= htab_find_slot_with_hash (decl_tree_for_type
, h
, TYPE_UID (type
),
106 *(struct tree_type_map
**) slot
= h
;
109 /* Helper routine, which encodes a value in the pointer_sized_int_node.
110 Arguments with precision <= POINTER_SIZE are passed directly,
111 the rest is passed by reference. T is a value we are to encode.
112 IN_EXPAND_P is true if this function is called during expansion. */
115 ubsan_encode_value (tree t
, bool in_expand_p
)
117 tree type
= TREE_TYPE (t
);
118 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
119 if (bitsize
<= POINTER_SIZE
)
120 switch (TREE_CODE (type
))
125 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
128 tree itype
= build_nonstandard_integer_type (bitsize
, true);
129 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
130 return fold_convert (pointer_sized_int_node
, t
);
137 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
139 /* The reason for this is that we don't want to pessimize
140 code by making vars unnecessarily addressable. */
141 tree var
= create_tmp_var (type
, NULL
);
142 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
146 = assign_stack_temp_for_type (TYPE_MODE (type
),
147 GET_MODE_SIZE (TYPE_MODE (type
)),
149 SET_DECL_RTL (var
, mem
);
150 expand_assignment (var
, t
, false);
151 return build_fold_addr_expr (var
);
153 t
= build_fold_addr_expr (var
);
154 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
157 return build_fold_addr_expr (t
);
162 struct __ubsan_type_descriptor
164 unsigned short __typekind;
165 unsigned short __typeinfo;
171 ubsan_type_descriptor_type (void)
173 static const char *field_names
[3]
174 = { "__typekind", "__typeinfo", "__typename" };
176 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
177 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
179 ret
= make_node (RECORD_TYPE
);
180 for (int i
= 0; i
< 3; i
++)
182 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
183 get_identifier (field_names
[i
]),
184 (i
== 2) ? flex_arr_type
185 : short_unsigned_type_node
);
186 DECL_CONTEXT (fields
[i
]) = ret
;
188 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
190 TYPE_FIELDS (ret
) = fields
[0];
191 TYPE_NAME (ret
) = get_identifier ("__ubsan_type_descriptor");
197 struct __ubsan_source_location
199 const char *__filename;
201 unsigned int __column;
206 ubsan_source_location_type (void)
208 static const char *field_names
[3]
209 = { "__filename", "__line", "__column" };
211 tree const_char_type
= build_qualified_type (char_type_node
,
214 ret
= make_node (RECORD_TYPE
);
215 for (int i
= 0; i
< 3; i
++)
217 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
218 get_identifier (field_names
[i
]),
219 (i
== 0) ? build_pointer_type (const_char_type
)
220 : unsigned_type_node
);
221 DECL_CONTEXT (fields
[i
]) = ret
;
223 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
225 TYPE_FIELDS (ret
) = fields
[0];
226 TYPE_NAME (ret
) = get_identifier ("__ubsan_source_location");
231 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
232 type with its fields filled from a location_t LOC. */
235 ubsan_source_location (location_t loc
)
237 expanded_location xloc
;
238 tree type
= ubsan_source_location_type ();
240 xloc
= expand_location (loc
);
242 /* Fill in the values from LOC. */
243 size_t len
= strlen (xloc
.file
);
244 tree str
= build_string (len
+ 1, xloc
.file
);
245 TREE_TYPE (str
) = build_array_type (char_type_node
,
246 build_index_type (size_int (len
)));
247 TREE_READONLY (str
) = 1;
248 TREE_STATIC (str
) = 1;
249 str
= build_fold_addr_expr (str
);
250 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
251 build_int_cst (unsigned_type_node
,
252 xloc
.line
), NULL_TREE
,
253 build_int_cst (unsigned_type_node
,
255 TREE_CONSTANT (ctor
) = 1;
256 TREE_STATIC (ctor
) = 1;
261 /* This routine returns a magic number for TYPE. */
263 static unsigned short
264 get_ubsan_type_info_for_type (tree type
)
266 gcc_assert (TYPE_SIZE (type
) && tree_fits_uhwi_p (TYPE_SIZE (type
)));
267 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
268 gcc_assert (prec
!= -1);
269 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
272 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
273 descriptor. It first looks into the hash table; if not found,
274 create the VAR_DECL, put it into the hash table and return the
275 ADDR_EXPR of it. TYPE describes a particular type. WANT_POINTER_TYPE_P
276 means whether we are interested in the pointer type and not the pointer
280 ubsan_type_descriptor (tree type
, bool want_pointer_type_p
)
282 /* See through any typedefs. */
283 type
= TYPE_MAIN_VARIANT (type
);
285 tree decl
= decl_for_type_lookup (type
);
286 /* It is possible that some of the earlier created DECLs were found
287 unused, in that case they weren't emitted and varpool_get_node
288 returns NULL node on them. But now we really need them. Thus,
290 if (decl
!= NULL_TREE
&& varpool_get_node (decl
))
291 return build_fold_addr_expr (decl
);
293 tree dtype
= ubsan_type_descriptor_type ();
295 const char *tname
= NULL
;
297 unsigned char deref_depth
= 0;
298 unsigned short tkind
, tinfo
;
300 /* Get the name of the type, or the name of the pointer type. */
301 if (want_pointer_type_p
)
303 gcc_assert (POINTER_TYPE_P (type
));
304 type2
= TREE_TYPE (type
);
306 /* Remove any '*' operators from TYPE. */
307 while (POINTER_TYPE_P (type2
))
308 deref_depth
++, type2
= TREE_TYPE (type2
);
310 if (TREE_CODE (type2
) == METHOD_TYPE
)
311 type2
= TYPE_METHOD_BASETYPE (type2
);
314 /* If an array, get its type. */
315 type2
= strip_array_types (type2
);
317 if (TYPE_NAME (type2
) != NULL
)
319 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
320 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
322 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
326 /* We weren't able to determine the type name. */
329 /* Decorate the type name with '', '*', "struct", or "union". */
330 pretty_name
= (char *) alloca (strlen (tname
) + 16 + deref_depth
);
331 if (want_pointer_type_p
)
333 int pos
= sprintf (pretty_name
, "'%s%s%s%s%s%s%s",
334 TYPE_VOLATILE (type2
) ? "volatile " : "",
335 TYPE_READONLY (type2
) ? "const " : "",
336 TYPE_RESTRICT (type2
) ? "restrict " : "",
337 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
338 TREE_CODE (type2
) == RECORD_TYPE
340 : TREE_CODE (type2
) == UNION_TYPE
341 ? "union " : "", tname
,
342 deref_depth
== 0 ? "" : " ");
343 while (deref_depth
-- > 0)
344 pretty_name
[pos
++] = '*';
345 pretty_name
[pos
++] = '\'';
346 pretty_name
[pos
] = '\0';
349 sprintf (pretty_name
, "'%s'", tname
);
351 switch (TREE_CODE (type
))
365 tinfo
= get_ubsan_type_info_for_type (type
);
367 /* Create a new VAR_DECL of type descriptor. */
369 static unsigned int type_var_id_num
;
370 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
371 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
373 TREE_STATIC (decl
) = 1;
374 TREE_PUBLIC (decl
) = 0;
375 DECL_ARTIFICIAL (decl
) = 1;
376 DECL_IGNORED_P (decl
) = 1;
377 DECL_EXTERNAL (decl
) = 0;
379 size_t len
= strlen (pretty_name
);
380 tree str
= build_string (len
+ 1, pretty_name
);
381 TREE_TYPE (str
) = build_array_type (char_type_node
,
382 build_index_type (size_int (len
)));
383 TREE_READONLY (str
) = 1;
384 TREE_STATIC (str
) = 1;
385 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
386 build_int_cst (short_unsigned_type_node
,
388 build_int_cst (short_unsigned_type_node
,
389 tinfo
), NULL_TREE
, str
);
390 TREE_CONSTANT (ctor
) = 1;
391 TREE_STATIC (ctor
) = 1;
392 DECL_INITIAL (decl
) = ctor
;
393 rest_of_decl_compilation (decl
, 1, 0);
395 /* Save the VAR_DECL into the hash table. */
396 decl_for_type_insert (type
, decl
);
398 return build_fold_addr_expr (decl
);
401 /* Create a structure for the ubsan library. NAME is a name of the new
402 structure. The arguments in ... are of __ubsan_type_descriptor type
403 and there are at most two of them. MISMATCH are data used by ubsan
407 ubsan_create_data (const char *name
, location_t loc
,
408 const struct ubsan_mismatch_data
*mismatch
, ...)
413 vec
<tree
, va_gc
> *saved_args
= NULL
;
416 /* Firstly, create a pointer to type descriptor type. */
417 tree td_type
= ubsan_type_descriptor_type ();
418 TYPE_READONLY (td_type
) = 1;
419 td_type
= build_pointer_type (td_type
);
420 loc
= LOCATION_LOCUS (loc
);
422 /* Create the structure type. */
423 ret
= make_node (RECORD_TYPE
);
424 if (loc
!= UNKNOWN_LOCATION
)
426 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
427 ubsan_source_location_type ());
428 DECL_CONTEXT (fields
[i
]) = ret
;
432 va_start (args
, mismatch
);
433 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
434 i
++, t
= va_arg (args
, tree
))
436 gcc_checking_assert (i
< 3);
437 /* Save the tree arguments for later use. */
438 vec_safe_push (saved_args
, t
);
439 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
441 DECL_CONTEXT (fields
[i
]) = ret
;
443 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
447 if (mismatch
!= NULL
)
449 /* We have to add two more decls. */
450 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
451 pointer_sized_int_node
);
452 DECL_CONTEXT (fields
[i
]) = ret
;
453 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
456 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
457 unsigned_char_type_node
);
458 DECL_CONTEXT (fields
[i
]) = ret
;
459 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
463 TYPE_FIELDS (ret
) = fields
[0];
464 TYPE_NAME (ret
) = get_identifier (name
);
467 /* Now, fill in the type. */
469 static unsigned int ubsan_var_id_num
;
470 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
471 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
473 TREE_STATIC (var
) = 1;
474 TREE_PUBLIC (var
) = 0;
475 DECL_ARTIFICIAL (var
) = 1;
476 DECL_IGNORED_P (var
) = 1;
477 DECL_EXTERNAL (var
) = 0;
479 vec
<constructor_elt
, va_gc
> *v
;
481 tree ctor
= build_constructor (ret
, v
);
483 /* If desirable, set the __ubsan_source_location element. */
484 if (loc
!= UNKNOWN_LOCATION
)
485 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
487 size_t nelts
= vec_safe_length (saved_args
);
488 for (i
= 0; i
< nelts
; i
++)
490 t
= (*saved_args
)[i
];
491 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
494 if (mismatch
!= NULL
)
496 /* Append the pointer data. */
497 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, mismatch
->align
);
498 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, mismatch
->ckind
);
501 TREE_CONSTANT (ctor
) = 1;
502 TREE_STATIC (ctor
) = 1;
503 DECL_INITIAL (var
) = ctor
;
504 rest_of_decl_compilation (var
, 1, 0);
509 /* Instrument the __builtin_unreachable call. We just call the libubsan
513 ubsan_instrument_unreachable (location_t loc
)
515 tree data
= ubsan_create_data ("__ubsan_unreachable_data", loc
, NULL
,
517 tree t
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
518 return build_call_expr_loc (loc
, t
, 1, build_fold_addr_expr_loc (loc
, data
));
521 /* Return true if T is a call to a libubsan routine. */
524 is_ubsan_builtin_p (tree t
)
526 gcc_checking_assert (TREE_CODE (t
) == FUNCTION_DECL
);
527 return strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
528 "__builtin___ubsan_", 18) == 0;
531 /* Expand UBSAN_NULL internal call. */
534 ubsan_expand_null_ifn (gimple_stmt_iterator gsi
)
536 gimple stmt
= gsi_stmt (gsi
);
537 location_t loc
= gimple_location (stmt
);
538 gcc_assert (gimple_call_num_args (stmt
) == 2);
539 tree ptr
= gimple_call_arg (stmt
, 0);
540 tree ckind
= gimple_call_arg (stmt
, 1);
542 basic_block cur_bb
= gsi_bb (gsi
);
544 /* Split the original block holding the pointer dereference. */
545 edge e
= split_block (cur_bb
, stmt
);
547 /* Get a hold on the 'condition block', the 'then block' and the
549 basic_block cond_bb
= e
->src
;
550 basic_block fallthru_bb
= e
->dest
;
551 basic_block then_bb
= create_empty_bb (cond_bb
);
554 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
555 loops_state_set (LOOPS_NEED_FIXUP
);
558 /* Make an edge coming from the 'cond block' into the 'then block';
559 this edge is unlikely taken, so set up the probability accordingly. */
560 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
561 e
->probability
= PROB_VERY_UNLIKELY
;
563 /* Connect 'then block' with the 'else block'. This is needed
564 as the ubsan routines we call in the 'then block' are not noreturn.
565 The 'then block' only has one outcoming edge. */
566 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
568 /* Set up the fallthrough basic block. */
569 e
= find_edge (cond_bb
, fallthru_bb
);
570 e
->flags
= EDGE_FALSE_VALUE
;
571 e
->count
= cond_bb
->count
;
572 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
574 /* Update dominance info for the newly created then_bb; note that
575 fallthru_bb's dominance info has already been updated by
577 if (dom_info_available_p (CDI_DOMINATORS
))
578 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
580 /* Put the ubsan builtin call into the newly created BB. */
581 tree fn
= builtin_decl_implicit (BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
);
582 const struct ubsan_mismatch_data m
583 = { build_zero_cst (pointer_sized_int_node
), ckind
};
584 tree data
= ubsan_create_data ("__ubsan_null_data",
586 ubsan_type_descriptor (TREE_TYPE (ptr
), true),
588 data
= build_fold_addr_expr_loc (loc
, data
);
589 gimple g
= gimple_build_call (fn
, 2, data
,
590 build_zero_cst (pointer_sized_int_node
));
591 gimple_set_location (g
, loc
);
592 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
593 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
595 /* Unlink the UBSAN_NULLs vops before replacing it. */
596 unlink_stmt_vdef (stmt
);
598 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
599 NULL_TREE
, NULL_TREE
);
600 gimple_set_location (g
, loc
);
602 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
603 gsi_replace (&gsi
, g
, false);
606 /* Instrument a member call. We check whether 'this' is NULL. */
609 instrument_member_call (gimple_stmt_iterator
*iter
)
611 tree this_parm
= gimple_call_arg (gsi_stmt (*iter
), 0);
612 tree kind
= build_int_cst (unsigned_char_type_node
, UBSAN_MEMBER_CALL
);
613 gimple g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 2, this_parm
, kind
);
614 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
615 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
618 /* Instrument a memory reference. T is the pointer, IS_LHS says
619 whether the pointer is on the left hand side of the assignment. */
622 instrument_mem_ref (tree t
, gimple_stmt_iterator
*iter
, bool is_lhs
)
624 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
625 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t
))))
626 ikind
= UBSAN_MEMBER_ACCESS
;
627 tree kind
= build_int_cst (unsigned_char_type_node
, ikind
);
628 gimple g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 2, t
, kind
);
629 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
630 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
633 /* Perform the pointer instrumentation. */
636 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
638 gimple stmt
= gsi_stmt (gsi
);
639 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
640 t
= get_base_address (t
);
641 const enum tree_code code
= TREE_CODE (t
);
643 && TREE_CODE (TREE_OPERAND (t
, 0)) == SSA_NAME
)
644 instrument_mem_ref (TREE_OPERAND (t
, 0), &gsi
, is_lhs
);
645 else if (code
== ADDR_EXPR
646 && POINTER_TYPE_P (TREE_TYPE (t
))
647 && TREE_CODE (TREE_TYPE (TREE_TYPE (t
))) == METHOD_TYPE
)
648 instrument_member_call (&gsi
);
651 /* Build an ubsan builtin call for the signed-integer-overflow
652 sanitization. CODE says what kind of builtin are we building,
653 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
654 are operands of the binary operation. */
657 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
660 tree data
= ubsan_create_data ("__ubsan_overflow_data", loc
, NULL
,
661 ubsan_type_descriptor (lhstype
, false),
663 enum built_in_function fn_code
;
668 fn_code
= BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
;
671 fn_code
= BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
;
674 fn_code
= BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
;
677 fn_code
= BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
;
682 tree fn
= builtin_decl_explicit (fn_code
);
683 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
684 build_fold_addr_expr_loc (loc
, data
),
685 ubsan_encode_value (op0
, true),
686 op1
? ubsan_encode_value (op1
, true)
690 /* Perform the signed integer instrumentation. GSI is the iterator
691 pointing at statement we are trying to instrument. */
694 instrument_si_overflow (gimple_stmt_iterator gsi
)
696 gimple stmt
= gsi_stmt (gsi
);
697 tree_code code
= gimple_assign_rhs_code (stmt
);
698 tree lhs
= gimple_assign_lhs (stmt
);
699 tree lhstype
= TREE_TYPE (lhs
);
703 /* If this is not a signed operation, don't instrument anything here.
704 Also punt on bit-fields. */
705 if (!INTEGRAL_TYPE_P (lhstype
)
706 || TYPE_OVERFLOW_WRAPS (lhstype
)
707 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
718 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
719 a
= gimple_assign_rhs1 (stmt
);
720 b
= gimple_assign_rhs2 (stmt
);
721 g
= gimple_build_call_internal (code
== PLUS_EXPR
722 ? IFN_UBSAN_CHECK_ADD
724 ? IFN_UBSAN_CHECK_SUB
725 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
726 gimple_call_set_lhs (g
, lhs
);
727 gsi_replace (&gsi
, g
, false);
732 i = UBSAN_CHECK_SUB (0, u); */
733 a
= build_int_cst (lhstype
, 0);
734 b
= gimple_assign_rhs1 (stmt
);
735 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
736 gimple_call_set_lhs (g
, lhs
);
737 gsi_replace (&gsi
, g
, false);
744 /* Instrument loads from (non-bitfield) bool and C++ enum values
745 to check if the memory value is outside of the range of the valid
749 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
751 gimple stmt
= gsi_stmt (*gsi
);
752 tree rhs
= gimple_assign_rhs1 (stmt
);
753 tree type
= TREE_TYPE (rhs
);
754 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
756 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
758 minv
= boolean_false_node
;
759 maxv
= boolean_true_node
;
761 else if (TREE_CODE (type
) == ENUMERAL_TYPE
762 && (flag_sanitize
& SANITIZE_ENUM
)
763 && TREE_TYPE (type
) != NULL_TREE
764 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
765 && (TYPE_PRECISION (TREE_TYPE (type
))
766 < GET_MODE_PRECISION (TYPE_MODE (type
))))
768 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
769 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
774 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
775 HOST_WIDE_INT bitsize
, bitpos
;
777 enum machine_mode mode
;
778 int volatilep
= 0, unsignedp
= 0;
779 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
780 &unsignedp
, &volatilep
, false);
781 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
783 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
784 || (bitpos
% modebitsize
) != 0
785 || bitsize
!= modebitsize
786 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
787 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
790 location_t loc
= gimple_location (stmt
);
791 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
792 tree atype
= reference_alias_ptr_type (rhs
);
793 gimple g
= gimple_build_assign (make_ssa_name (ptype
, NULL
),
794 build_fold_addr_expr (rhs
));
795 gimple_set_location (g
, loc
);
796 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
797 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
798 build_int_cst (atype
, 0));
799 tree urhs
= make_ssa_name (utype
, NULL
);
800 g
= gimple_build_assign (urhs
, mem
);
801 gimple_set_location (g
, loc
);
802 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
803 minv
= fold_convert (utype
, minv
);
804 maxv
= fold_convert (utype
, maxv
);
805 if (!integer_zerop (minv
))
807 g
= gimple_build_assign_with_ops (MINUS_EXPR
,
808 make_ssa_name (utype
, NULL
),
810 gimple_set_location (g
, loc
);
811 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
814 gimple_stmt_iterator gsi2
= *gsi
;
815 basic_block then_bb
, fallthru_bb
;
816 *gsi
= create_cond_insert_point (gsi
, true, false, true,
817 &then_bb
, &fallthru_bb
);
818 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
819 int_const_binop (MINUS_EXPR
, maxv
, minv
),
820 NULL_TREE
, NULL_TREE
);
821 gimple_set_location (g
, loc
);
822 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
824 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
, NULL_TREE
);
827 tree data
= ubsan_create_data ("__ubsan_invalid_value_data",
829 ubsan_type_descriptor (type
, false),
831 data
= build_fold_addr_expr_loc (loc
, data
);
832 tree fn
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
);
834 gsi2
= gsi_after_labels (then_bb
);
835 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
836 true, NULL_TREE
, true, GSI_SAME_STMT
);
837 g
= gimple_build_call (fn
, 2, data
, val
);
838 gimple_set_location (g
, loc
);
839 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
842 /* Gate and execute functions for ubsan pass. */
848 gimple_stmt_iterator gsi
;
850 FOR_EACH_BB_FN (bb
, cfun
)
852 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
854 gimple stmt
= gsi_stmt (gsi
);
855 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
861 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
862 && is_gimple_assign (stmt
))
863 instrument_si_overflow (gsi
);
865 if (flag_sanitize
& SANITIZE_NULL
)
867 if (gimple_store_p (stmt
))
868 instrument_null (gsi
, true);
869 if (gimple_assign_load_p (stmt
))
870 instrument_null (gsi
, false);
873 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
874 && gimple_assign_load_p (stmt
))
875 instrument_bool_enum_load (&gsi
);
886 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
887 | SANITIZE_BOOL
| SANITIZE_ENUM
);
892 const pass_data pass_data_ubsan
=
894 GIMPLE_PASS
, /* type */
896 OPTGROUP_NONE
, /* optinfo_flags */
898 true, /* has_execute */
899 TV_TREE_UBSAN
, /* tv_id */
900 ( PROP_cfg
| PROP_ssa
), /* properties_required */
901 0, /* properties_provided */
902 0, /* properties_destroyed */
903 0, /* todo_flags_start */
904 TODO_update_ssa
, /* todo_flags_finish */
907 class pass_ubsan
: public gimple_opt_pass
910 pass_ubsan (gcc::context
*ctxt
)
911 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
914 /* opt_pass methods: */
915 bool gate () { return gate_ubsan (); }
916 unsigned int execute () { return ubsan_pass (); }
918 }; // class pass_ubsan
923 make_pass_ubsan (gcc::context
*ctxt
)
925 return new pass_ubsan (ctxt
);
928 #include "gt-ubsan.h"