re PR tree-optimization/59287 (points-to analysis confused by union accesses)
[official-gcc.git] / gcc / ubsan.c
bloba16f3eb097f1981b46c8365105b989bf6c23b35b
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 = xloc.file ? strlen (xloc.file) : 0;
233 tree str = build_string (len + 1, xloc.file ? 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_loc (loc, 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 if (decl != NULL_TREE)
276 return decl;
278 tree dtype = ubsan_type_descriptor_type ();
279 tree type2 = type;
280 const char *tname = NULL;
281 char *pretty_name;
282 unsigned char deref_depth = 0;
283 unsigned short tkind, tinfo;
285 /* Get the name of the type, or the name of the pointer type. */
286 if (want_pointer_type_p)
288 gcc_assert (POINTER_TYPE_P (type));
289 type2 = TREE_TYPE (type);
291 /* Remove any '*' operators from TYPE. */
292 while (POINTER_TYPE_P (type2))
293 deref_depth++, type2 = TREE_TYPE (type2);
295 if (TREE_CODE (type2) == METHOD_TYPE)
296 type2 = TYPE_METHOD_BASETYPE (type2);
299 if (TYPE_NAME (type2) != NULL)
301 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
302 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
303 else
304 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
307 if (tname == NULL)
308 /* We weren't able to determine the type name. */
309 tname = "<unknown>";
311 /* Decorate the type name with '', '*', "struct", or "union". */
312 pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
313 if (want_pointer_type_p)
315 int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
316 TYPE_VOLATILE (type2) ? "volatile " : "",
317 TYPE_READONLY (type2) ? "const " : "",
318 TYPE_RESTRICT (type2) ? "restrict " : "",
319 TYPE_ATOMIC (type2) ? "_Atomic " : "",
320 TREE_CODE (type2) == RECORD_TYPE
321 ? "struct "
322 : TREE_CODE (type2) == UNION_TYPE
323 ? "union " : "", tname,
324 deref_depth == 0 ? "" : " ");
325 while (deref_depth-- > 0)
326 pretty_name[pos++] = '*';
327 pretty_name[pos++] = '\'';
328 pretty_name[pos] = '\0';
330 else
331 sprintf (pretty_name, "'%s'", tname);
333 switch (TREE_CODE (type))
335 case INTEGER_TYPE:
336 tkind = 0x0000;
337 break;
338 case REAL_TYPE:
339 tkind = 0x0001;
340 break;
341 default:
342 tkind = 0xffff;
343 break;
345 tinfo = get_ubsan_type_info_for_type (type);
347 /* Create a new VAR_DECL of type descriptor. */
348 char tmp_name[32];
349 static unsigned int type_var_id_num;
350 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
351 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
352 dtype);
353 TREE_STATIC (decl) = 1;
354 TREE_PUBLIC (decl) = 0;
355 DECL_ARTIFICIAL (decl) = 1;
356 DECL_IGNORED_P (decl) = 1;
357 DECL_EXTERNAL (decl) = 0;
359 size_t len = strlen (pretty_name);
360 tree str = build_string (len + 1, pretty_name);
361 TREE_TYPE (str) = build_array_type (char_type_node,
362 build_index_type (size_int (len)));
363 TREE_READONLY (str) = 1;
364 TREE_STATIC (str) = 1;
365 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
366 build_int_cst (short_unsigned_type_node,
367 tkind), NULL_TREE,
368 build_int_cst (short_unsigned_type_node,
369 tinfo), NULL_TREE, str);
370 TREE_CONSTANT (ctor) = 1;
371 TREE_STATIC (ctor) = 1;
372 DECL_INITIAL (decl) = ctor;
373 rest_of_decl_compilation (decl, 1, 0);
375 /* Save the address of the VAR_DECL into the hash table. */
376 decl = build_fold_addr_expr (decl);
377 decl_for_type_insert (type, decl);
379 return decl;
382 /* Create a structure for the ubsan library. NAME is a name of the new
383 structure. The arguments in ... are of __ubsan_type_descriptor type
384 and there are at most two of them. MISMATCH are data used by ubsan
385 pointer checking. */
387 tree
388 ubsan_create_data (const char *name, location_t loc,
389 const struct ubsan_mismatch_data *mismatch, ...)
391 va_list args;
392 tree ret, t;
393 tree fields[5];
394 vec<tree, va_gc> *saved_args = NULL;
395 size_t i = 0;
397 /* Firstly, create a pointer to type descriptor type. */
398 tree td_type = ubsan_type_descriptor_type ();
399 TYPE_READONLY (td_type) = 1;
400 td_type = build_pointer_type (td_type);
402 /* Create the structure type. */
403 ret = make_node (RECORD_TYPE);
404 if (loc != UNKNOWN_LOCATION)
406 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
407 ubsan_source_location_type ());
408 DECL_CONTEXT (fields[i]) = ret;
409 i++;
412 va_start (args, mismatch);
413 for (t = va_arg (args, tree); t != NULL_TREE;
414 i++, t = va_arg (args, tree))
416 gcc_checking_assert (i < 3);
417 /* Save the tree arguments for later use. */
418 vec_safe_push (saved_args, t);
419 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
420 td_type);
421 DECL_CONTEXT (fields[i]) = ret;
422 if (i)
423 DECL_CHAIN (fields[i - 1]) = fields[i];
425 va_end (args);
427 if (mismatch != NULL)
429 /* We have to add two more decls. */
430 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
431 pointer_sized_int_node);
432 DECL_CONTEXT (fields[i]) = ret;
433 DECL_CHAIN (fields[i - 1]) = fields[i];
434 i++;
436 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
437 unsigned_char_type_node);
438 DECL_CONTEXT (fields[i]) = ret;
439 DECL_CHAIN (fields[i - 1]) = fields[i];
440 i++;
443 TYPE_FIELDS (ret) = fields[0];
444 TYPE_NAME (ret) = get_identifier (name);
445 layout_type (ret);
447 /* Now, fill in the type. */
448 char tmp_name[32];
449 static unsigned int ubsan_var_id_num;
450 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
451 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
452 ret);
453 TREE_STATIC (var) = 1;
454 TREE_PUBLIC (var) = 0;
455 DECL_ARTIFICIAL (var) = 1;
456 DECL_IGNORED_P (var) = 1;
457 DECL_EXTERNAL (var) = 0;
459 vec<constructor_elt, va_gc> *v;
460 vec_alloc (v, i);
461 tree ctor = build_constructor (ret, v);
463 /* If desirable, set the __ubsan_source_location element. */
464 if (loc != UNKNOWN_LOCATION)
465 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
467 size_t nelts = vec_safe_length (saved_args);
468 for (i = 0; i < nelts; i++)
470 t = (*saved_args)[i];
471 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
474 if (mismatch != NULL)
476 /* Append the pointer data. */
477 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->align);
478 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->ckind);
481 TREE_CONSTANT (ctor) = 1;
482 TREE_STATIC (ctor) = 1;
483 DECL_INITIAL (var) = ctor;
484 rest_of_decl_compilation (var, 1, 0);
486 return var;
489 /* Instrument the __builtin_unreachable call. We just call the libubsan
490 routine instead. */
492 tree
493 ubsan_instrument_unreachable (location_t loc)
495 tree data = ubsan_create_data ("__ubsan_unreachable_data", loc, NULL,
496 NULL_TREE);
497 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
498 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
501 /* Return true if T is a call to a libubsan routine. */
503 bool
504 is_ubsan_builtin_p (tree t)
506 gcc_checking_assert (TREE_CODE (t) == FUNCTION_DECL);
507 return strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
508 "__builtin___ubsan_", 18) == 0;
511 /* Expand UBSAN_NULL internal call. */
513 void
514 ubsan_expand_null_ifn (gimple_stmt_iterator gsi)
516 gimple stmt = gsi_stmt (gsi);
517 location_t loc = gimple_location (stmt);
518 gcc_assert (gimple_call_num_args (stmt) == 2);
519 tree ptr = gimple_call_arg (stmt, 0);
520 tree ckind = gimple_call_arg (stmt, 1);
522 basic_block cur_bb = gsi_bb (gsi);
524 /* Split the original block holding the pointer dereference. */
525 edge e = split_block (cur_bb, stmt);
527 /* Get a hold on the 'condition block', the 'then block' and the
528 'else block'. */
529 basic_block cond_bb = e->src;
530 basic_block fallthru_bb = e->dest;
531 basic_block then_bb = create_empty_bb (cond_bb);
532 if (current_loops)
534 add_bb_to_loop (then_bb, cond_bb->loop_father);
535 loops_state_set (LOOPS_NEED_FIXUP);
538 /* Make an edge coming from the 'cond block' into the 'then block';
539 this edge is unlikely taken, so set up the probability accordingly. */
540 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
541 e->probability = PROB_VERY_UNLIKELY;
543 /* Connect 'then block' with the 'else block'. This is needed
544 as the ubsan routines we call in the 'then block' are not noreturn.
545 The 'then block' only has one outcoming edge. */
546 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
548 /* Set up the fallthrough basic block. */
549 e = find_edge (cond_bb, fallthru_bb);
550 e->flags = EDGE_FALSE_VALUE;
551 e->count = cond_bb->count;
552 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
554 /* Update dominance info for the newly created then_bb; note that
555 fallthru_bb's dominance info has already been updated by
556 split_bock. */
557 if (dom_info_available_p (CDI_DOMINATORS))
558 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
560 /* Put the ubsan builtin call into the newly created BB. */
561 tree fn = builtin_decl_implicit (BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH);
562 const struct ubsan_mismatch_data m
563 = { build_zero_cst (pointer_sized_int_node), ckind };
564 tree data = ubsan_create_data ("__ubsan_null_data",
565 loc, &m,
566 ubsan_type_descriptor (TREE_TYPE (ptr), true),
567 NULL_TREE);
568 data = build_fold_addr_expr_loc (loc, data);
569 gimple g = gimple_build_call (fn, 2, data,
570 build_zero_cst (pointer_sized_int_node));
571 gimple_set_location (g, loc);
572 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
573 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
575 /* Unlink the UBSAN_NULLs vops before replacing it. */
576 unlink_stmt_vdef (stmt);
578 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
579 NULL_TREE, NULL_TREE);
580 gimple_set_location (g, loc);
582 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
583 gsi_replace (&gsi, g, false);
586 /* Instrument a member call. We check whether 'this' is NULL. */
588 static void
589 instrument_member_call (gimple_stmt_iterator *iter)
591 tree this_parm = gimple_call_arg (gsi_stmt (*iter), 0);
592 tree kind = build_int_cst (unsigned_char_type_node, UBSAN_MEMBER_CALL);
593 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, this_parm, kind);
594 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
595 gsi_insert_before (iter, g, GSI_SAME_STMT);
598 /* Instrument a memory reference. T is the pointer, IS_LHS says
599 whether the pointer is on the left hand side of the assignment. */
601 static void
602 instrument_mem_ref (tree t, gimple_stmt_iterator *iter, bool is_lhs)
604 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
605 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
606 ikind = UBSAN_MEMBER_ACCESS;
607 tree kind = build_int_cst (unsigned_char_type_node, ikind);
608 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, t, kind);
609 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
610 gsi_insert_before (iter, g, GSI_SAME_STMT);
613 /* Callback function for the pointer instrumentation. */
615 static tree
616 instrument_null (tree *tp, int * /*walk_subtree*/, void *data)
618 tree t = *tp;
619 const enum tree_code code = TREE_CODE (t);
620 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
622 if (code == MEM_REF
623 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
624 instrument_mem_ref (TREE_OPERAND (t, 0), &wi->gsi, wi->is_lhs);
625 else if (code == ADDR_EXPR
626 && POINTER_TYPE_P (TREE_TYPE (t))
627 && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == METHOD_TYPE)
628 instrument_member_call (&wi->gsi);
630 return NULL_TREE;
633 /* Gate and execute functions for ubsan pass. */
635 static unsigned int
636 ubsan_pass (void)
638 basic_block bb;
639 gimple_stmt_iterator gsi;
641 FOR_EACH_BB (bb)
643 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
645 struct walk_stmt_info wi;
646 gimple stmt = gsi_stmt (gsi);
647 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
649 gsi_next (&gsi);
650 continue;
653 memset (&wi, 0, sizeof (wi));
654 wi.gsi = gsi;
655 walk_gimple_op (stmt, instrument_null, &wi);
656 gsi_next (&gsi);
659 return 0;
662 static bool
663 gate_ubsan (void)
665 return flag_sanitize & SANITIZE_NULL;
668 namespace {
670 const pass_data pass_data_ubsan =
672 GIMPLE_PASS, /* type */
673 "ubsan", /* name */
674 OPTGROUP_NONE, /* optinfo_flags */
675 true, /* has_gate */
676 true, /* has_execute */
677 TV_TREE_UBSAN, /* tv_id */
678 ( PROP_cfg | PROP_ssa ), /* properties_required */
679 0, /* properties_provided */
680 0, /* properties_destroyed */
681 0, /* todo_flags_start */
682 TODO_update_ssa, /* todo_flags_finish */
685 class pass_ubsan : public gimple_opt_pass
687 public:
688 pass_ubsan (gcc::context *ctxt)
689 : gimple_opt_pass (pass_data_ubsan, ctxt)
692 /* opt_pass methods: */
693 bool gate () { return gate_ubsan (); }
694 unsigned int execute () { return ubsan_pass (); }
696 }; // class pass_ubsan
698 } // anon namespace
700 gimple_opt_pass *
701 make_pass_ubsan (gcc::context *ctxt)
703 return new pass_ubsan (ctxt);
706 #include "gt-ubsan.h"