* gcc/ChangeLog: Fix ChangeLog entry.
[official-gcc.git] / gcc / ubsan.c
blobe33e62a028ae25dfaa6486171127c594df765d9c
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013 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
10 version.
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
15 for more details.
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/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tree.h"
25 #include "stor-layout.h"
26 #include "stringpool.h"
27 #include "cgraph.h"
28 #include "tree-pass.h"
29 #include "tree-ssa-alias.h"
30 #include "internal-fn.h"
31 #include "gimple-expr.h"
32 #include "gimple.h"
33 #include "gimple-iterator.h"
34 #include "gimple-ssa.h"
35 #include "gimple-walk.h"
36 #include "hashtab.h"
37 #include "output.h"
38 #include "tm_p.h"
39 #include "toplev.h"
40 #include "cfgloop.h"
41 #include "ubsan.h"
42 #include "c-family/c-common.h"
44 /* From trans-mem.c. */
45 #define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 2000 - 1)
47 /* Map from a tree to a VAR_DECL tree. */
49 struct GTY(()) tree_type_map {
50 struct tree_map_base type;
51 tree decl;
54 #define tree_type_map_eq tree_map_base_eq
55 #define tree_type_map_marked_p tree_map_base_marked_p
57 /* Hash from a tree in a tree_type_map. */
59 unsigned int
60 tree_type_map_hash (const void *item)
62 return TYPE_UID (((const struct tree_type_map *)item)->type.from);
65 static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map)))
66 htab_t decl_tree_for_type;
68 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
70 static tree
71 decl_for_type_lookup (tree type)
73 /* If the hash table is not initialized yet, create it now. */
74 if (decl_tree_for_type == NULL)
76 decl_tree_for_type = htab_create_ggc (10, tree_type_map_hash,
77 tree_type_map_eq, 0);
78 /* That also means we don't have to bother with the lookup. */
79 return NULL_TREE;
82 struct tree_type_map *h, in;
83 in.type.from = type;
85 h = (struct tree_type_map *)
86 htab_find_with_hash (decl_tree_for_type, &in, TYPE_UID (type));
87 return h ? h->decl : NULL_TREE;
90 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
92 static void
93 decl_for_type_insert (tree type, tree decl)
95 struct tree_type_map *h;
96 void **slot;
98 h = ggc_alloc_tree_type_map ();
99 h->type.from = type;
100 h->decl = decl;
101 slot = htab_find_slot_with_hash (decl_tree_for_type, h, TYPE_UID (type),
102 INSERT);
103 *(struct tree_type_map **) slot = h;
106 /* Helper routine, which encodes a value in the pointer_sized_int_node.
107 Arguments with precision <= POINTER_SIZE are passed directly,
108 the rest is passed by reference. T is a value we are to encode. */
110 tree
111 ubsan_encode_value (tree t)
113 tree type = TREE_TYPE (t);
114 switch (TREE_CODE (type))
116 case INTEGER_TYPE:
117 if (TYPE_PRECISION (type) <= POINTER_SIZE)
118 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
119 else
120 return build_fold_addr_expr (t);
121 case REAL_TYPE:
123 unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
124 if (bitsize <= POINTER_SIZE)
126 tree itype = build_nonstandard_integer_type (bitsize, true);
127 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
128 return fold_convert (pointer_sized_int_node, t);
130 else
132 if (!TREE_ADDRESSABLE (t))
134 /* The reason for this is that we don't want to pessimize
135 code by making vars unnecessarily addressable. */
136 tree var = create_tmp_var (TREE_TYPE (t), NULL);
137 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
138 t = build_fold_addr_expr (var);
139 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
141 else
142 return build_fold_addr_expr (t);
145 default:
146 gcc_unreachable ();
150 /* Build
151 struct __ubsan_type_descriptor
153 unsigned short __typekind;
154 unsigned short __typeinfo;
155 char __typename[];
157 type. */
159 static tree
160 ubsan_type_descriptor_type (void)
162 static const char *field_names[3]
163 = { "__typekind", "__typeinfo", "__typename" };
164 tree fields[3], ret;
165 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
166 tree flex_arr_type = build_array_type (char_type_node, itype);
168 ret = make_node (RECORD_TYPE);
169 for (int i = 0; i < 3; i++)
171 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
172 get_identifier (field_names[i]),
173 (i == 2) ? flex_arr_type
174 : short_unsigned_type_node);
175 DECL_CONTEXT (fields[i]) = ret;
176 if (i)
177 DECL_CHAIN (fields[i - 1]) = fields[i];
179 TYPE_FIELDS (ret) = fields[0];
180 TYPE_NAME (ret) = get_identifier ("__ubsan_type_descriptor");
181 layout_type (ret);
182 return ret;
185 /* Build
186 struct __ubsan_source_location
188 const char *__filename;
189 unsigned int __line;
190 unsigned int __column;
192 type. */
194 static tree
195 ubsan_source_location_type (void)
197 static const char *field_names[3]
198 = { "__filename", "__line", "__column" };
199 tree fields[3], ret;
200 tree const_char_type = build_qualified_type (char_type_node,
201 TYPE_QUAL_CONST);
203 ret = make_node (RECORD_TYPE);
204 for (int i = 0; i < 3; i++)
206 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
207 get_identifier (field_names[i]),
208 (i == 0) ? build_pointer_type (const_char_type)
209 : unsigned_type_node);
210 DECL_CONTEXT (fields[i]) = ret;
211 if (i)
212 DECL_CHAIN (fields[i - 1]) = fields[i];
214 TYPE_FIELDS (ret) = fields[0];
215 TYPE_NAME (ret) = get_identifier ("__ubsan_source_location");
216 layout_type (ret);
217 return ret;
220 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
221 type with its fields filled from a location_t LOC. */
223 static tree
224 ubsan_source_location (location_t loc)
226 expanded_location xloc;
227 tree type = ubsan_source_location_type ();
229 xloc = expand_location (loc);
231 /* Fill in the values from LOC. */
232 size_t len = strlen (xloc.file);
233 tree str = build_string (len + 1, xloc.file);
234 TREE_TYPE (str) = build_array_type (char_type_node,
235 build_index_type (size_int (len)));
236 TREE_READONLY (str) = 1;
237 TREE_STATIC (str) = 1;
238 str = build_fold_addr_expr (str);
239 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
240 build_int_cst (unsigned_type_node,
241 xloc.line), NULL_TREE,
242 build_int_cst (unsigned_type_node,
243 xloc.column));
244 TREE_CONSTANT (ctor) = 1;
245 TREE_STATIC (ctor) = 1;
247 return ctor;
250 /* This routine returns a magic number for TYPE. */
252 static unsigned short
253 get_ubsan_type_info_for_type (tree type)
255 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
256 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
257 gcc_assert (prec != -1);
258 return (prec << 1) | !TYPE_UNSIGNED (type);
261 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
262 descriptor. It first looks into the hash table; if not found,
263 create the VAR_DECL, put it into the hash table and return the
264 ADDR_EXPR of it. TYPE describes a particular type. WANT_POINTER_TYPE_P
265 means whether we are interested in the pointer type and not the pointer
266 itself. */
268 tree
269 ubsan_type_descriptor (tree type, bool want_pointer_type_p)
271 /* See through any typedefs. */
272 type = TYPE_MAIN_VARIANT (type);
274 tree decl = decl_for_type_lookup (type);
275 /* It is possible that some of the earlier created DECLs were found
276 unused, in that case they weren't emitted and varpool_get_node
277 returns NULL node on them. But now we really need them. Thus,
278 renew them here. */
279 if (decl != NULL_TREE && varpool_get_node (decl))
280 return build_fold_addr_expr (decl);
282 tree dtype = ubsan_type_descriptor_type ();
283 tree type2 = type;
284 const char *tname = NULL;
285 char *pretty_name;
286 unsigned char deref_depth = 0;
287 unsigned short tkind, tinfo;
289 /* Get the name of the type, or the name of the pointer type. */
290 if (want_pointer_type_p)
292 gcc_assert (POINTER_TYPE_P (type));
293 type2 = TREE_TYPE (type);
295 /* Remove any '*' operators from TYPE. */
296 while (POINTER_TYPE_P (type2))
297 deref_depth++, type2 = TREE_TYPE (type2);
299 if (TREE_CODE (type2) == METHOD_TYPE)
300 type2 = TYPE_METHOD_BASETYPE (type2);
303 if (TYPE_NAME (type2) != NULL)
305 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
306 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
307 else
308 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
311 if (tname == NULL)
312 /* We weren't able to determine the type name. */
313 tname = "<unknown>";
315 /* Decorate the type name with '', '*', "struct", or "union". */
316 pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
317 if (want_pointer_type_p)
319 int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
320 TYPE_VOLATILE (type2) ? "volatile " : "",
321 TYPE_READONLY (type2) ? "const " : "",
322 TYPE_RESTRICT (type2) ? "restrict " : "",
323 TYPE_ATOMIC (type2) ? "_Atomic " : "",
324 TREE_CODE (type2) == RECORD_TYPE
325 ? "struct "
326 : TREE_CODE (type2) == UNION_TYPE
327 ? "union " : "", tname,
328 deref_depth == 0 ? "" : " ");
329 while (deref_depth-- > 0)
330 pretty_name[pos++] = '*';
331 pretty_name[pos++] = '\'';
332 pretty_name[pos] = '\0';
334 else
335 sprintf (pretty_name, "'%s'", tname);
337 switch (TREE_CODE (type))
339 case INTEGER_TYPE:
340 tkind = 0x0000;
341 break;
342 case REAL_TYPE:
343 tkind = 0x0001;
344 break;
345 default:
346 tkind = 0xffff;
347 break;
349 tinfo = get_ubsan_type_info_for_type (type);
351 /* Create a new VAR_DECL of type descriptor. */
352 char tmp_name[32];
353 static unsigned int type_var_id_num;
354 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
355 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
356 dtype);
357 TREE_STATIC (decl) = 1;
358 TREE_PUBLIC (decl) = 0;
359 DECL_ARTIFICIAL (decl) = 1;
360 DECL_IGNORED_P (decl) = 1;
361 DECL_EXTERNAL (decl) = 0;
363 size_t len = strlen (pretty_name);
364 tree str = build_string (len + 1, pretty_name);
365 TREE_TYPE (str) = build_array_type (char_type_node,
366 build_index_type (size_int (len)));
367 TREE_READONLY (str) = 1;
368 TREE_STATIC (str) = 1;
369 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
370 build_int_cst (short_unsigned_type_node,
371 tkind), NULL_TREE,
372 build_int_cst (short_unsigned_type_node,
373 tinfo), NULL_TREE, str);
374 TREE_CONSTANT (ctor) = 1;
375 TREE_STATIC (ctor) = 1;
376 DECL_INITIAL (decl) = ctor;
377 rest_of_decl_compilation (decl, 1, 0);
379 /* Save the VAR_DECL into the hash table. */
380 decl_for_type_insert (type, decl);
382 return build_fold_addr_expr (decl);
385 /* Create a structure for the ubsan library. NAME is a name of the new
386 structure. The arguments in ... are of __ubsan_type_descriptor type
387 and there are at most two of them. MISMATCH are data used by ubsan
388 pointer checking. */
390 tree
391 ubsan_create_data (const char *name, location_t loc,
392 const struct ubsan_mismatch_data *mismatch, ...)
394 va_list args;
395 tree ret, t;
396 tree fields[5];
397 vec<tree, va_gc> *saved_args = NULL;
398 size_t i = 0;
400 /* Firstly, create a pointer to type descriptor type. */
401 tree td_type = ubsan_type_descriptor_type ();
402 TYPE_READONLY (td_type) = 1;
403 td_type = build_pointer_type (td_type);
404 loc = LOCATION_LOCUS (loc);
406 /* Create the structure type. */
407 ret = make_node (RECORD_TYPE);
408 if (loc != UNKNOWN_LOCATION)
410 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
411 ubsan_source_location_type ());
412 DECL_CONTEXT (fields[i]) = ret;
413 i++;
416 va_start (args, mismatch);
417 for (t = va_arg (args, tree); t != NULL_TREE;
418 i++, t = va_arg (args, tree))
420 gcc_checking_assert (i < 3);
421 /* Save the tree arguments for later use. */
422 vec_safe_push (saved_args, t);
423 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
424 td_type);
425 DECL_CONTEXT (fields[i]) = ret;
426 if (i)
427 DECL_CHAIN (fields[i - 1]) = fields[i];
429 va_end (args);
431 if (mismatch != NULL)
433 /* We have to add two more decls. */
434 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
435 pointer_sized_int_node);
436 DECL_CONTEXT (fields[i]) = ret;
437 DECL_CHAIN (fields[i - 1]) = fields[i];
438 i++;
440 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
441 unsigned_char_type_node);
442 DECL_CONTEXT (fields[i]) = ret;
443 DECL_CHAIN (fields[i - 1]) = fields[i];
444 i++;
447 TYPE_FIELDS (ret) = fields[0];
448 TYPE_NAME (ret) = get_identifier (name);
449 layout_type (ret);
451 /* Now, fill in the type. */
452 char tmp_name[32];
453 static unsigned int ubsan_var_id_num;
454 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
455 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
456 ret);
457 TREE_STATIC (var) = 1;
458 TREE_PUBLIC (var) = 0;
459 DECL_ARTIFICIAL (var) = 1;
460 DECL_IGNORED_P (var) = 1;
461 DECL_EXTERNAL (var) = 0;
463 vec<constructor_elt, va_gc> *v;
464 vec_alloc (v, i);
465 tree ctor = build_constructor (ret, v);
467 /* If desirable, set the __ubsan_source_location element. */
468 if (loc != UNKNOWN_LOCATION)
469 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
471 size_t nelts = vec_safe_length (saved_args);
472 for (i = 0; i < nelts; i++)
474 t = (*saved_args)[i];
475 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
478 if (mismatch != NULL)
480 /* Append the pointer data. */
481 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->align);
482 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->ckind);
485 TREE_CONSTANT (ctor) = 1;
486 TREE_STATIC (ctor) = 1;
487 DECL_INITIAL (var) = ctor;
488 rest_of_decl_compilation (var, 1, 0);
490 return var;
493 /* Instrument the __builtin_unreachable call. We just call the libubsan
494 routine instead. */
496 tree
497 ubsan_instrument_unreachable (location_t loc)
499 tree data = ubsan_create_data ("__ubsan_unreachable_data", loc, NULL,
500 NULL_TREE);
501 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
502 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
505 /* Return true if T is a call to a libubsan routine. */
507 bool
508 is_ubsan_builtin_p (tree t)
510 gcc_checking_assert (TREE_CODE (t) == FUNCTION_DECL);
511 return strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
512 "__builtin___ubsan_", 18) == 0;
515 /* Expand UBSAN_NULL internal call. */
517 void
518 ubsan_expand_null_ifn (gimple_stmt_iterator gsi)
520 gimple stmt = gsi_stmt (gsi);
521 location_t loc = gimple_location (stmt);
522 gcc_assert (gimple_call_num_args (stmt) == 2);
523 tree ptr = gimple_call_arg (stmt, 0);
524 tree ckind = gimple_call_arg (stmt, 1);
526 basic_block cur_bb = gsi_bb (gsi);
528 /* Split the original block holding the pointer dereference. */
529 edge e = split_block (cur_bb, stmt);
531 /* Get a hold on the 'condition block', the 'then block' and the
532 'else block'. */
533 basic_block cond_bb = e->src;
534 basic_block fallthru_bb = e->dest;
535 basic_block then_bb = create_empty_bb (cond_bb);
536 if (current_loops)
538 add_bb_to_loop (then_bb, cond_bb->loop_father);
539 loops_state_set (LOOPS_NEED_FIXUP);
542 /* Make an edge coming from the 'cond block' into the 'then block';
543 this edge is unlikely taken, so set up the probability accordingly. */
544 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
545 e->probability = PROB_VERY_UNLIKELY;
547 /* Connect 'then block' with the 'else block'. This is needed
548 as the ubsan routines we call in the 'then block' are not noreturn.
549 The 'then block' only has one outcoming edge. */
550 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
552 /* Set up the fallthrough basic block. */
553 e = find_edge (cond_bb, fallthru_bb);
554 e->flags = EDGE_FALSE_VALUE;
555 e->count = cond_bb->count;
556 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
558 /* Update dominance info for the newly created then_bb; note that
559 fallthru_bb's dominance info has already been updated by
560 split_bock. */
561 if (dom_info_available_p (CDI_DOMINATORS))
562 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
564 /* Put the ubsan builtin call into the newly created BB. */
565 tree fn = builtin_decl_implicit (BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH);
566 const struct ubsan_mismatch_data m
567 = { build_zero_cst (pointer_sized_int_node), ckind };
568 tree data = ubsan_create_data ("__ubsan_null_data",
569 loc, &m,
570 ubsan_type_descriptor (TREE_TYPE (ptr), true),
571 NULL_TREE);
572 data = build_fold_addr_expr_loc (loc, data);
573 gimple g = gimple_build_call (fn, 2, data,
574 build_zero_cst (pointer_sized_int_node));
575 gimple_set_location (g, loc);
576 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
577 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
579 /* Unlink the UBSAN_NULLs vops before replacing it. */
580 unlink_stmt_vdef (stmt);
582 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
583 NULL_TREE, NULL_TREE);
584 gimple_set_location (g, loc);
586 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
587 gsi_replace (&gsi, g, false);
590 /* Instrument a member call. We check whether 'this' is NULL. */
592 static void
593 instrument_member_call (gimple_stmt_iterator *iter)
595 tree this_parm = gimple_call_arg (gsi_stmt (*iter), 0);
596 tree kind = build_int_cst (unsigned_char_type_node, UBSAN_MEMBER_CALL);
597 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, this_parm, kind);
598 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
599 gsi_insert_before (iter, g, GSI_SAME_STMT);
602 /* Instrument a memory reference. T is the pointer, IS_LHS says
603 whether the pointer is on the left hand side of the assignment. */
605 static void
606 instrument_mem_ref (tree t, gimple_stmt_iterator *iter, bool is_lhs)
608 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
609 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
610 ikind = UBSAN_MEMBER_ACCESS;
611 tree kind = build_int_cst (unsigned_char_type_node, ikind);
612 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, t, kind);
613 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
614 gsi_insert_before (iter, g, GSI_SAME_STMT);
617 /* Perform the pointer instrumentation. */
619 static void
620 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
622 gimple stmt = gsi_stmt (gsi);
623 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
624 t = get_base_address (t);
625 const enum tree_code code = TREE_CODE (t);
626 if (code == MEM_REF
627 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
628 instrument_mem_ref (TREE_OPERAND (t, 0), &gsi, is_lhs);
629 else if (code == ADDR_EXPR
630 && POINTER_TYPE_P (TREE_TYPE (t))
631 && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == METHOD_TYPE)
632 instrument_member_call (&gsi);
635 /* Gate and execute functions for ubsan pass. */
637 static unsigned int
638 ubsan_pass (void)
640 basic_block bb;
641 gimple_stmt_iterator gsi;
643 FOR_EACH_BB (bb)
645 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
647 gimple stmt = gsi_stmt (gsi);
648 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
650 gsi_next (&gsi);
651 continue;
654 if (flag_sanitize & SANITIZE_NULL)
656 if (gimple_store_p (stmt))
657 instrument_null (gsi, true);
658 if (gimple_assign_load_p (stmt))
659 instrument_null (gsi, false);
662 gsi_next (&gsi);
665 return 0;
668 static bool
669 gate_ubsan (void)
671 return flag_sanitize & SANITIZE_NULL;
674 namespace {
676 const pass_data pass_data_ubsan =
678 GIMPLE_PASS, /* type */
679 "ubsan", /* name */
680 OPTGROUP_NONE, /* optinfo_flags */
681 true, /* has_gate */
682 true, /* has_execute */
683 TV_TREE_UBSAN, /* tv_id */
684 ( PROP_cfg | PROP_ssa ), /* properties_required */
685 0, /* properties_provided */
686 0, /* properties_destroyed */
687 0, /* todo_flags_start */
688 TODO_update_ssa, /* todo_flags_finish */
691 class pass_ubsan : public gimple_opt_pass
693 public:
694 pass_ubsan (gcc::context *ctxt)
695 : gimple_opt_pass (pass_data_ubsan, ctxt)
698 /* opt_pass methods: */
699 bool gate () { return gate_ubsan (); }
700 unsigned int execute () { return ubsan_pass (); }
702 }; // class pass_ubsan
704 } // anon namespace
706 gimple_opt_pass *
707 make_pass_ubsan (gcc::context *ctxt)
709 return new pass_ubsan (ctxt);
712 #include "gt-ubsan.h"