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"
52 /* Map from a tree to a VAR_DECL tree. */
54 struct GTY(()) tree_type_map
{
55 struct tree_map_base type
;
59 #define tree_type_map_eq tree_map_base_eq
60 #define tree_type_map_marked_p tree_map_base_marked_p
62 /* Hash from a tree in a tree_type_map. */
65 tree_type_map_hash (const void *item
)
67 return TYPE_UID (((const struct tree_type_map
*)item
)->type
.from
);
70 static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map
)))
71 htab_t decl_tree_for_type
;
73 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
76 decl_for_type_lookup (tree type
)
78 /* If the hash table is not initialized yet, create it now. */
79 if (decl_tree_for_type
== NULL
)
81 decl_tree_for_type
= htab_create_ggc (10, tree_type_map_hash
,
83 /* That also means we don't have to bother with the lookup. */
87 struct tree_type_map
*h
, in
;
90 h
= (struct tree_type_map
*)
91 htab_find_with_hash (decl_tree_for_type
, &in
, TYPE_UID (type
));
92 return h
? h
->decl
: NULL_TREE
;
95 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
98 decl_for_type_insert (tree type
, tree decl
)
100 struct tree_type_map
*h
;
103 h
= ggc_alloc_tree_type_map ();
106 slot
= htab_find_slot_with_hash (decl_tree_for_type
, h
, TYPE_UID (type
),
108 *(struct tree_type_map
**) slot
= h
;
111 /* Helper routine, which encodes a value in the pointer_sized_int_node.
112 Arguments with precision <= POINTER_SIZE are passed directly,
113 the rest is passed by reference. T is a value we are to encode.
114 IN_EXPAND_P is true if this function is called during expansion. */
117 ubsan_encode_value (tree t
, bool in_expand_p
)
119 tree type
= TREE_TYPE (t
);
120 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
121 if (bitsize
<= POINTER_SIZE
)
122 switch (TREE_CODE (type
))
127 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
130 tree itype
= build_nonstandard_integer_type (bitsize
, true);
131 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
132 return fold_convert (pointer_sized_int_node
, t
);
139 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
141 /* The reason for this is that we don't want to pessimize
142 code by making vars unnecessarily addressable. */
143 tree var
= create_tmp_var (type
, NULL
);
144 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
148 = assign_stack_temp_for_type (TYPE_MODE (type
),
149 GET_MODE_SIZE (TYPE_MODE (type
)),
151 SET_DECL_RTL (var
, mem
);
152 expand_assignment (var
, t
, false);
153 return build_fold_addr_expr (var
);
155 t
= build_fold_addr_expr (var
);
156 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
159 return build_fold_addr_expr (t
);
164 struct __ubsan_type_descriptor
166 unsigned short __typekind;
167 unsigned short __typeinfo;
173 ubsan_type_descriptor_type (void)
175 static const char *field_names
[3]
176 = { "__typekind", "__typeinfo", "__typename" };
178 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
179 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
181 ret
= make_node (RECORD_TYPE
);
182 for (int i
= 0; i
< 3; i
++)
184 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
185 get_identifier (field_names
[i
]),
186 (i
== 2) ? flex_arr_type
187 : short_unsigned_type_node
);
188 DECL_CONTEXT (fields
[i
]) = ret
;
190 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
192 TYPE_FIELDS (ret
) = fields
[0];
193 TYPE_NAME (ret
) = get_identifier ("__ubsan_type_descriptor");
199 struct __ubsan_source_location
201 const char *__filename;
203 unsigned int __column;
208 ubsan_source_location_type (void)
210 static const char *field_names
[3]
211 = { "__filename", "__line", "__column" };
213 tree const_char_type
= build_qualified_type (char_type_node
,
216 ret
= make_node (RECORD_TYPE
);
217 for (int i
= 0; i
< 3; i
++)
219 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
220 get_identifier (field_names
[i
]),
221 (i
== 0) ? build_pointer_type (const_char_type
)
222 : unsigned_type_node
);
223 DECL_CONTEXT (fields
[i
]) = ret
;
225 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
227 TYPE_FIELDS (ret
) = fields
[0];
228 TYPE_NAME (ret
) = get_identifier ("__ubsan_source_location");
233 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
234 type with its fields filled from a location_t LOC. */
237 ubsan_source_location (location_t loc
)
239 expanded_location xloc
;
240 tree type
= ubsan_source_location_type ();
242 xloc
= expand_location (loc
);
243 if (xloc
.file
== NULL
)
244 xloc
.file
= "<unknown>";
246 /* Fill in the values from LOC. */
247 size_t len
= strlen (xloc
.file
);
248 tree str
= build_string (len
+ 1, xloc
.file
);
249 TREE_TYPE (str
) = build_array_type (char_type_node
,
250 build_index_type (size_int (len
)));
251 TREE_READONLY (str
) = 1;
252 TREE_STATIC (str
) = 1;
253 str
= build_fold_addr_expr (str
);
254 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
255 build_int_cst (unsigned_type_node
,
256 xloc
.line
), NULL_TREE
,
257 build_int_cst (unsigned_type_node
,
259 TREE_CONSTANT (ctor
) = 1;
260 TREE_STATIC (ctor
) = 1;
265 /* This routine returns a magic number for TYPE. */
267 static unsigned short
268 get_ubsan_type_info_for_type (tree type
)
270 gcc_assert (TYPE_SIZE (type
) && tree_fits_uhwi_p (TYPE_SIZE (type
)));
271 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
272 gcc_assert (prec
!= -1);
273 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
276 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
277 descriptor. It first looks into the hash table; if not found,
278 create the VAR_DECL, put it into the hash table and return the
279 ADDR_EXPR of it. TYPE describes a particular type. WANT_POINTER_TYPE_P
280 means whether we are interested in the pointer type and not the pointer
284 ubsan_type_descriptor (tree type
, bool want_pointer_type_p
)
286 /* See through any typedefs. */
287 type
= TYPE_MAIN_VARIANT (type
);
289 tree decl
= decl_for_type_lookup (type
);
290 /* It is possible that some of the earlier created DECLs were found
291 unused, in that case they weren't emitted and varpool_get_node
292 returns NULL node on them. But now we really need them. Thus,
294 if (decl
!= NULL_TREE
&& varpool_get_node (decl
))
295 return build_fold_addr_expr (decl
);
297 tree dtype
= ubsan_type_descriptor_type ();
299 const char *tname
= NULL
;
301 unsigned char deref_depth
= 0;
302 unsigned short tkind
, tinfo
;
304 /* Get the name of the type, or the name of the pointer type. */
305 if (want_pointer_type_p
)
307 gcc_assert (POINTER_TYPE_P (type
));
308 type2
= TREE_TYPE (type
);
310 /* Remove any '*' operators from TYPE. */
311 while (POINTER_TYPE_P (type2
))
312 deref_depth
++, type2
= TREE_TYPE (type2
);
314 if (TREE_CODE (type2
) == METHOD_TYPE
)
315 type2
= TYPE_METHOD_BASETYPE (type2
);
318 /* If an array, get its type. */
319 type2
= strip_array_types (type2
);
321 if (TYPE_NAME (type2
) != NULL
)
323 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
324 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
325 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
326 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
330 /* We weren't able to determine the type name. */
333 /* Decorate the type name with '', '*', "struct", or "union". */
334 pretty_name
= (char *) alloca (strlen (tname
) + 16 + deref_depth
);
335 if (want_pointer_type_p
)
337 int pos
= sprintf (pretty_name
, "'%s%s%s%s%s%s%s",
338 TYPE_VOLATILE (type2
) ? "volatile " : "",
339 TYPE_READONLY (type2
) ? "const " : "",
340 TYPE_RESTRICT (type2
) ? "restrict " : "",
341 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
342 TREE_CODE (type2
) == RECORD_TYPE
344 : TREE_CODE (type2
) == UNION_TYPE
345 ? "union " : "", tname
,
346 deref_depth
== 0 ? "" : " ");
347 while (deref_depth
-- > 0)
348 pretty_name
[pos
++] = '*';
349 pretty_name
[pos
++] = '\'';
350 pretty_name
[pos
] = '\0';
353 sprintf (pretty_name
, "'%s'", tname
);
355 switch (TREE_CODE (type
))
369 tinfo
= get_ubsan_type_info_for_type (type
);
371 /* Create a new VAR_DECL of type descriptor. */
373 static unsigned int type_var_id_num
;
374 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
375 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
377 TREE_STATIC (decl
) = 1;
378 TREE_PUBLIC (decl
) = 0;
379 DECL_ARTIFICIAL (decl
) = 1;
380 DECL_IGNORED_P (decl
) = 1;
381 DECL_EXTERNAL (decl
) = 0;
383 size_t len
= strlen (pretty_name
);
384 tree str
= build_string (len
+ 1, pretty_name
);
385 TREE_TYPE (str
) = build_array_type (char_type_node
,
386 build_index_type (size_int (len
)));
387 TREE_READONLY (str
) = 1;
388 TREE_STATIC (str
) = 1;
389 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
390 build_int_cst (short_unsigned_type_node
,
392 build_int_cst (short_unsigned_type_node
,
393 tinfo
), NULL_TREE
, str
);
394 TREE_CONSTANT (ctor
) = 1;
395 TREE_STATIC (ctor
) = 1;
396 DECL_INITIAL (decl
) = ctor
;
397 varpool_finalize_decl (decl
);
399 /* Save the VAR_DECL into the hash table. */
400 decl_for_type_insert (type
, decl
);
402 return build_fold_addr_expr (decl
);
405 /* Create a structure for the ubsan library. NAME is a name of the new
406 structure. The arguments in ... are of __ubsan_type_descriptor type
407 and there are at most two of them. MISMATCH are data used by ubsan
411 ubsan_create_data (const char *name
, const location_t
*ploc
,
412 const struct ubsan_mismatch_data
*mismatch
, ...)
417 vec
<tree
, va_gc
> *saved_args
= NULL
;
419 location_t loc
= UNKNOWN_LOCATION
;
421 /* Firstly, create a pointer to type descriptor type. */
422 tree td_type
= ubsan_type_descriptor_type ();
423 TYPE_READONLY (td_type
) = 1;
424 td_type
= build_pointer_type (td_type
);
426 /* Create the structure type. */
427 ret
= make_node (RECORD_TYPE
);
430 loc
= LOCATION_LOCUS (*ploc
);
431 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
432 ubsan_source_location_type ());
433 DECL_CONTEXT (fields
[i
]) = ret
;
437 va_start (args
, mismatch
);
438 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
439 i
++, t
= va_arg (args
, tree
))
441 gcc_checking_assert (i
< 3);
442 /* Save the tree arguments for later use. */
443 vec_safe_push (saved_args
, t
);
444 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
446 DECL_CONTEXT (fields
[i
]) = ret
;
448 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
452 if (mismatch
!= NULL
)
454 /* We have to add two more decls. */
455 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
456 pointer_sized_int_node
);
457 DECL_CONTEXT (fields
[i
]) = ret
;
458 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
461 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
462 unsigned_char_type_node
);
463 DECL_CONTEXT (fields
[i
]) = ret
;
464 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
468 TYPE_FIELDS (ret
) = fields
[0];
469 TYPE_NAME (ret
) = get_identifier (name
);
472 /* Now, fill in the type. */
474 static unsigned int ubsan_var_id_num
;
475 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
476 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
478 TREE_STATIC (var
) = 1;
479 TREE_PUBLIC (var
) = 0;
480 DECL_ARTIFICIAL (var
) = 1;
481 DECL_IGNORED_P (var
) = 1;
482 DECL_EXTERNAL (var
) = 0;
484 vec
<constructor_elt
, va_gc
> *v
;
486 tree ctor
= build_constructor (ret
, v
);
488 /* If desirable, set the __ubsan_source_location element. */
490 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
492 size_t nelts
= vec_safe_length (saved_args
);
493 for (i
= 0; i
< nelts
; i
++)
495 t
= (*saved_args
)[i
];
496 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
499 if (mismatch
!= NULL
)
501 /* Append the pointer data. */
502 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, mismatch
->align
);
503 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, mismatch
->ckind
);
506 TREE_CONSTANT (ctor
) = 1;
507 TREE_STATIC (ctor
) = 1;
508 DECL_INITIAL (var
) = ctor
;
509 varpool_finalize_decl (var
);
514 /* Instrument the __builtin_unreachable call. We just call the libubsan
518 ubsan_instrument_unreachable (location_t loc
)
520 initialize_sanitizer_builtins ();
521 tree data
= ubsan_create_data ("__ubsan_unreachable_data", &loc
, NULL
,
523 tree t
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
524 return build_call_expr_loc (loc
, t
, 1, build_fold_addr_expr_loc (loc
, data
));
527 /* Return true if T is a call to a libubsan routine. */
530 is_ubsan_builtin_p (tree t
)
532 return TREE_CODE (t
) == FUNCTION_DECL
533 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
534 "__builtin___ubsan_", 18) == 0;
537 /* Expand UBSAN_NULL internal call. */
540 ubsan_expand_null_ifn (gimple_stmt_iterator gsi
)
542 gimple stmt
= gsi_stmt (gsi
);
543 location_t loc
= gimple_location (stmt
);
544 gcc_assert (gimple_call_num_args (stmt
) == 2);
545 tree ptr
= gimple_call_arg (stmt
, 0);
546 tree ckind
= gimple_call_arg (stmt
, 1);
548 basic_block cur_bb
= gsi_bb (gsi
);
550 /* Split the original block holding the pointer dereference. */
551 edge e
= split_block (cur_bb
, stmt
);
553 /* Get a hold on the 'condition block', the 'then block' and the
555 basic_block cond_bb
= e
->src
;
556 basic_block fallthru_bb
= e
->dest
;
557 basic_block then_bb
= create_empty_bb (cond_bb
);
560 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
561 loops_state_set (LOOPS_NEED_FIXUP
);
564 /* Make an edge coming from the 'cond block' into the 'then block';
565 this edge is unlikely taken, so set up the probability accordingly. */
566 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
567 e
->probability
= PROB_VERY_UNLIKELY
;
569 /* Connect 'then block' with the 'else block'. This is needed
570 as the ubsan routines we call in the 'then block' are not noreturn.
571 The 'then block' only has one outcoming edge. */
572 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
574 /* Set up the fallthrough basic block. */
575 e
= find_edge (cond_bb
, fallthru_bb
);
576 e
->flags
= EDGE_FALSE_VALUE
;
577 e
->count
= cond_bb
->count
;
578 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
580 /* Update dominance info for the newly created then_bb; note that
581 fallthru_bb's dominance info has already been updated by
583 if (dom_info_available_p (CDI_DOMINATORS
))
584 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
586 /* Put the ubsan builtin call into the newly created BB. */
587 tree fn
= builtin_decl_implicit (BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
);
588 const struct ubsan_mismatch_data m
589 = { build_zero_cst (pointer_sized_int_node
), ckind
};
590 tree data
= ubsan_create_data ("__ubsan_null_data",
592 ubsan_type_descriptor (TREE_TYPE (ptr
), true),
594 data
= build_fold_addr_expr_loc (loc
, data
);
595 gimple g
= gimple_build_call (fn
, 2, data
,
596 build_zero_cst (pointer_sized_int_node
));
597 gimple_set_location (g
, loc
);
598 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
599 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
601 /* Unlink the UBSAN_NULLs vops before replacing it. */
602 unlink_stmt_vdef (stmt
);
604 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
605 NULL_TREE
, NULL_TREE
);
606 gimple_set_location (g
, loc
);
608 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
609 gsi_replace (&gsi
, g
, false);
612 /* Instrument a member call. We check whether 'this' is NULL. */
615 instrument_member_call (gimple_stmt_iterator
*iter
)
617 tree this_parm
= gimple_call_arg (gsi_stmt (*iter
), 0);
618 tree kind
= build_int_cst (unsigned_char_type_node
, UBSAN_MEMBER_CALL
);
619 gimple g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 2, this_parm
, kind
);
620 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
621 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
624 /* Instrument a memory reference. T is the pointer, IS_LHS says
625 whether the pointer is on the left hand side of the assignment. */
628 instrument_mem_ref (tree t
, gimple_stmt_iterator
*iter
, bool is_lhs
)
630 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
631 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t
))))
632 ikind
= UBSAN_MEMBER_ACCESS
;
633 tree kind
= build_int_cst (unsigned_char_type_node
, ikind
);
634 gimple g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 2, t
, kind
);
635 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
636 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
639 /* Perform the pointer instrumentation. */
642 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
644 gimple stmt
= gsi_stmt (gsi
);
645 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
646 t
= get_base_address (t
);
647 const enum tree_code code
= TREE_CODE (t
);
649 && TREE_CODE (TREE_OPERAND (t
, 0)) == SSA_NAME
)
650 instrument_mem_ref (TREE_OPERAND (t
, 0), &gsi
, is_lhs
);
651 else if (code
== ADDR_EXPR
652 && POINTER_TYPE_P (TREE_TYPE (t
))
653 && TREE_CODE (TREE_TYPE (TREE_TYPE (t
))) == METHOD_TYPE
)
654 instrument_member_call (&gsi
);
657 /* Build an ubsan builtin call for the signed-integer-overflow
658 sanitization. CODE says what kind of builtin are we building,
659 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
660 are operands of the binary operation. */
663 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
666 tree data
= ubsan_create_data ("__ubsan_overflow_data", &loc
, NULL
,
667 ubsan_type_descriptor (lhstype
, false),
669 enum built_in_function fn_code
;
674 fn_code
= BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
;
677 fn_code
= BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
;
680 fn_code
= BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
;
683 fn_code
= BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
;
688 tree fn
= builtin_decl_explicit (fn_code
);
689 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
690 build_fold_addr_expr_loc (loc
, data
),
691 ubsan_encode_value (op0
, true),
692 op1
? ubsan_encode_value (op1
, true)
696 /* Perform the signed integer instrumentation. GSI is the iterator
697 pointing at statement we are trying to instrument. */
700 instrument_si_overflow (gimple_stmt_iterator gsi
)
702 gimple stmt
= gsi_stmt (gsi
);
703 tree_code code
= gimple_assign_rhs_code (stmt
);
704 tree lhs
= gimple_assign_lhs (stmt
);
705 tree lhstype
= TREE_TYPE (lhs
);
709 /* If this is not a signed operation, don't instrument anything here.
710 Also punt on bit-fields. */
711 if (!INTEGRAL_TYPE_P (lhstype
)
712 || TYPE_OVERFLOW_WRAPS (lhstype
)
713 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
724 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
725 a
= gimple_assign_rhs1 (stmt
);
726 b
= gimple_assign_rhs2 (stmt
);
727 g
= gimple_build_call_internal (code
== PLUS_EXPR
728 ? IFN_UBSAN_CHECK_ADD
730 ? IFN_UBSAN_CHECK_SUB
731 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
732 gimple_call_set_lhs (g
, lhs
);
733 gsi_replace (&gsi
, g
, false);
738 i = UBSAN_CHECK_SUB (0, u); */
739 a
= build_int_cst (lhstype
, 0);
740 b
= gimple_assign_rhs1 (stmt
);
741 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
742 gimple_call_set_lhs (g
, lhs
);
743 gsi_replace (&gsi
, g
, false);
746 /* Transform i = ABS_EXPR<u>;
748 _N = UBSAN_CHECK_SUB (0, u);
750 a
= build_int_cst (lhstype
, 0);
751 b
= gimple_assign_rhs1 (stmt
);
752 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
753 a
= make_ssa_name (lhstype
, NULL
);
754 gimple_call_set_lhs (g
, a
);
755 gimple_set_location (g
, gimple_location (stmt
));
756 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
757 gimple_assign_set_rhs1 (stmt
, a
);
765 /* Instrument loads from (non-bitfield) bool and C++ enum values
766 to check if the memory value is outside of the range of the valid
770 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
772 gimple stmt
= gsi_stmt (*gsi
);
773 tree rhs
= gimple_assign_rhs1 (stmt
);
774 tree type
= TREE_TYPE (rhs
);
775 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
777 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
779 minv
= boolean_false_node
;
780 maxv
= boolean_true_node
;
782 else if (TREE_CODE (type
) == ENUMERAL_TYPE
783 && (flag_sanitize
& SANITIZE_ENUM
)
784 && TREE_TYPE (type
) != NULL_TREE
785 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
786 && (TYPE_PRECISION (TREE_TYPE (type
))
787 < GET_MODE_PRECISION (TYPE_MODE (type
))))
789 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
790 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
795 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
796 HOST_WIDE_INT bitsize
, bitpos
;
798 enum machine_mode mode
;
799 int volatilep
= 0, unsignedp
= 0;
800 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
801 &unsignedp
, &volatilep
, false);
802 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
804 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
805 || (bitpos
% modebitsize
) != 0
806 || bitsize
!= modebitsize
807 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
808 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
811 bool can_throw
= stmt_could_throw_p (stmt
);
812 location_t loc
= gimple_location (stmt
);
813 tree lhs
= gimple_assign_lhs (stmt
);
814 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
815 tree atype
= reference_alias_ptr_type (rhs
);
816 gimple g
= gimple_build_assign (make_ssa_name (ptype
, NULL
),
817 build_fold_addr_expr (rhs
));
818 gimple_set_location (g
, loc
);
819 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
820 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
821 build_int_cst (atype
, 0));
822 tree urhs
= make_ssa_name (utype
, NULL
);
825 gimple_assign_set_lhs (stmt
, urhs
);
826 g
= gimple_build_assign_with_ops (NOP_EXPR
, lhs
, urhs
, NULL_TREE
);
827 gimple_set_location (g
, loc
);
828 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
829 gsi_insert_on_edge_immediate (e
, g
);
830 gimple_assign_set_rhs_from_tree (gsi
, mem
);
832 *gsi
= gsi_for_stmt (g
);
837 g
= gimple_build_assign (urhs
, mem
);
838 gimple_set_location (g
, loc
);
839 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
841 minv
= fold_convert (utype
, minv
);
842 maxv
= fold_convert (utype
, maxv
);
843 if (!integer_zerop (minv
))
845 g
= gimple_build_assign_with_ops (MINUS_EXPR
,
846 make_ssa_name (utype
, NULL
),
848 gimple_set_location (g
, loc
);
849 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
852 gimple_stmt_iterator gsi2
= *gsi
;
853 basic_block then_bb
, fallthru_bb
;
854 *gsi
= create_cond_insert_point (gsi
, true, false, true,
855 &then_bb
, &fallthru_bb
);
856 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
857 int_const_binop (MINUS_EXPR
, maxv
, minv
),
858 NULL_TREE
, NULL_TREE
);
859 gimple_set_location (g
, loc
);
860 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
864 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
, NULL_TREE
);
868 tree data
= ubsan_create_data ("__ubsan_invalid_value_data",
870 ubsan_type_descriptor (type
, false),
872 data
= build_fold_addr_expr_loc (loc
, data
);
873 tree fn
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
);
875 gsi2
= gsi_after_labels (then_bb
);
876 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
877 true, NULL_TREE
, true, GSI_SAME_STMT
);
878 g
= gimple_build_call (fn
, 2, data
, val
);
879 gimple_set_location (g
, loc
);
880 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
883 /* Gate and execute functions for ubsan pass. */
889 gimple_stmt_iterator gsi
;
891 initialize_sanitizer_builtins ();
893 FOR_EACH_BB_FN (bb
, cfun
)
895 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
897 gimple stmt
= gsi_stmt (gsi
);
898 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
904 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
905 && is_gimple_assign (stmt
))
906 instrument_si_overflow (gsi
);
908 if (flag_sanitize
& SANITIZE_NULL
)
910 if (gimple_store_p (stmt
))
911 instrument_null (gsi
, true);
912 if (gimple_assign_load_p (stmt
))
913 instrument_null (gsi
, false);
916 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
917 && gimple_assign_load_p (stmt
))
918 instrument_bool_enum_load (&gsi
);
929 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
930 | SANITIZE_BOOL
| SANITIZE_ENUM
);
935 const pass_data pass_data_ubsan
=
937 GIMPLE_PASS
, /* type */
939 OPTGROUP_NONE
, /* optinfo_flags */
941 true, /* has_execute */
942 TV_TREE_UBSAN
, /* tv_id */
943 ( PROP_cfg
| PROP_ssa
), /* properties_required */
944 0, /* properties_provided */
945 0, /* properties_destroyed */
946 0, /* todo_flags_start */
947 TODO_update_ssa
, /* todo_flags_finish */
950 class pass_ubsan
: public gimple_opt_pass
953 pass_ubsan (gcc::context
*ctxt
)
954 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
957 /* opt_pass methods: */
958 bool gate () { return gate_ubsan (); }
959 unsigned int execute () { return ubsan_pass (); }
961 }; // class pass_ubsan
966 make_pass_ubsan (gcc::context
*ctxt
)
968 return new pass_ubsan (ctxt
);
971 #include "gt-ubsan.h"