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"
54 /* Map from a tree to a VAR_DECL tree. */
56 struct GTY(()) tree_type_map
{
57 struct tree_map_base type
;
61 #define tree_type_map_eq tree_map_base_eq
62 #define tree_type_map_marked_p tree_map_base_marked_p
64 /* Hash from a tree in a tree_type_map. */
67 tree_type_map_hash (const void *item
)
69 return TYPE_UID (((const struct tree_type_map
*)item
)->type
.from
);
72 static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map
)))
73 htab_t decl_tree_for_type
;
75 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
78 decl_for_type_lookup (tree type
)
80 /* If the hash table is not initialized yet, create it now. */
81 if (decl_tree_for_type
== NULL
)
83 decl_tree_for_type
= htab_create_ggc (10, tree_type_map_hash
,
85 /* That also means we don't have to bother with the lookup. */
89 struct tree_type_map
*h
, in
;
92 h
= (struct tree_type_map
*)
93 htab_find_with_hash (decl_tree_for_type
, &in
, TYPE_UID (type
));
94 return h
? h
->decl
: NULL_TREE
;
97 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
100 decl_for_type_insert (tree type
, tree decl
)
102 struct tree_type_map
*h
;
105 h
= ggc_alloc
<tree_type_map
> ();
108 slot
= htab_find_slot_with_hash (decl_tree_for_type
, h
, TYPE_UID (type
),
110 *(struct tree_type_map
**) slot
= h
;
113 /* Helper routine, which encodes a value in the pointer_sized_int_node.
114 Arguments with precision <= POINTER_SIZE are passed directly,
115 the rest is passed by reference. T is a value we are to encode.
116 IN_EXPAND_P is true if this function is called during expansion. */
119 ubsan_encode_value (tree t
, bool in_expand_p
)
121 tree type
= TREE_TYPE (t
);
122 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
123 if (bitsize
<= POINTER_SIZE
)
124 switch (TREE_CODE (type
))
129 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
132 tree itype
= build_nonstandard_integer_type (bitsize
, true);
133 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
134 return fold_convert (pointer_sized_int_node
, t
);
141 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
143 /* The reason for this is that we don't want to pessimize
144 code by making vars unnecessarily addressable. */
145 tree var
= create_tmp_var (type
, NULL
);
146 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
150 = assign_stack_temp_for_type (TYPE_MODE (type
),
151 GET_MODE_SIZE (TYPE_MODE (type
)),
153 SET_DECL_RTL (var
, mem
);
154 expand_assignment (var
, t
, false);
155 return build_fold_addr_expr (var
);
157 t
= build_fold_addr_expr (var
);
158 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
161 return build_fold_addr_expr (t
);
166 struct __ubsan_type_descriptor
168 unsigned short __typekind;
169 unsigned short __typeinfo;
175 ubsan_type_descriptor_type (void)
177 static const char *field_names
[3]
178 = { "__typekind", "__typeinfo", "__typename" };
180 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
181 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
183 ret
= make_node (RECORD_TYPE
);
184 for (int i
= 0; i
< 3; i
++)
186 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
187 get_identifier (field_names
[i
]),
188 (i
== 2) ? flex_arr_type
189 : short_unsigned_type_node
);
190 DECL_CONTEXT (fields
[i
]) = ret
;
192 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
194 TYPE_FIELDS (ret
) = fields
[0];
195 TYPE_NAME (ret
) = get_identifier ("__ubsan_type_descriptor");
201 struct __ubsan_source_location
203 const char *__filename;
205 unsigned int __column;
210 ubsan_source_location_type (void)
212 static const char *field_names
[3]
213 = { "__filename", "__line", "__column" };
215 tree const_char_type
= build_qualified_type (char_type_node
,
218 ret
= make_node (RECORD_TYPE
);
219 for (int i
= 0; i
< 3; i
++)
221 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
222 get_identifier (field_names
[i
]),
223 (i
== 0) ? build_pointer_type (const_char_type
)
224 : unsigned_type_node
);
225 DECL_CONTEXT (fields
[i
]) = ret
;
227 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
229 TYPE_FIELDS (ret
) = fields
[0];
230 TYPE_NAME (ret
) = get_identifier ("__ubsan_source_location");
235 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
236 type with its fields filled from a location_t LOC. */
239 ubsan_source_location (location_t loc
)
241 expanded_location xloc
;
242 tree type
= ubsan_source_location_type ();
244 xloc
= expand_location (loc
);
245 if (xloc
.file
== NULL
)
246 xloc
.file
= "<unknown>";
248 /* Fill in the values from LOC. */
249 size_t len
= strlen (xloc
.file
);
250 tree str
= build_string (len
+ 1, xloc
.file
);
251 TREE_TYPE (str
) = build_array_type (char_type_node
,
252 build_index_type (size_int (len
)));
253 TREE_READONLY (str
) = 1;
254 TREE_STATIC (str
) = 1;
255 str
= build_fold_addr_expr (str
);
256 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
257 build_int_cst (unsigned_type_node
,
258 xloc
.line
), NULL_TREE
,
259 build_int_cst (unsigned_type_node
,
261 TREE_CONSTANT (ctor
) = 1;
262 TREE_STATIC (ctor
) = 1;
267 /* This routine returns a magic number for TYPE. */
269 static unsigned short
270 get_ubsan_type_info_for_type (tree type
)
272 gcc_assert (TYPE_SIZE (type
) && tree_fits_uhwi_p (TYPE_SIZE (type
)));
273 if (TREE_CODE (type
) == REAL_TYPE
)
274 return tree_to_uhwi (TYPE_SIZE (type
));
275 else if (INTEGRAL_TYPE_P (type
))
277 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
278 gcc_assert (prec
!= -1);
279 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
285 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
286 descriptor. It first looks into the hash table; if not found,
287 create the VAR_DECL, put it into the hash table and return the
288 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
289 an enum controlling how we want to print the type. */
292 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
294 /* See through any typedefs. */
295 type
= TYPE_MAIN_VARIANT (type
);
297 tree decl
= decl_for_type_lookup (type
);
298 /* It is possible that some of the earlier created DECLs were found
299 unused, in that case they weren't emitted and varpool_node::get
300 returns NULL node on them. But now we really need them. Thus,
302 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
303 return build_fold_addr_expr (decl
);
305 tree dtype
= ubsan_type_descriptor_type ();
307 const char *tname
= NULL
;
309 unsigned char deref_depth
= 0;
310 unsigned short tkind
, tinfo
;
312 /* Get the name of the type, or the name of the pointer type. */
313 if (pstyle
== UBSAN_PRINT_POINTER
)
315 gcc_assert (POINTER_TYPE_P (type
));
316 type2
= TREE_TYPE (type
);
318 /* Remove any '*' operators from TYPE. */
319 while (POINTER_TYPE_P (type2
))
320 deref_depth
++, type2
= TREE_TYPE (type2
);
322 if (TREE_CODE (type2
) == METHOD_TYPE
)
323 type2
= TYPE_METHOD_BASETYPE (type2
);
326 /* If an array, get its type. */
327 type2
= strip_array_types (type2
);
329 if (pstyle
== UBSAN_PRINT_ARRAY
)
331 while (POINTER_TYPE_P (type2
))
332 deref_depth
++, type2
= TREE_TYPE (type2
);
335 if (TYPE_NAME (type2
) != NULL
)
337 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
338 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
339 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
340 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
344 /* We weren't able to determine the type name. */
347 /* Decorate the type name with '', '*', "struct", or "union". */
348 pretty_name
= (char *) alloca (strlen (tname
) + 16 + deref_depth
);
349 if (pstyle
== UBSAN_PRINT_POINTER
)
351 int pos
= sprintf (pretty_name
, "'%s%s%s%s%s%s%s",
352 TYPE_VOLATILE (type2
) ? "volatile " : "",
353 TYPE_READONLY (type2
) ? "const " : "",
354 TYPE_RESTRICT (type2
) ? "restrict " : "",
355 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
356 TREE_CODE (type2
) == RECORD_TYPE
358 : TREE_CODE (type2
) == UNION_TYPE
359 ? "union " : "", tname
,
360 deref_depth
== 0 ? "" : " ");
361 while (deref_depth
-- > 0)
362 pretty_name
[pos
++] = '*';
363 pretty_name
[pos
++] = '\'';
364 pretty_name
[pos
] = '\0';
366 else if (pstyle
== UBSAN_PRINT_ARRAY
)
368 /* Pretty print the array dimensions. */
369 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
371 int pos
= sprintf (pretty_name
, "'%s ", tname
);
372 while (deref_depth
-- > 0)
373 pretty_name
[pos
++] = '*';
374 while (TREE_CODE (t
) == ARRAY_TYPE
)
376 pretty_name
[pos
++] = '[';
377 tree dom
= TYPE_DOMAIN (t
);
378 if (dom
&& TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
379 pos
+= sprintf (&pretty_name
[pos
], HOST_WIDE_INT_PRINT_DEC
,
380 tree_to_shwi (TYPE_MAX_VALUE (dom
)) + 1);
382 /* ??? We can't determine the variable name; print VLA unspec. */
383 pretty_name
[pos
++] = '*';
384 pretty_name
[pos
++] = ']';
387 pretty_name
[pos
++] = '\'';
388 pretty_name
[pos
] = '\0';
390 /* Save the tree with stripped types. */
394 sprintf (pretty_name
, "'%s'", tname
);
396 switch (TREE_CODE (type
))
404 /* FIXME: libubsan right now only supports float, double and
405 long double type formats. */
406 if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
)
407 || TYPE_MODE (type
) == TYPE_MODE (double_type_node
)
408 || TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
417 tinfo
= get_ubsan_type_info_for_type (type
);
419 /* Create a new VAR_DECL of type descriptor. */
421 static unsigned int type_var_id_num
;
422 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
423 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
425 TREE_STATIC (decl
) = 1;
426 TREE_PUBLIC (decl
) = 0;
427 DECL_ARTIFICIAL (decl
) = 1;
428 DECL_IGNORED_P (decl
) = 1;
429 DECL_EXTERNAL (decl
) = 0;
431 size_t len
= strlen (pretty_name
);
432 tree str
= build_string (len
+ 1, pretty_name
);
433 TREE_TYPE (str
) = build_array_type (char_type_node
,
434 build_index_type (size_int (len
)));
435 TREE_READONLY (str
) = 1;
436 TREE_STATIC (str
) = 1;
437 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
438 build_int_cst (short_unsigned_type_node
,
440 build_int_cst (short_unsigned_type_node
,
441 tinfo
), NULL_TREE
, str
);
442 TREE_CONSTANT (ctor
) = 1;
443 TREE_STATIC (ctor
) = 1;
444 DECL_INITIAL (decl
) = ctor
;
445 varpool_node::finalize_decl (decl
);
447 /* Save the VAR_DECL into the hash table. */
448 decl_for_type_insert (type
, decl
);
450 return build_fold_addr_expr (decl
);
453 /* Create a structure for the ubsan library. NAME is a name of the new
454 structure. The arguments in ... are of __ubsan_type_descriptor type
455 and there are at most two of them. MISMATCH are data used by ubsan
459 ubsan_create_data (const char *name
, const location_t
*ploc
,
460 const struct ubsan_mismatch_data
*mismatch
, ...)
465 vec
<tree
, va_gc
> *saved_args
= NULL
;
467 location_t loc
= UNKNOWN_LOCATION
;
469 /* Firstly, create a pointer to type descriptor type. */
470 tree td_type
= ubsan_type_descriptor_type ();
471 TYPE_READONLY (td_type
) = 1;
472 td_type
= build_pointer_type (td_type
);
474 /* Create the structure type. */
475 ret
= make_node (RECORD_TYPE
);
478 loc
= LOCATION_LOCUS (*ploc
);
479 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
480 ubsan_source_location_type ());
481 DECL_CONTEXT (fields
[i
]) = ret
;
485 va_start (args
, mismatch
);
486 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
487 i
++, t
= va_arg (args
, tree
))
489 gcc_checking_assert (i
< 3);
490 /* Save the tree arguments for later use. */
491 vec_safe_push (saved_args
, t
);
492 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
494 DECL_CONTEXT (fields
[i
]) = ret
;
496 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
500 if (mismatch
!= NULL
)
502 /* We have to add two more decls. */
503 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
504 pointer_sized_int_node
);
505 DECL_CONTEXT (fields
[i
]) = ret
;
506 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
509 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
510 unsigned_char_type_node
);
511 DECL_CONTEXT (fields
[i
]) = ret
;
512 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
516 TYPE_FIELDS (ret
) = fields
[0];
517 TYPE_NAME (ret
) = get_identifier (name
);
520 /* Now, fill in the type. */
522 static unsigned int ubsan_var_id_num
;
523 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
524 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
526 TREE_STATIC (var
) = 1;
527 TREE_PUBLIC (var
) = 0;
528 DECL_ARTIFICIAL (var
) = 1;
529 DECL_IGNORED_P (var
) = 1;
530 DECL_EXTERNAL (var
) = 0;
532 vec
<constructor_elt
, va_gc
> *v
;
534 tree ctor
= build_constructor (ret
, v
);
536 /* If desirable, set the __ubsan_source_location element. */
538 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
540 size_t nelts
= vec_safe_length (saved_args
);
541 for (i
= 0; i
< nelts
; i
++)
543 t
= (*saved_args
)[i
];
544 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
547 if (mismatch
!= NULL
)
549 /* Append the pointer data. */
550 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, mismatch
->align
);
551 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, mismatch
->ckind
);
554 TREE_CONSTANT (ctor
) = 1;
555 TREE_STATIC (ctor
) = 1;
556 DECL_INITIAL (var
) = ctor
;
557 varpool_node::finalize_decl (var
);
562 /* Instrument the __builtin_unreachable call. We just call the libubsan
566 ubsan_instrument_unreachable (location_t loc
)
568 if (flag_sanitize_undefined_trap_on_error
)
569 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
571 initialize_sanitizer_builtins ();
572 tree data
= ubsan_create_data ("__ubsan_unreachable_data", &loc
, NULL
,
574 tree t
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
575 return build_call_expr_loc (loc
, t
, 1, build_fold_addr_expr_loc (loc
, data
));
578 /* Return true if T is a call to a libubsan routine. */
581 is_ubsan_builtin_p (tree t
)
583 return TREE_CODE (t
) == FUNCTION_DECL
584 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
585 "__builtin___ubsan_", 18) == 0;
588 /* Expand the UBSAN_BOUNDS special builtin function. */
591 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
593 gimple stmt
= gsi_stmt (*gsi
);
594 location_t loc
= gimple_location (stmt
);
595 gcc_assert (gimple_call_num_args (stmt
) == 3);
597 /* Pick up the arguments of the UBSAN_BOUNDS call. */
598 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
599 tree index
= gimple_call_arg (stmt
, 1);
600 tree orig_index_type
= TREE_TYPE (index
);
601 tree bound
= gimple_call_arg (stmt
, 2);
603 gimple_stmt_iterator gsi_orig
= *gsi
;
605 /* Create condition "if (index > bound)". */
606 basic_block then_bb
, fallthru_bb
;
607 gimple_stmt_iterator cond_insert_point
608 = create_cond_insert_point (gsi
, 0/*before_p*/, false, true,
609 &then_bb
, &fallthru_bb
);
610 index
= fold_convert (TREE_TYPE (bound
), index
);
611 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
612 true/*simple_p*/, NULL_TREE
,
613 false/*before*/, GSI_NEW_STMT
);
614 gimple g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
615 gimple_set_location (g
, loc
);
616 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
618 /* Generate __ubsan_handle_out_of_bounds call. */
619 *gsi
= gsi_after_labels (then_bb
);
620 if (flag_sanitize_undefined_trap_on_error
)
621 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
625 = ubsan_create_data ("__ubsan_out_of_bounds_data", &loc
, NULL
,
626 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
627 ubsan_type_descriptor (orig_index_type
),
629 data
= build_fold_addr_expr_loc (loc
, data
);
630 enum built_in_function bcode
631 = flag_sanitize_recover
632 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
633 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
634 tree fn
= builtin_decl_explicit (bcode
);
635 tree val
= force_gimple_operand_gsi (gsi
, ubsan_encode_value (index
),
636 true, NULL_TREE
, true,
638 g
= gimple_build_call (fn
, 2, data
, val
);
640 gimple_set_location (g
, loc
);
641 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
643 /* Get rid of the UBSAN_BOUNDS call from the IR. */
644 unlink_stmt_vdef (stmt
);
645 gsi_remove (&gsi_orig
, true);
647 /* Point GSI to next logical statement. */
648 *gsi
= gsi_start_bb (fallthru_bb
);
652 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
653 argument which is a constant, because the middle-end treats pointer
654 conversions as useless and therefore the type of the first argument
655 could be changed to any other pointer type. */
658 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
660 gimple_stmt_iterator gsi
= *gsip
;
661 gimple stmt
= gsi_stmt (gsi
);
662 location_t loc
= gimple_location (stmt
);
663 gcc_assert (gimple_call_num_args (stmt
) == 3);
664 tree ptr
= gimple_call_arg (stmt
, 0);
665 tree ckind
= gimple_call_arg (stmt
, 1);
666 tree align
= gimple_call_arg (stmt
, 2);
667 tree check_align
= NULL_TREE
;
670 basic_block cur_bb
= gsi_bb (gsi
);
673 if (!integer_zerop (align
))
675 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
676 if (compare_tree_int (align
, ptralign
) == 1)
678 check_align
= make_ssa_name (pointer_sized_int_node
, NULL
);
679 g
= gimple_build_assign_with_ops (NOP_EXPR
, check_align
,
681 gimple_set_location (g
, loc
);
682 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
685 check_null
= (flag_sanitize
& SANITIZE_NULL
) != 0;
687 if (check_align
== NULL_TREE
&& !check_null
)
689 gsi_remove (gsip
, true);
690 /* Unlink the UBSAN_NULLs vops before replacing it. */
691 unlink_stmt_vdef (stmt
);
695 /* Split the original block holding the pointer dereference. */
696 edge e
= split_block (cur_bb
, stmt
);
698 /* Get a hold on the 'condition block', the 'then block' and the
700 basic_block cond_bb
= e
->src
;
701 basic_block fallthru_bb
= e
->dest
;
702 basic_block then_bb
= create_empty_bb (cond_bb
);
703 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
704 loops_state_set (LOOPS_NEED_FIXUP
);
706 /* Make an edge coming from the 'cond block' into the 'then block';
707 this edge is unlikely taken, so set up the probability accordingly. */
708 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
709 e
->probability
= PROB_VERY_UNLIKELY
;
711 /* Connect 'then block' with the 'else block'. This is needed
712 as the ubsan routines we call in the 'then block' are not noreturn.
713 The 'then block' only has one outcoming edge. */
714 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
716 /* Set up the fallthrough basic block. */
717 e
= find_edge (cond_bb
, fallthru_bb
);
718 e
->flags
= EDGE_FALSE_VALUE
;
719 e
->count
= cond_bb
->count
;
720 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
722 /* Update dominance info for the newly created then_bb; note that
723 fallthru_bb's dominance info has already been updated by
725 if (dom_info_available_p (CDI_DOMINATORS
))
726 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
728 /* Put the ubsan builtin call into the newly created BB. */
729 if (flag_sanitize_undefined_trap_on_error
)
730 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
733 enum built_in_function bcode
734 = flag_sanitize_recover
735 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
736 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
737 tree fn
= builtin_decl_implicit (bcode
);
738 const struct ubsan_mismatch_data m
739 = { align
, fold_convert (unsigned_char_type_node
, ckind
) };
741 = ubsan_create_data ("__ubsan_null_data", &loc
, &m
,
742 ubsan_type_descriptor (TREE_TYPE (ckind
),
743 UBSAN_PRINT_POINTER
),
745 data
= build_fold_addr_expr_loc (loc
, data
);
746 g
= gimple_build_call (fn
, 2, data
,
747 check_align
? check_align
748 : build_zero_cst (pointer_sized_int_node
));
750 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
751 gimple_set_location (g
, loc
);
752 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
754 /* Unlink the UBSAN_NULLs vops before replacing it. */
755 unlink_stmt_vdef (stmt
);
759 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
760 NULL_TREE
, NULL_TREE
);
761 gimple_set_location (g
, loc
);
763 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
764 gsi_replace (&gsi
, g
, false);
771 /* Split the block with the condition again. */
772 e
= split_block (cond_bb
, stmt
);
773 basic_block cond1_bb
= e
->src
;
774 basic_block cond2_bb
= e
->dest
;
776 /* Make an edge coming from the 'cond1 block' into the 'then block';
777 this edge is unlikely taken, so set up the probability
779 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
780 e
->probability
= PROB_VERY_UNLIKELY
;
782 /* Set up the fallthrough basic block. */
783 e
= find_edge (cond1_bb
, cond2_bb
);
784 e
->flags
= EDGE_FALSE_VALUE
;
785 e
->count
= cond1_bb
->count
;
786 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
788 /* Update dominance info. */
789 if (dom_info_available_p (CDI_DOMINATORS
))
791 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
792 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
795 gsi2
= gsi_start_bb (cond2_bb
);
798 tree mask
= build_int_cst (pointer_sized_int_node
,
799 tree_to_uhwi (align
) - 1);
800 g
= gimple_build_assign_with_ops (BIT_AND_EXPR
,
801 make_ssa_name (pointer_sized_int_node
,
804 gimple_set_location (g
, loc
);
806 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
808 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
810 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
811 build_int_cst (pointer_sized_int_node
, 0),
812 NULL_TREE
, NULL_TREE
);
813 gimple_set_location (g
, loc
);
815 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
817 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
818 gsi_replace (&gsi
, g
, false);
823 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
824 whether the pointer is on the left hand side of the assignment. */
827 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
830 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
831 unsigned int align
= 0;
832 if (flag_sanitize
& SANITIZE_ALIGNMENT
)
834 align
= min_align_of_type (TREE_TYPE (base
));
838 if (align
== 0 && (flag_sanitize
& SANITIZE_NULL
) == 0)
840 tree t
= TREE_OPERAND (base
, 0);
841 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
843 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t
))) && mem
!= base
)
844 ikind
= UBSAN_MEMBER_ACCESS
;
845 tree kind
= build_int_cst (TREE_TYPE (t
), ikind
);
846 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
847 gimple g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
848 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
849 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
852 /* Perform the pointer instrumentation. */
855 instrument_null (gimple_stmt_iterator gsi
, bool is_lhs
)
857 gimple stmt
= gsi_stmt (gsi
);
858 tree t
= is_lhs
? gimple_get_lhs (stmt
) : gimple_assign_rhs1 (stmt
);
859 tree base
= get_base_address (t
);
860 const enum tree_code code
= TREE_CODE (base
);
862 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
863 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
866 /* Build an ubsan builtin call for the signed-integer-overflow
867 sanitization. CODE says what kind of builtin are we building,
868 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
869 are operands of the binary operation. */
872 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
875 if (flag_sanitize_undefined_trap_on_error
)
876 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
878 tree data
= ubsan_create_data ("__ubsan_overflow_data", &loc
, NULL
,
879 ubsan_type_descriptor (lhstype
), NULL_TREE
);
880 enum built_in_function fn_code
;
885 fn_code
= flag_sanitize_recover
886 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
887 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
890 fn_code
= flag_sanitize_recover
891 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
892 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
895 fn_code
= flag_sanitize_recover
896 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
897 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
900 fn_code
= flag_sanitize_recover
901 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
902 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
907 tree fn
= builtin_decl_explicit (fn_code
);
908 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
909 build_fold_addr_expr_loc (loc
, data
),
910 ubsan_encode_value (op0
, true),
911 op1
? ubsan_encode_value (op1
, true)
915 /* Perform the signed integer instrumentation. GSI is the iterator
916 pointing at statement we are trying to instrument. */
919 instrument_si_overflow (gimple_stmt_iterator gsi
)
921 gimple stmt
= gsi_stmt (gsi
);
922 tree_code code
= gimple_assign_rhs_code (stmt
);
923 tree lhs
= gimple_assign_lhs (stmt
);
924 tree lhstype
= TREE_TYPE (lhs
);
928 /* If this is not a signed operation, don't instrument anything here.
929 Also punt on bit-fields. */
930 if (!INTEGRAL_TYPE_P (lhstype
)
931 || TYPE_OVERFLOW_WRAPS (lhstype
)
932 || GET_MODE_BITSIZE (TYPE_MODE (lhstype
)) != TYPE_PRECISION (lhstype
))
943 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
944 a
= gimple_assign_rhs1 (stmt
);
945 b
= gimple_assign_rhs2 (stmt
);
946 g
= gimple_build_call_internal (code
== PLUS_EXPR
947 ? IFN_UBSAN_CHECK_ADD
949 ? IFN_UBSAN_CHECK_SUB
950 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
951 gimple_call_set_lhs (g
, lhs
);
952 gsi_replace (&gsi
, g
, false);
957 i = UBSAN_CHECK_SUB (0, u); */
958 a
= build_int_cst (lhstype
, 0);
959 b
= gimple_assign_rhs1 (stmt
);
960 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
961 gimple_call_set_lhs (g
, lhs
);
962 gsi_replace (&gsi
, g
, false);
965 /* Transform i = ABS_EXPR<u>;
967 _N = UBSAN_CHECK_SUB (0, u);
969 a
= build_int_cst (lhstype
, 0);
970 b
= gimple_assign_rhs1 (stmt
);
971 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
972 a
= make_ssa_name (lhstype
, NULL
);
973 gimple_call_set_lhs (g
, a
);
974 gimple_set_location (g
, gimple_location (stmt
));
975 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
976 gimple_assign_set_rhs1 (stmt
, a
);
984 /* Instrument loads from (non-bitfield) bool and C++ enum values
985 to check if the memory value is outside of the range of the valid
989 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
991 gimple stmt
= gsi_stmt (*gsi
);
992 tree rhs
= gimple_assign_rhs1 (stmt
);
993 tree type
= TREE_TYPE (rhs
);
994 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
996 if (TREE_CODE (type
) == BOOLEAN_TYPE
&& (flag_sanitize
& SANITIZE_BOOL
))
998 minv
= boolean_false_node
;
999 maxv
= boolean_true_node
;
1001 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1002 && (flag_sanitize
& SANITIZE_ENUM
)
1003 && TREE_TYPE (type
) != NULL_TREE
1004 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1005 && (TYPE_PRECISION (TREE_TYPE (type
))
1006 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1008 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1009 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1014 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1015 HOST_WIDE_INT bitsize
, bitpos
;
1017 enum machine_mode mode
;
1018 int volatilep
= 0, unsignedp
= 0;
1019 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1020 &unsignedp
, &volatilep
, false);
1021 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1023 if ((TREE_CODE (base
) == VAR_DECL
&& DECL_HARD_REGISTER (base
))
1024 || (bitpos
% modebitsize
) != 0
1025 || bitsize
!= modebitsize
1026 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1027 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1030 location_t loc
= gimple_location (stmt
);
1031 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1032 tree atype
= reference_alias_ptr_type (rhs
);
1033 gimple g
= gimple_build_assign (make_ssa_name (ptype
, NULL
),
1034 build_fold_addr_expr (rhs
));
1035 gimple_set_location (g
, loc
);
1036 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1037 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1038 build_int_cst (atype
, 0));
1039 tree urhs
= make_ssa_name (utype
, NULL
);
1040 g
= gimple_build_assign (urhs
, mem
);
1041 gimple_set_location (g
, loc
);
1042 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1043 minv
= fold_convert (utype
, minv
);
1044 maxv
= fold_convert (utype
, maxv
);
1045 if (!integer_zerop (minv
))
1047 g
= gimple_build_assign_with_ops (MINUS_EXPR
,
1048 make_ssa_name (utype
, NULL
),
1050 gimple_set_location (g
, loc
);
1051 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1054 gimple_stmt_iterator gsi2
= *gsi
;
1055 basic_block then_bb
, fallthru_bb
;
1056 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1057 &then_bb
, &fallthru_bb
);
1058 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1059 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1060 NULL_TREE
, NULL_TREE
);
1061 gimple_set_location (g
, loc
);
1062 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1064 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
, NULL_TREE
);
1067 gsi2
= gsi_after_labels (then_bb
);
1068 if (flag_sanitize_undefined_trap_on_error
)
1069 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1072 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", &loc
, NULL
,
1073 ubsan_type_descriptor (type
), NULL_TREE
);
1074 data
= build_fold_addr_expr_loc (loc
, data
);
1075 enum built_in_function bcode
1076 = flag_sanitize_recover
1077 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1078 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1079 tree fn
= builtin_decl_explicit (bcode
);
1081 tree val
= force_gimple_operand_gsi (&gsi2
, ubsan_encode_value (urhs
),
1082 true, NULL_TREE
, true,
1084 g
= gimple_build_call (fn
, 2, data
, val
);
1086 gimple_set_location (g
, loc
);
1087 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1090 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1091 destination, EXPR is floating-point expression. */
1094 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
)
1096 tree expr_type
= TREE_TYPE (expr
);
1097 tree t
, tt
, fn
, min
, max
;
1098 enum machine_mode mode
= TYPE_MODE (expr_type
);
1099 int prec
= TYPE_PRECISION (type
);
1100 bool uns_p
= TYPE_UNSIGNED (type
);
1102 /* Float to integer conversion first truncates toward zero, so
1103 even signed char c = 127.875f; is not problematic.
1104 Therefore, we should complain only if EXPR is unordered or smaller
1105 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1106 TYPE_MAX_VALUE + 1.0. */
1107 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1109 /* For maximum, TYPE_MAX_VALUE might not be representable
1110 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1111 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1112 either representable or infinity. */
1113 REAL_VALUE_TYPE maxval
= dconst1
;
1114 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1115 real_convert (&maxval
, mode
, &maxval
);
1116 max
= build_real (expr_type
, maxval
);
1118 /* For unsigned, assume -1.0 is always representable. */
1120 min
= build_minus_one_cst (expr_type
);
1123 /* TYPE_MIN_VALUE is generally representable (or -inf),
1124 but TYPE_MIN_VALUE - 1.0 might not be. */
1125 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1126 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1127 real_convert (&minval
, mode
, &minval
);
1128 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1129 real_convert (&minval2
, mode
, &minval2
);
1130 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1131 && !real_isinf (&minval
))
1133 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1134 rounds to TYPE_MIN_VALUE, we need to subtract
1135 more. As REAL_MODE_FORMAT (mode)->p is the number
1136 of base digits, we want to subtract a number that
1137 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1138 times smaller than minval. */
1140 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1141 SET_REAL_EXP (&minval2
,
1142 REAL_EXP (&minval2
) + prec
- 1
1143 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1144 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1145 real_convert (&minval2
, mode
, &minval2
);
1147 min
= build_real (expr_type
, minval2
);
1150 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1152 /* For _Decimal128 up to 34 decimal digits, - sign,
1153 dot, e, exponent. */
1156 int p
= REAL_MODE_FORMAT (mode
)->p
;
1157 REAL_VALUE_TYPE maxval
, minval
;
1159 /* Use mpfr_snprintf rounding to compute the smallest
1160 representable decimal number greater or equal than
1161 1 << (prec - !uns_p). */
1162 mpfr_init2 (m
, prec
+ 2);
1163 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1164 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1165 decimal_real_from_string (&maxval
, buf
);
1166 max
= build_real (expr_type
, maxval
);
1168 /* For unsigned, assume -1.0 is always representable. */
1170 min
= build_minus_one_cst (expr_type
);
1173 /* Use mpfr_snprintf rounding to compute the largest
1174 representable decimal number less or equal than
1175 (-1 << (prec - 1)) - 1. */
1176 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1177 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1178 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1179 decimal_real_from_string (&minval
, buf
);
1180 min
= build_real (expr_type
, minval
);
1187 if (flag_sanitize_undefined_trap_on_error
)
1188 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1191 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1192 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data", NULL
,
1193 NULL
, ubsan_type_descriptor (expr_type
),
1194 ubsan_type_descriptor (type
), NULL_TREE
);
1195 enum built_in_function bcode
1196 = flag_sanitize_recover
1197 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1198 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1199 fn
= builtin_decl_explicit (bcode
);
1200 fn
= build_call_expr_loc (loc
, fn
, 2,
1201 build_fold_addr_expr_loc (loc
, data
),
1202 ubsan_encode_value (expr
, false));
1205 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1206 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1207 return fold_build3 (COND_EXPR
, void_type_node
,
1208 fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
),
1209 fn
, integer_zero_node
);
1214 const pass_data pass_data_ubsan
=
1216 GIMPLE_PASS
, /* type */
1218 OPTGROUP_NONE
, /* optinfo_flags */
1219 TV_TREE_UBSAN
, /* tv_id */
1220 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1221 0, /* properties_provided */
1222 0, /* properties_destroyed */
1223 0, /* todo_flags_start */
1224 TODO_update_ssa
, /* todo_flags_finish */
1227 class pass_ubsan
: public gimple_opt_pass
1230 pass_ubsan (gcc::context
*ctxt
)
1231 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1234 /* opt_pass methods: */
1235 virtual bool gate (function
*)
1237 return flag_sanitize
& (SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1238 | SANITIZE_BOOL
| SANITIZE_ENUM
1239 | SANITIZE_ALIGNMENT
)
1240 && current_function_decl
!= NULL_TREE
1241 && !lookup_attribute ("no_sanitize_undefined",
1242 DECL_ATTRIBUTES (current_function_decl
));
1245 virtual unsigned int execute (function
*);
1247 }; // class pass_ubsan
1250 pass_ubsan::execute (function
*fun
)
1253 gimple_stmt_iterator gsi
;
1255 initialize_sanitizer_builtins ();
1257 FOR_EACH_BB_FN (bb
, fun
)
1259 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1261 gimple stmt
= gsi_stmt (gsi
);
1262 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
1268 if ((flag_sanitize
& SANITIZE_SI_OVERFLOW
)
1269 && is_gimple_assign (stmt
))
1270 instrument_si_overflow (gsi
);
1272 if (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1274 if (gimple_store_p (stmt
))
1275 instrument_null (gsi
, true);
1276 if (gimple_assign_load_p (stmt
))
1277 instrument_null (gsi
, false);
1280 if (flag_sanitize
& (SANITIZE_BOOL
| SANITIZE_ENUM
)
1281 && gimple_assign_load_p (stmt
))
1282 instrument_bool_enum_load (&gsi
);
1293 make_pass_ubsan (gcc::context
*ctxt
)
1295 return new pass_ubsan (ctxt
);
1298 #include "gt-ubsan.h"