* asan.c (create_cond_insert_point): Maintain profile.
[official-gcc.git] / gcc / ubsan.c
blob52dacd001f8db0cd81806ea1c808a5e8b694fe56
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2017 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 "backend.h"
25 #include "rtl.h"
26 #include "c-family/c-common.h"
27 #include "gimple.h"
28 #include "cfghooks.h"
29 #include "tree-pass.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "ssa.h"
33 #include "cgraph.h"
34 #include "tree-pretty-print.h"
35 #include "stor-layout.h"
36 #include "cfganal.h"
37 #include "gimple-iterator.h"
38 #include "output.h"
39 #include "cfgloop.h"
40 #include "ubsan.h"
41 #include "expr.h"
42 #include "stringpool.h"
43 #include "attribs.h"
44 #include "asan.h"
45 #include "gimplify-me.h"
46 #include "dfp.h"
47 #include "builtins.h"
48 #include "tree-object-size.h"
49 #include "tree-cfg.h"
50 #include "gimple-fold.h"
51 #include "varasm.h"
53 /* Map from a tree to a VAR_DECL tree. */
55 struct GTY((for_user)) tree_type_map {
56 struct tree_map_base type;
57 tree decl;
60 struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
62 static inline hashval_t
63 hash (tree_type_map *t)
65 return TYPE_UID (t->type.from);
68 static inline bool
69 equal (tree_type_map *a, tree_type_map *b)
71 return a->type.from == b->type.from;
74 static int
75 keep_cache_entry (tree_type_map *&m)
77 return ggc_marked_p (m->type.from);
81 static GTY ((cache))
82 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
84 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
86 static tree
87 decl_for_type_lookup (tree type)
89 /* If the hash table is not initialized yet, create it now. */
90 if (decl_tree_for_type == NULL)
92 decl_tree_for_type
93 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
94 /* That also means we don't have to bother with the lookup. */
95 return NULL_TREE;
98 struct tree_type_map *h, in;
99 in.type.from = type;
101 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
102 return h ? h->decl : NULL_TREE;
105 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
107 static void
108 decl_for_type_insert (tree type, tree decl)
110 struct tree_type_map *h;
112 h = ggc_alloc<tree_type_map> ();
113 h->type.from = type;
114 h->decl = decl;
115 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
118 /* Helper routine, which encodes a value in the pointer_sized_int_node.
119 Arguments with precision <= POINTER_SIZE are passed directly,
120 the rest is passed by reference. T is a value we are to encode.
121 PHASE determines when this function is called. */
123 tree
124 ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase)
126 tree type = TREE_TYPE (t);
127 scalar_mode mode = SCALAR_TYPE_MODE (type);
128 const unsigned int bitsize = GET_MODE_BITSIZE (mode);
129 if (bitsize <= POINTER_SIZE)
130 switch (TREE_CODE (type))
132 case BOOLEAN_TYPE:
133 case ENUMERAL_TYPE:
134 case INTEGER_TYPE:
135 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
136 case REAL_TYPE:
138 tree itype = build_nonstandard_integer_type (bitsize, true);
139 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
140 return fold_convert (pointer_sized_int_node, t);
142 default:
143 gcc_unreachable ();
145 else
147 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
149 /* The reason for this is that we don't want to pessimize
150 code by making vars unnecessarily addressable. */
151 tree var;
152 if (phase != UBSAN_ENCODE_VALUE_GENERIC)
154 var = create_tmp_var (type);
155 mark_addressable (var);
157 else
159 var = create_tmp_var_raw (type);
160 TREE_ADDRESSABLE (var) = 1;
161 DECL_CONTEXT (var) = current_function_decl;
163 if (phase == UBSAN_ENCODE_VALUE_RTL)
165 rtx mem = assign_stack_temp_for_type (mode, GET_MODE_SIZE (mode),
166 type);
167 SET_DECL_RTL (var, mem);
168 expand_assignment (var, t, false);
169 return build_fold_addr_expr (var);
171 if (phase != UBSAN_ENCODE_VALUE_GENERIC)
173 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
174 t = build_fold_addr_expr (var);
175 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
177 else
179 var = build4 (TARGET_EXPR, type, var, t, NULL_TREE, NULL_TREE);
180 return build_fold_addr_expr (var);
183 else
184 return build_fold_addr_expr (t);
188 /* Cached ubsan_get_type_descriptor_type () return value. */
189 static GTY(()) tree ubsan_type_descriptor_type;
191 /* Build
192 struct __ubsan_type_descriptor
194 unsigned short __typekind;
195 unsigned short __typeinfo;
196 char __typename[];
198 type. */
200 static tree
201 ubsan_get_type_descriptor_type (void)
203 static const char *field_names[3]
204 = { "__typekind", "__typeinfo", "__typename" };
205 tree fields[3], ret;
207 if (ubsan_type_descriptor_type)
208 return ubsan_type_descriptor_type;
210 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
211 tree flex_arr_type = build_array_type (char_type_node, itype);
213 ret = make_node (RECORD_TYPE);
214 for (int i = 0; i < 3; i++)
216 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
217 get_identifier (field_names[i]),
218 (i == 2) ? flex_arr_type
219 : short_unsigned_type_node);
220 DECL_CONTEXT (fields[i]) = ret;
221 if (i)
222 DECL_CHAIN (fields[i - 1]) = fields[i];
224 tree type_decl = build_decl (input_location, TYPE_DECL,
225 get_identifier ("__ubsan_type_descriptor"),
226 ret);
227 DECL_IGNORED_P (type_decl) = 1;
228 DECL_ARTIFICIAL (type_decl) = 1;
229 TYPE_FIELDS (ret) = fields[0];
230 TYPE_NAME (ret) = type_decl;
231 TYPE_STUB_DECL (ret) = type_decl;
232 layout_type (ret);
233 ubsan_type_descriptor_type = ret;
234 return ret;
237 /* Cached ubsan_get_source_location_type () return value. */
238 static GTY(()) tree ubsan_source_location_type;
240 /* Build
241 struct __ubsan_source_location
243 const char *__filename;
244 unsigned int __line;
245 unsigned int __column;
247 type. */
249 tree
250 ubsan_get_source_location_type (void)
252 static const char *field_names[3]
253 = { "__filename", "__line", "__column" };
254 tree fields[3], ret;
255 if (ubsan_source_location_type)
256 return ubsan_source_location_type;
258 tree const_char_type = build_qualified_type (char_type_node,
259 TYPE_QUAL_CONST);
261 ret = make_node (RECORD_TYPE);
262 for (int i = 0; i < 3; i++)
264 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
265 get_identifier (field_names[i]),
266 (i == 0) ? build_pointer_type (const_char_type)
267 : unsigned_type_node);
268 DECL_CONTEXT (fields[i]) = ret;
269 if (i)
270 DECL_CHAIN (fields[i - 1]) = fields[i];
272 tree type_decl = build_decl (input_location, TYPE_DECL,
273 get_identifier ("__ubsan_source_location"),
274 ret);
275 DECL_IGNORED_P (type_decl) = 1;
276 DECL_ARTIFICIAL (type_decl) = 1;
277 TYPE_FIELDS (ret) = fields[0];
278 TYPE_NAME (ret) = type_decl;
279 TYPE_STUB_DECL (ret) = type_decl;
280 layout_type (ret);
281 ubsan_source_location_type = ret;
282 return ret;
285 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
286 type with its fields filled from a location_t LOC. */
288 static tree
289 ubsan_source_location (location_t loc)
291 expanded_location xloc;
292 tree type = ubsan_get_source_location_type ();
294 xloc = expand_location (loc);
295 tree str;
296 if (xloc.file == NULL)
298 str = build_int_cst (ptr_type_node, 0);
299 xloc.line = 0;
300 xloc.column = 0;
302 else
304 /* Fill in the values from LOC. */
305 size_t len = strlen (xloc.file) + 1;
306 str = build_string (len, xloc.file);
307 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
308 TREE_READONLY (str) = 1;
309 TREE_STATIC (str) = 1;
310 str = build_fold_addr_expr (str);
312 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
313 build_int_cst (unsigned_type_node,
314 xloc.line), NULL_TREE,
315 build_int_cst (unsigned_type_node,
316 xloc.column));
317 TREE_CONSTANT (ctor) = 1;
318 TREE_STATIC (ctor) = 1;
320 return ctor;
323 /* This routine returns a magic number for TYPE. */
325 static unsigned short
326 get_ubsan_type_info_for_type (tree type)
328 if (TREE_CODE (type) == REAL_TYPE)
329 return tree_to_uhwi (TYPE_SIZE (type));
330 else if (INTEGRAL_TYPE_P (type))
332 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
333 gcc_assert (prec != -1);
334 return (prec << 1) | !TYPE_UNSIGNED (type);
336 else
337 return 0;
340 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
341 ubsan_ids[1] for Lubsan_data labels. */
342 static GTY(()) unsigned int ubsan_ids[2];
344 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
345 descriptor. It first looks into the hash table; if not found,
346 create the VAR_DECL, put it into the hash table and return the
347 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
348 an enum controlling how we want to print the type. */
350 tree
351 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
353 /* See through any typedefs. */
354 type = TYPE_MAIN_VARIANT (type);
356 tree decl = decl_for_type_lookup (type);
357 /* It is possible that some of the earlier created DECLs were found
358 unused, in that case they weren't emitted and varpool_node::get
359 returns NULL node on them. But now we really need them. Thus,
360 renew them here. */
361 if (decl != NULL_TREE && varpool_node::get (decl))
362 return build_fold_addr_expr (decl);
364 tree dtype = ubsan_get_type_descriptor_type ();
365 tree type2 = type;
366 const char *tname = NULL;
367 pretty_printer pretty_name;
368 unsigned char deref_depth = 0;
369 unsigned short tkind, tinfo;
371 /* Get the name of the type, or the name of the pointer type. */
372 if (pstyle == UBSAN_PRINT_POINTER)
374 gcc_assert (POINTER_TYPE_P (type));
375 type2 = TREE_TYPE (type);
377 /* Remove any '*' operators from TYPE. */
378 while (POINTER_TYPE_P (type2))
379 deref_depth++, type2 = TREE_TYPE (type2);
381 if (TREE_CODE (type2) == METHOD_TYPE)
382 type2 = TYPE_METHOD_BASETYPE (type2);
385 /* If an array, get its type. */
386 type2 = strip_array_types (type2);
388 if (pstyle == UBSAN_PRINT_ARRAY)
390 while (POINTER_TYPE_P (type2))
391 deref_depth++, type2 = TREE_TYPE (type2);
394 if (TYPE_NAME (type2) != NULL)
396 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
397 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
398 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
399 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
402 if (tname == NULL)
403 /* We weren't able to determine the type name. */
404 tname = "<unknown>";
406 tree eltype = type;
407 if (pstyle == UBSAN_PRINT_POINTER)
409 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
410 TYPE_VOLATILE (type2) ? "volatile " : "",
411 TYPE_READONLY (type2) ? "const " : "",
412 TYPE_RESTRICT (type2) ? "restrict " : "",
413 TYPE_ATOMIC (type2) ? "_Atomic " : "",
414 TREE_CODE (type2) == RECORD_TYPE
415 ? "struct "
416 : TREE_CODE (type2) == UNION_TYPE
417 ? "union " : "", tname,
418 deref_depth == 0 ? "" : " ");
419 while (deref_depth-- > 0)
420 pp_star (&pretty_name);
421 pp_quote (&pretty_name);
423 else if (pstyle == UBSAN_PRINT_ARRAY)
425 /* Pretty print the array dimensions. */
426 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
427 tree t = type;
428 pp_printf (&pretty_name, "'%s ", tname);
429 while (deref_depth-- > 0)
430 pp_star (&pretty_name);
431 while (TREE_CODE (t) == ARRAY_TYPE)
433 pp_left_bracket (&pretty_name);
434 tree dom = TYPE_DOMAIN (t);
435 if (dom != NULL_TREE
436 && TYPE_MAX_VALUE (dom) != NULL_TREE
437 && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
439 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
440 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
441 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
442 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
443 else
444 pp_wide_int (&pretty_name,
445 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
446 TYPE_SIGN (TREE_TYPE (dom)));
448 else
449 /* ??? We can't determine the variable name; print VLA unspec. */
450 pp_star (&pretty_name);
451 pp_right_bracket (&pretty_name);
452 t = TREE_TYPE (t);
454 pp_quote (&pretty_name);
456 /* Save the tree with stripped types. */
457 eltype = t;
459 else
460 pp_printf (&pretty_name, "'%s'", tname);
462 switch (TREE_CODE (eltype))
464 case BOOLEAN_TYPE:
465 case ENUMERAL_TYPE:
466 case INTEGER_TYPE:
467 tkind = 0x0000;
468 break;
469 case REAL_TYPE:
470 /* FIXME: libubsan right now only supports float, double and
471 long double type formats. */
472 if (TYPE_MODE (eltype) == TYPE_MODE (float_type_node)
473 || TYPE_MODE (eltype) == TYPE_MODE (double_type_node)
474 || TYPE_MODE (eltype) == TYPE_MODE (long_double_type_node))
475 tkind = 0x0001;
476 else
477 tkind = 0xffff;
478 break;
479 default:
480 tkind = 0xffff;
481 break;
483 tinfo = get_ubsan_type_info_for_type (eltype);
485 /* Create a new VAR_DECL of type descriptor. */
486 const char *tmp = pp_formatted_text (&pretty_name);
487 size_t len = strlen (tmp) + 1;
488 tree str = build_string (len, tmp);
489 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
490 TREE_READONLY (str) = 1;
491 TREE_STATIC (str) = 1;
493 char tmp_name[32];
494 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
495 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
496 dtype);
497 TREE_STATIC (decl) = 1;
498 TREE_PUBLIC (decl) = 0;
499 DECL_ARTIFICIAL (decl) = 1;
500 DECL_IGNORED_P (decl) = 1;
501 DECL_EXTERNAL (decl) = 0;
502 DECL_SIZE (decl)
503 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
504 DECL_SIZE_UNIT (decl)
505 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
506 TYPE_SIZE_UNIT (TREE_TYPE (str)));
508 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
509 build_int_cst (short_unsigned_type_node,
510 tkind), NULL_TREE,
511 build_int_cst (short_unsigned_type_node,
512 tinfo), NULL_TREE, str);
513 TREE_CONSTANT (ctor) = 1;
514 TREE_STATIC (ctor) = 1;
515 DECL_INITIAL (decl) = ctor;
516 varpool_node::finalize_decl (decl);
518 /* Save the VAR_DECL into the hash table. */
519 decl_for_type_insert (type, decl);
521 return build_fold_addr_expr (decl);
524 /* Create a structure for the ubsan library. NAME is a name of the new
525 structure. LOCCNT is number of locations, PLOC points to array of
526 locations. The arguments in ... are of __ubsan_type_descriptor type
527 and there are at most two of them, followed by NULL_TREE, followed
528 by optional extra arguments and another NULL_TREE. */
530 tree
531 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
533 va_list args;
534 tree ret, t;
535 tree fields[6];
536 vec<tree, va_gc> *saved_args = NULL;
537 size_t i = 0;
538 int j;
540 /* It is possible that PCH zapped table with definitions of sanitizer
541 builtins. Reinitialize them if needed. */
542 initialize_sanitizer_builtins ();
544 /* Firstly, create a pointer to type descriptor type. */
545 tree td_type = ubsan_get_type_descriptor_type ();
546 td_type = build_pointer_type (td_type);
548 /* Create the structure type. */
549 ret = make_node (RECORD_TYPE);
550 for (j = 0; j < loccnt; j++)
552 gcc_checking_assert (i < 2);
553 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
554 ubsan_get_source_location_type ());
555 DECL_CONTEXT (fields[i]) = ret;
556 if (i)
557 DECL_CHAIN (fields[i - 1]) = fields[i];
558 i++;
561 va_start (args, ploc);
562 for (t = va_arg (args, tree); t != NULL_TREE;
563 i++, t = va_arg (args, tree))
565 gcc_checking_assert (i < 4);
566 /* Save the tree arguments for later use. */
567 vec_safe_push (saved_args, t);
568 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
569 td_type);
570 DECL_CONTEXT (fields[i]) = ret;
571 if (i)
572 DECL_CHAIN (fields[i - 1]) = fields[i];
575 for (t = va_arg (args, tree); t != NULL_TREE;
576 i++, t = va_arg (args, tree))
578 gcc_checking_assert (i < 6);
579 /* Save the tree arguments for later use. */
580 vec_safe_push (saved_args, t);
581 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
582 TREE_TYPE (t));
583 DECL_CONTEXT (fields[i]) = ret;
584 if (i)
585 DECL_CHAIN (fields[i - 1]) = fields[i];
587 va_end (args);
589 tree type_decl = build_decl (input_location, TYPE_DECL,
590 get_identifier (name), ret);
591 DECL_IGNORED_P (type_decl) = 1;
592 DECL_ARTIFICIAL (type_decl) = 1;
593 TYPE_FIELDS (ret) = fields[0];
594 TYPE_NAME (ret) = type_decl;
595 TYPE_STUB_DECL (ret) = type_decl;
596 layout_type (ret);
598 /* Now, fill in the type. */
599 char tmp_name[32];
600 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
601 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
602 ret);
603 TREE_STATIC (var) = 1;
604 TREE_PUBLIC (var) = 0;
605 DECL_ARTIFICIAL (var) = 1;
606 DECL_IGNORED_P (var) = 1;
607 DECL_EXTERNAL (var) = 0;
609 vec<constructor_elt, va_gc> *v;
610 vec_alloc (v, i);
611 tree ctor = build_constructor (ret, v);
613 /* If desirable, set the __ubsan_source_location element. */
614 for (j = 0; j < loccnt; j++)
616 location_t loc = LOCATION_LOCUS (ploc[j]);
617 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
620 size_t nelts = vec_safe_length (saved_args);
621 for (i = 0; i < nelts; i++)
623 t = (*saved_args)[i];
624 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
627 TREE_CONSTANT (ctor) = 1;
628 TREE_STATIC (ctor) = 1;
629 DECL_INITIAL (var) = ctor;
630 varpool_node::finalize_decl (var);
632 return var;
635 /* Instrument the __builtin_unreachable call. We just call the libubsan
636 routine instead. */
638 bool
639 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
641 gimple *g;
642 location_t loc = gimple_location (gsi_stmt (*gsi));
644 if (flag_sanitize_undefined_trap_on_error)
645 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
646 else
648 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
649 NULL_TREE, NULL_TREE);
650 data = build_fold_addr_expr_loc (loc, data);
651 tree fn
652 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
653 g = gimple_build_call (fn, 1, data);
655 gimple_set_location (g, loc);
656 gsi_replace (gsi, g, false);
657 return false;
660 /* Return true if T is a call to a libubsan routine. */
662 bool
663 is_ubsan_builtin_p (tree t)
665 return TREE_CODE (t) == FUNCTION_DECL
666 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
667 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
668 "__builtin___ubsan_", 18) == 0;
671 /* Create a callgraph edge for statement STMT. */
673 static void
674 ubsan_create_edge (gimple *stmt)
676 gcall *call_stmt = dyn_cast <gcall *> (stmt);
677 basic_block bb = gimple_bb (stmt);
678 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
679 cgraph_node *node = cgraph_node::get (current_function_decl);
680 tree decl = gimple_call_fndecl (call_stmt);
681 if (decl)
682 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
683 freq);
686 /* Expand the UBSAN_BOUNDS special builtin function. */
688 bool
689 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
691 gimple *stmt = gsi_stmt (*gsi);
692 location_t loc = gimple_location (stmt);
693 gcc_assert (gimple_call_num_args (stmt) == 3);
695 /* Pick up the arguments of the UBSAN_BOUNDS call. */
696 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
697 tree index = gimple_call_arg (stmt, 1);
698 tree orig_index = index;
699 tree bound = gimple_call_arg (stmt, 2);
701 gimple_stmt_iterator gsi_orig = *gsi;
703 /* Create condition "if (index > bound)". */
704 basic_block then_bb, fallthru_bb;
705 gimple_stmt_iterator cond_insert_point
706 = create_cond_insert_point (gsi, false, false, true,
707 &then_bb, &fallthru_bb);
708 index = fold_convert (TREE_TYPE (bound), index);
709 index = force_gimple_operand_gsi (&cond_insert_point, index,
710 true, NULL_TREE,
711 false, GSI_NEW_STMT);
712 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
713 gimple_set_location (g, loc);
714 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
716 /* Generate __ubsan_handle_out_of_bounds call. */
717 *gsi = gsi_after_labels (then_bb);
718 if (flag_sanitize_undefined_trap_on_error)
719 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
720 else
722 tree data
723 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
724 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
725 ubsan_type_descriptor (TREE_TYPE (orig_index)),
726 NULL_TREE, NULL_TREE);
727 data = build_fold_addr_expr_loc (loc, data);
728 enum built_in_function bcode
729 = (flag_sanitize_recover & SANITIZE_BOUNDS)
730 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
731 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
732 tree fn = builtin_decl_explicit (bcode);
733 tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE);
734 val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true,
735 GSI_SAME_STMT);
736 g = gimple_build_call (fn, 2, data, val);
738 gimple_set_location (g, loc);
739 gsi_insert_before (gsi, g, GSI_SAME_STMT);
741 /* Get rid of the UBSAN_BOUNDS call from the IR. */
742 unlink_stmt_vdef (stmt);
743 gsi_remove (&gsi_orig, true);
745 /* Point GSI to next logical statement. */
746 *gsi = gsi_start_bb (fallthru_bb);
747 return true;
750 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
751 argument which is a constant, because the middle-end treats pointer
752 conversions as useless and therefore the type of the first argument
753 could be changed to any other pointer type. */
755 bool
756 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
758 gimple_stmt_iterator gsi = *gsip;
759 gimple *stmt = gsi_stmt (gsi);
760 location_t loc = gimple_location (stmt);
761 gcc_assert (gimple_call_num_args (stmt) == 3);
762 tree ptr = gimple_call_arg (stmt, 0);
763 tree ckind = gimple_call_arg (stmt, 1);
764 tree align = gimple_call_arg (stmt, 2);
765 tree check_align = NULL_TREE;
766 bool check_null;
768 basic_block cur_bb = gsi_bb (gsi);
770 gimple *g;
771 if (!integer_zerop (align))
773 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
774 if (compare_tree_int (align, ptralign) == 1)
776 check_align = make_ssa_name (pointer_sized_int_node);
777 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
778 gimple_set_location (g, loc);
779 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
782 check_null = sanitize_flags_p (SANITIZE_NULL);
784 if (check_align == NULL_TREE && !check_null)
786 gsi_remove (gsip, true);
787 /* Unlink the UBSAN_NULLs vops before replacing it. */
788 unlink_stmt_vdef (stmt);
789 return true;
792 /* Split the original block holding the pointer dereference. */
793 edge e = split_block (cur_bb, stmt);
795 /* Get a hold on the 'condition block', the 'then block' and the
796 'else block'. */
797 basic_block cond_bb = e->src;
798 basic_block fallthru_bb = e->dest;
799 basic_block then_bb = create_empty_bb (cond_bb);
800 add_bb_to_loop (then_bb, cond_bb->loop_father);
801 loops_state_set (LOOPS_NEED_FIXUP);
803 /* Make an edge coming from the 'cond block' into the 'then block';
804 this edge is unlikely taken, so set up the probability accordingly. */
805 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
806 e->probability = profile_probability::very_unlikely ();
807 then_bb->count = e->count ();
809 /* Connect 'then block' with the 'else block'. This is needed
810 as the ubsan routines we call in the 'then block' are not noreturn.
811 The 'then block' only has one outcoming edge. */
812 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
814 /* Set up the fallthrough basic block. */
815 e = find_edge (cond_bb, fallthru_bb);
816 e->flags = EDGE_FALSE_VALUE;
817 e->probability = profile_probability::very_likely ();
819 /* Update dominance info for the newly created then_bb; note that
820 fallthru_bb's dominance info has already been updated by
821 split_block. */
822 if (dom_info_available_p (CDI_DOMINATORS))
823 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
825 /* Put the ubsan builtin call into the newly created BB. */
826 if (flag_sanitize_undefined_trap_on_error)
827 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
828 else
830 enum built_in_function bcode
831 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
832 | (check_null ? SANITIZE_NULL : 0)))
833 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1
834 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_ABORT;
835 tree fn = builtin_decl_implicit (bcode);
836 int align_log = tree_log2 (align);
837 tree data
838 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
839 ubsan_type_descriptor (TREE_TYPE (ckind),
840 UBSAN_PRINT_POINTER),
841 NULL_TREE,
842 build_int_cst (unsigned_char_type_node,
843 MAX (align_log, 0)),
844 fold_convert (unsigned_char_type_node, ckind),
845 NULL_TREE);
846 data = build_fold_addr_expr_loc (loc, data);
847 g = gimple_build_call (fn, 2, data,
848 check_align ? check_align
849 : build_zero_cst (pointer_sized_int_node));
851 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
852 gimple_set_location (g, loc);
853 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
855 /* Unlink the UBSAN_NULLs vops before replacing it. */
856 unlink_stmt_vdef (stmt);
858 if (check_null)
860 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
861 NULL_TREE, NULL_TREE);
862 gimple_set_location (g, loc);
864 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
865 gsi_replace (&gsi, g, false);
866 stmt = g;
869 if (check_align)
871 if (check_null)
873 /* Split the block with the condition again. */
874 e = split_block (cond_bb, stmt);
875 basic_block cond1_bb = e->src;
876 basic_block cond2_bb = e->dest;
878 /* Make an edge coming from the 'cond1 block' into the 'then block';
879 this edge is unlikely taken, so set up the probability
880 accordingly. */
881 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
882 e->probability = profile_probability::very_unlikely ();
884 /* Set up the fallthrough basic block. */
885 e = find_edge (cond1_bb, cond2_bb);
886 e->flags = EDGE_FALSE_VALUE;
887 e->probability = profile_probability::very_likely ();
889 /* Update dominance info. */
890 if (dom_info_available_p (CDI_DOMINATORS))
892 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
893 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
896 gsi2 = gsi_start_bb (cond2_bb);
899 tree mask = build_int_cst (pointer_sized_int_node,
900 tree_to_uhwi (align) - 1);
901 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
902 BIT_AND_EXPR, check_align, mask);
903 gimple_set_location (g, loc);
904 if (check_null)
905 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
906 else
907 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
909 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
910 build_int_cst (pointer_sized_int_node, 0),
911 NULL_TREE, NULL_TREE);
912 gimple_set_location (g, loc);
913 if (check_null)
914 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
915 else
916 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
917 gsi_replace (&gsi, g, false);
919 return false;
922 #define OBJSZ_MAX_OFFSET (1024 * 16)
924 /* Expand UBSAN_OBJECT_SIZE internal call. */
926 bool
927 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
929 gimple *stmt = gsi_stmt (*gsi);
930 location_t loc = gimple_location (stmt);
931 gcc_assert (gimple_call_num_args (stmt) == 4);
933 tree ptr = gimple_call_arg (stmt, 0);
934 tree offset = gimple_call_arg (stmt, 1);
935 tree size = gimple_call_arg (stmt, 2);
936 tree ckind = gimple_call_arg (stmt, 3);
937 gimple_stmt_iterator gsi_orig = *gsi;
938 gimple *g;
940 /* See if we can discard the check. */
941 if (TREE_CODE (size) != INTEGER_CST
942 || integer_all_onesp (size))
943 /* Yes, __builtin_object_size couldn't determine the
944 object size. */;
945 else if (TREE_CODE (offset) == INTEGER_CST
946 && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
947 && wi::to_widest (offset) <= -1)
948 /* The offset is in range [-16K, -1]. */;
949 else
951 /* if (offset > objsize) */
952 basic_block then_bb, fallthru_bb;
953 gimple_stmt_iterator cond_insert_point
954 = create_cond_insert_point (gsi, false, false, true,
955 &then_bb, &fallthru_bb);
956 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
957 gimple_set_location (g, loc);
958 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
960 /* If the offset is small enough, we don't need the second
961 run-time check. */
962 if (TREE_CODE (offset) == INTEGER_CST
963 && wi::to_widest (offset) >= 0
964 && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
965 *gsi = gsi_after_labels (then_bb);
966 else
968 /* Don't issue run-time error if (ptr > ptr + offset). That
969 may happen when computing a POINTER_PLUS_EXPR. */
970 basic_block then2_bb, fallthru2_bb;
972 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
973 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
974 true, &then2_bb,
975 &fallthru2_bb);
976 /* Convert the pointer to an integer type. */
977 tree p = make_ssa_name (pointer_sized_int_node);
978 g = gimple_build_assign (p, NOP_EXPR, ptr);
979 gimple_set_location (g, loc);
980 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
981 p = gimple_assign_lhs (g);
982 /* Compute ptr + offset. */
983 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
984 PLUS_EXPR, p, offset);
985 gimple_set_location (g, loc);
986 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
987 /* Now build the conditional and put it into the IR. */
988 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
989 NULL_TREE, NULL_TREE);
990 gimple_set_location (g, loc);
991 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
992 *gsi = gsi_after_labels (then2_bb);
995 /* Generate __ubsan_handle_type_mismatch call. */
996 if (flag_sanitize_undefined_trap_on_error)
997 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
998 else
1000 tree data
1001 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
1002 ubsan_type_descriptor (TREE_TYPE (ptr),
1003 UBSAN_PRINT_POINTER),
1004 NULL_TREE,
1005 build_zero_cst (unsigned_char_type_node),
1006 ckind,
1007 NULL_TREE);
1008 data = build_fold_addr_expr_loc (loc, data);
1009 enum built_in_function bcode
1010 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1011 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1
1012 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_ABORT;
1013 tree p = make_ssa_name (pointer_sized_int_node);
1014 g = gimple_build_assign (p, NOP_EXPR, ptr);
1015 gimple_set_location (g, loc);
1016 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1017 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1019 gimple_set_location (g, loc);
1020 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1022 /* Point GSI to next logical statement. */
1023 *gsi = gsi_start_bb (fallthru_bb);
1025 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1026 unlink_stmt_vdef (stmt);
1027 gsi_remove (&gsi_orig, true);
1028 return true;
1031 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1032 unlink_stmt_vdef (stmt);
1033 gsi_remove (gsi, true);
1034 return true;
1037 /* Expand UBSAN_PTR internal call. */
1039 bool
1040 ubsan_expand_ptr_ifn (gimple_stmt_iterator *gsip)
1042 gimple_stmt_iterator gsi = *gsip;
1043 gimple *stmt = gsi_stmt (gsi);
1044 location_t loc = gimple_location (stmt);
1045 gcc_assert (gimple_call_num_args (stmt) == 2);
1046 tree ptr = gimple_call_arg (stmt, 0);
1047 tree off = gimple_call_arg (stmt, 1);
1049 if (integer_zerop (off))
1051 gsi_remove (gsip, true);
1052 unlink_stmt_vdef (stmt);
1053 return true;
1056 basic_block cur_bb = gsi_bb (gsi);
1057 tree ptrplusoff = make_ssa_name (pointer_sized_int_node);
1058 tree ptri = make_ssa_name (pointer_sized_int_node);
1059 int pos_neg = get_range_pos_neg (off);
1061 /* Split the original block holding the pointer dereference. */
1062 edge e = split_block (cur_bb, stmt);
1064 /* Get a hold on the 'condition block', the 'then block' and the
1065 'else block'. */
1066 basic_block cond_bb = e->src;
1067 basic_block fallthru_bb = e->dest;
1068 basic_block then_bb = create_empty_bb (cond_bb);
1069 basic_block cond_pos_bb = NULL, cond_neg_bb = NULL;
1070 add_bb_to_loop (then_bb, cond_bb->loop_father);
1071 loops_state_set (LOOPS_NEED_FIXUP);
1073 /* Set up the fallthrough basic block. */
1074 e->flags = EDGE_FALSE_VALUE;
1075 if (pos_neg != 3)
1077 e->probability = profile_probability::very_likely ();
1079 /* Connect 'then block' with the 'else block'. This is needed
1080 as the ubsan routines we call in the 'then block' are not noreturn.
1081 The 'then block' only has one outcoming edge. */
1082 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
1084 /* Make an edge coming from the 'cond block' into the 'then block';
1085 this edge is unlikely taken, so set up the probability
1086 accordingly. */
1087 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
1088 e->probability = profile_probability::very_unlikely ();
1089 then_bb->count = e->count ();
1091 else
1093 e->probability = profile_probability::even ();
1095 e = split_block (fallthru_bb, (gimple *) NULL);
1096 cond_neg_bb = e->src;
1097 fallthru_bb = e->dest;
1098 e->probability = profile_probability::very_likely ();
1099 e->flags = EDGE_FALSE_VALUE;
1101 e = make_edge (cond_neg_bb, then_bb, EDGE_TRUE_VALUE);
1102 e->probability = profile_probability::very_unlikely ();
1103 then_bb->count = e->count ();
1105 cond_pos_bb = create_empty_bb (cond_bb);
1106 add_bb_to_loop (cond_pos_bb, cond_bb->loop_father);
1108 e = make_edge (cond_bb, cond_pos_bb, EDGE_TRUE_VALUE);
1109 e->probability = profile_probability::even ();
1110 cond_pos_bb->count = e->count ();
1112 e = make_edge (cond_pos_bb, then_bb, EDGE_TRUE_VALUE);
1113 e->probability = profile_probability::very_unlikely ();
1115 e = make_edge (cond_pos_bb, fallthru_bb, EDGE_FALSE_VALUE);
1116 e->probability = profile_probability::very_likely ();
1118 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
1121 gimple *g = gimple_build_assign (ptri, NOP_EXPR, ptr);
1122 gimple_set_location (g, loc);
1123 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1124 g = gimple_build_assign (ptrplusoff, PLUS_EXPR, ptri, off);
1125 gimple_set_location (g, loc);
1126 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1128 /* Update dominance info for the newly created then_bb; note that
1129 fallthru_bb's dominance info has already been updated by
1130 split_block. */
1131 if (dom_info_available_p (CDI_DOMINATORS))
1133 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
1134 if (pos_neg == 3)
1136 set_immediate_dominator (CDI_DOMINATORS, cond_pos_bb, cond_bb);
1137 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond_bb);
1141 /* Put the ubsan builtin call into the newly created BB. */
1142 if (flag_sanitize_undefined_trap_on_error)
1143 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
1144 else
1146 enum built_in_function bcode
1147 = (flag_sanitize_recover & SANITIZE_POINTER_OVERFLOW)
1148 ? BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW
1149 : BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW_ABORT;
1150 tree fn = builtin_decl_implicit (bcode);
1151 tree data
1152 = ubsan_create_data ("__ubsan_ptrovf_data", 1, &loc,
1153 NULL_TREE, NULL_TREE);
1154 data = build_fold_addr_expr_loc (loc, data);
1155 g = gimple_build_call (fn, 3, data, ptr, ptrplusoff);
1157 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
1158 gimple_set_location (g, loc);
1159 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1161 /* Unlink the UBSAN_PTRs vops before replacing it. */
1162 unlink_stmt_vdef (stmt);
1164 if (TREE_CODE (off) == INTEGER_CST)
1165 g = gimple_build_cond (wi::neg_p (wi::to_wide (off)) ? LT_EXPR : GE_EXPR,
1166 ptri, fold_build1 (NEGATE_EXPR, sizetype, off),
1167 NULL_TREE, NULL_TREE);
1168 else if (pos_neg != 3)
1169 g = gimple_build_cond (pos_neg == 1 ? LT_EXPR : GT_EXPR,
1170 ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1171 else
1173 gsi2 = gsi_start_bb (cond_pos_bb);
1174 g = gimple_build_cond (LT_EXPR, ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1175 gimple_set_location (g, loc);
1176 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1178 gsi2 = gsi_start_bb (cond_neg_bb);
1179 g = gimple_build_cond (GT_EXPR, ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1180 gimple_set_location (g, loc);
1181 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1183 gimple_seq seq = NULL;
1184 tree t = gimple_build (&seq, loc, NOP_EXPR, ssizetype, off);
1185 t = gimple_build (&seq, loc, GE_EXPR, boolean_type_node,
1186 t, ssize_int (0));
1187 gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
1188 g = gimple_build_cond (NE_EXPR, t, boolean_false_node,
1189 NULL_TREE, NULL_TREE);
1191 gimple_set_location (g, loc);
1192 /* Replace the UBSAN_PTR with a GIMPLE_COND stmt. */
1193 gsi_replace (&gsi, g, false);
1194 return false;
1198 /* Cached __ubsan_vptr_type_cache decl. */
1199 static GTY(()) tree ubsan_vptr_type_cache_decl;
1201 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1202 argument which is a constant, because the middle-end treats pointer
1203 conversions as useless and therefore the type of the first argument
1204 could be changed to any other pointer type. */
1206 bool
1207 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1209 gimple_stmt_iterator gsi = *gsip;
1210 gimple *stmt = gsi_stmt (gsi);
1211 location_t loc = gimple_location (stmt);
1212 gcc_assert (gimple_call_num_args (stmt) == 5);
1213 tree op = gimple_call_arg (stmt, 0);
1214 tree vptr = gimple_call_arg (stmt, 1);
1215 tree str_hash = gimple_call_arg (stmt, 2);
1216 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1217 tree ckind_tree = gimple_call_arg (stmt, 4);
1218 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1219 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1220 gimple *g;
1221 basic_block fallthru_bb = NULL;
1223 if (ckind == UBSAN_DOWNCAST_POINTER)
1225 /* Guard everything with if (op != NULL) { ... }. */
1226 basic_block then_bb;
1227 gimple_stmt_iterator cond_insert_point
1228 = create_cond_insert_point (gsip, false, false, true,
1229 &then_bb, &fallthru_bb);
1230 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1231 NULL_TREE, NULL_TREE);
1232 gimple_set_location (g, loc);
1233 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1234 *gsip = gsi_after_labels (then_bb);
1235 gsi_remove (&gsi, false);
1236 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1237 gsi = *gsip;
1240 tree htype = TREE_TYPE (str_hash);
1241 tree cst = wide_int_to_tree (htype,
1242 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1243 | 0xeb382d69, 64));
1244 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1245 vptr, str_hash);
1246 gimple_set_location (g, loc);
1247 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1248 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1249 gimple_assign_lhs (g), cst);
1250 gimple_set_location (g, loc);
1251 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1252 tree t1 = gimple_assign_lhs (g);
1253 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1254 t1, build_int_cst (integer_type_node, 47));
1255 gimple_set_location (g, loc);
1256 tree t2 = gimple_assign_lhs (g);
1257 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1258 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1259 vptr, t1);
1260 gimple_set_location (g, loc);
1261 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1262 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1263 t2, gimple_assign_lhs (g));
1264 gimple_set_location (g, loc);
1265 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1266 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1267 gimple_assign_lhs (g), cst);
1268 gimple_set_location (g, loc);
1269 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1270 tree t3 = gimple_assign_lhs (g);
1271 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1272 t3, build_int_cst (integer_type_node, 47));
1273 gimple_set_location (g, loc);
1274 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1275 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1276 t3, gimple_assign_lhs (g));
1277 gimple_set_location (g, loc);
1278 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1279 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1280 gimple_assign_lhs (g), cst);
1281 gimple_set_location (g, loc);
1282 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1283 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1285 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1286 NOP_EXPR, gimple_assign_lhs (g));
1287 gimple_set_location (g, loc);
1288 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1290 tree hash = gimple_assign_lhs (g);
1292 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1294 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1295 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1296 get_identifier ("__ubsan_vptr_type_cache"),
1297 atype);
1298 DECL_ARTIFICIAL (array) = 1;
1299 DECL_IGNORED_P (array) = 1;
1300 TREE_PUBLIC (array) = 1;
1301 TREE_STATIC (array) = 1;
1302 DECL_EXTERNAL (array) = 1;
1303 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1304 DECL_VISIBILITY_SPECIFIED (array) = 1;
1305 varpool_node::finalize_decl (array);
1306 ubsan_vptr_type_cache_decl = array;
1309 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1310 BIT_AND_EXPR, hash,
1311 build_int_cst (pointer_sized_int_node, 127));
1312 gimple_set_location (g, loc);
1313 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1315 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1316 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1317 NULL_TREE, NULL_TREE);
1318 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1319 ARRAY_REF, c);
1320 gimple_set_location (g, loc);
1321 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1323 basic_block then_bb, fallthru2_bb;
1324 gimple_stmt_iterator cond_insert_point
1325 = create_cond_insert_point (gsip, false, false, true,
1326 &then_bb, &fallthru2_bb);
1327 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1328 NULL_TREE, NULL_TREE);
1329 gimple_set_location (g, loc);
1330 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1331 *gsip = gsi_after_labels (then_bb);
1332 if (fallthru_bb == NULL)
1333 fallthru_bb = fallthru2_bb;
1335 tree data
1336 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1337 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1338 build_int_cst (unsigned_char_type_node, ckind),
1339 NULL_TREE);
1340 data = build_fold_addr_expr_loc (loc, data);
1341 enum built_in_function bcode
1342 = (flag_sanitize_recover & SANITIZE_VPTR)
1343 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1344 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1346 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1347 gimple_set_location (g, loc);
1348 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1350 /* Point GSI to next logical statement. */
1351 *gsip = gsi_start_bb (fallthru_bb);
1353 /* Get rid of the UBSAN_VPTR call from the IR. */
1354 unlink_stmt_vdef (stmt);
1355 gsi_remove (&gsi, true);
1356 return true;
1359 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1360 whether the pointer is on the left hand side of the assignment. */
1362 static void
1363 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1364 bool is_lhs)
1366 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1367 unsigned int align = 0;
1368 if (sanitize_flags_p (SANITIZE_ALIGNMENT))
1370 align = min_align_of_type (TREE_TYPE (base));
1371 if (align <= 1)
1372 align = 0;
1374 if (align == 0 && !sanitize_flags_p (SANITIZE_NULL))
1375 return;
1376 tree t = TREE_OPERAND (base, 0);
1377 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1378 return;
1379 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1380 ikind = UBSAN_MEMBER_ACCESS;
1381 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1382 tree alignt = build_int_cst (pointer_sized_int_node, align);
1383 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1384 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1385 gsi_insert_before (iter, g, GSI_SAME_STMT);
1388 /* Perform the pointer instrumentation. */
1390 static void
1391 instrument_null (gimple_stmt_iterator gsi, tree t, bool is_lhs)
1393 /* Handle also e.g. &s->i. */
1394 if (TREE_CODE (t) == ADDR_EXPR)
1395 t = TREE_OPERAND (t, 0);
1396 tree base = get_base_address (t);
1397 if (base != NULL_TREE
1398 && TREE_CODE (base) == MEM_REF
1399 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1400 instrument_mem_ref (t, base, &gsi, is_lhs);
1403 /* Instrument pointer arithmetics PTR p+ OFF. */
1405 static void
1406 instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree ptr, tree off)
1408 if (TYPE_PRECISION (sizetype) != POINTER_SIZE)
1409 return;
1410 gcall *g = gimple_build_call_internal (IFN_UBSAN_PTR, 2, ptr, off);
1411 gimple_set_location (g, gimple_location (gsi_stmt (*gsi)));
1412 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1415 /* Instrument pointer arithmetics if any. */
1417 static void
1418 maybe_instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree t)
1420 if (TYPE_PRECISION (sizetype) != POINTER_SIZE)
1421 return;
1423 /* Handle also e.g. &s->i. */
1424 if (TREE_CODE (t) == ADDR_EXPR)
1425 t = TREE_OPERAND (t, 0);
1427 if (!handled_component_p (t) && TREE_CODE (t) != MEM_REF)
1428 return;
1430 HOST_WIDE_INT bitsize, bitpos, bytepos;
1431 tree offset;
1432 machine_mode mode;
1433 int volatilep = 0, reversep, unsignedp = 0;
1434 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1435 &unsignedp, &reversep, &volatilep);
1436 tree moff = NULL_TREE;
1438 bool decl_p = DECL_P (inner);
1439 tree base;
1440 if (decl_p)
1442 if (DECL_REGISTER (inner))
1443 return;
1444 base = inner;
1445 /* If BASE is a fixed size automatic variable or
1446 global variable defined in the current TU and bitpos
1447 fits, don't instrument anything. */
1448 if (offset == NULL_TREE
1449 && bitpos > 0
1450 && (VAR_P (base)
1451 || TREE_CODE (base) == PARM_DECL
1452 || TREE_CODE (base) == RESULT_DECL)
1453 && DECL_SIZE (base)
1454 && TREE_CODE (DECL_SIZE (base)) == INTEGER_CST
1455 && compare_tree_int (DECL_SIZE (base), bitpos) >= 0
1456 && (!is_global_var (base) || decl_binds_to_current_def_p (base)))
1457 return;
1459 else if (TREE_CODE (inner) == MEM_REF)
1461 base = TREE_OPERAND (inner, 0);
1462 if (TREE_CODE (base) == ADDR_EXPR
1463 && DECL_P (TREE_OPERAND (base, 0))
1464 && !TREE_ADDRESSABLE (TREE_OPERAND (base, 0))
1465 && !is_global_var (TREE_OPERAND (base, 0)))
1466 return;
1467 moff = TREE_OPERAND (inner, 1);
1468 if (integer_zerop (moff))
1469 moff = NULL_TREE;
1471 else
1472 return;
1474 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1475 return;
1476 bytepos = bitpos / BITS_PER_UNIT;
1477 if (offset == NULL_TREE && bytepos == 0 && moff == NULL_TREE)
1478 return;
1480 tree base_addr = base;
1481 if (decl_p)
1482 base_addr = build1 (ADDR_EXPR,
1483 build_pointer_type (TREE_TYPE (base)), base);
1484 t = offset;
1485 if (bytepos)
1487 if (t)
1488 t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t,
1489 build_int_cst (TREE_TYPE (t), bytepos));
1490 else
1491 t = size_int (bytepos);
1493 if (moff)
1495 if (t)
1496 t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t,
1497 fold_convert (TREE_TYPE (t), moff));
1498 else
1499 t = fold_convert (sizetype, moff);
1501 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1502 GSI_SAME_STMT);
1503 base_addr = force_gimple_operand_gsi (gsi, base_addr, true, NULL_TREE, true,
1504 GSI_SAME_STMT);
1505 instrument_pointer_overflow (gsi, base_addr, t);
1508 /* Build an ubsan builtin call for the signed-integer-overflow
1509 sanitization. CODE says what kind of builtin are we building,
1510 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1511 are operands of the binary operation. */
1513 tree
1514 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1515 tree op0, tree op1, tree *datap)
1517 if (flag_sanitize_undefined_trap_on_error)
1518 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1520 tree data;
1521 if (datap && *datap)
1522 data = *datap;
1523 else
1524 data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1525 ubsan_type_descriptor (lhstype), NULL_TREE,
1526 NULL_TREE);
1527 if (datap)
1528 *datap = data;
1529 enum built_in_function fn_code;
1531 switch (code)
1533 case PLUS_EXPR:
1534 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1535 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1536 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1537 break;
1538 case MINUS_EXPR:
1539 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1540 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1541 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1542 break;
1543 case MULT_EXPR:
1544 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1545 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1546 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1547 break;
1548 case NEGATE_EXPR:
1549 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1550 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1551 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1552 break;
1553 default:
1554 gcc_unreachable ();
1556 tree fn = builtin_decl_explicit (fn_code);
1557 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1558 build_fold_addr_expr_loc (loc, data),
1559 ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL),
1561 ? ubsan_encode_value (op1,
1562 UBSAN_ENCODE_VALUE_RTL)
1563 : NULL_TREE);
1566 /* Perform the signed integer instrumentation. GSI is the iterator
1567 pointing at statement we are trying to instrument. */
1569 static void
1570 instrument_si_overflow (gimple_stmt_iterator gsi)
1572 gimple *stmt = gsi_stmt (gsi);
1573 tree_code code = gimple_assign_rhs_code (stmt);
1574 tree lhs = gimple_assign_lhs (stmt);
1575 tree lhstype = TREE_TYPE (lhs);
1576 tree lhsinner = VECTOR_TYPE_P (lhstype) ? TREE_TYPE (lhstype) : lhstype;
1577 tree a, b;
1578 gimple *g;
1580 /* If this is not a signed operation, don't instrument anything here.
1581 Also punt on bit-fields. */
1582 if (!INTEGRAL_TYPE_P (lhsinner)
1583 || TYPE_OVERFLOW_WRAPS (lhsinner)
1584 || GET_MODE_BITSIZE (TYPE_MODE (lhsinner)) != TYPE_PRECISION (lhsinner))
1585 return;
1587 switch (code)
1589 case MINUS_EXPR:
1590 case PLUS_EXPR:
1591 case MULT_EXPR:
1592 /* Transform
1593 i = u {+,-,*} 5;
1594 into
1595 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1596 a = gimple_assign_rhs1 (stmt);
1597 b = gimple_assign_rhs2 (stmt);
1598 g = gimple_build_call_internal (code == PLUS_EXPR
1599 ? IFN_UBSAN_CHECK_ADD
1600 : code == MINUS_EXPR
1601 ? IFN_UBSAN_CHECK_SUB
1602 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1603 gimple_call_set_lhs (g, lhs);
1604 gsi_replace (&gsi, g, true);
1605 break;
1606 case NEGATE_EXPR:
1607 /* Represent i = -u;
1609 i = UBSAN_CHECK_SUB (0, u); */
1610 a = build_zero_cst (lhstype);
1611 b = gimple_assign_rhs1 (stmt);
1612 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1613 gimple_call_set_lhs (g, lhs);
1614 gsi_replace (&gsi, g, true);
1615 break;
1616 case ABS_EXPR:
1617 /* Transform i = ABS_EXPR<u>;
1618 into
1619 _N = UBSAN_CHECK_SUB (0, u);
1620 i = ABS_EXPR<_N>; */
1621 a = build_zero_cst (lhstype);
1622 b = gimple_assign_rhs1 (stmt);
1623 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1624 a = make_ssa_name (lhstype);
1625 gimple_call_set_lhs (g, a);
1626 gimple_set_location (g, gimple_location (stmt));
1627 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1628 gimple_assign_set_rhs1 (stmt, a);
1629 update_stmt (stmt);
1630 break;
1631 default:
1632 break;
1636 /* Instrument loads from (non-bitfield) bool and C++ enum values
1637 to check if the memory value is outside of the range of the valid
1638 type values. */
1640 static void
1641 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1643 gimple *stmt = gsi_stmt (*gsi);
1644 tree rhs = gimple_assign_rhs1 (stmt);
1645 tree type = TREE_TYPE (rhs);
1646 tree minv = NULL_TREE, maxv = NULL_TREE;
1648 if (TREE_CODE (type) == BOOLEAN_TYPE
1649 && sanitize_flags_p (SANITIZE_BOOL))
1651 minv = boolean_false_node;
1652 maxv = boolean_true_node;
1654 else if (TREE_CODE (type) == ENUMERAL_TYPE
1655 && sanitize_flags_p (SANITIZE_ENUM)
1656 && TREE_TYPE (type) != NULL_TREE
1657 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1658 && (TYPE_PRECISION (TREE_TYPE (type))
1659 < GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (type))))
1661 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1662 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1664 else
1665 return;
1667 int modebitsize = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type));
1668 HOST_WIDE_INT bitsize, bitpos;
1669 tree offset;
1670 machine_mode mode;
1671 int volatilep = 0, reversep, unsignedp = 0;
1672 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1673 &unsignedp, &reversep, &volatilep);
1674 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1676 if ((VAR_P (base) && DECL_HARD_REGISTER (base))
1677 || (bitpos % modebitsize) != 0
1678 || bitsize != modebitsize
1679 || GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (utype)) != modebitsize
1680 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1681 return;
1683 bool ends_bb = stmt_ends_bb_p (stmt);
1684 location_t loc = gimple_location (stmt);
1685 tree lhs = gimple_assign_lhs (stmt);
1686 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1687 tree atype = reference_alias_ptr_type (rhs);
1688 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1689 build_fold_addr_expr (rhs));
1690 gimple_set_location (g, loc);
1691 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1692 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1693 build_int_cst (atype, 0));
1694 tree urhs = make_ssa_name (utype);
1695 if (ends_bb)
1697 gimple_assign_set_lhs (stmt, urhs);
1698 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1699 gimple_set_location (g, loc);
1700 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1701 gsi_insert_on_edge_immediate (e, g);
1702 gimple_assign_set_rhs_from_tree (gsi, mem);
1703 update_stmt (stmt);
1704 *gsi = gsi_for_stmt (g);
1705 g = stmt;
1707 else
1709 g = gimple_build_assign (urhs, mem);
1710 gimple_set_location (g, loc);
1711 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1713 minv = fold_convert (utype, minv);
1714 maxv = fold_convert (utype, maxv);
1715 if (!integer_zerop (minv))
1717 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1718 gimple_set_location (g, loc);
1719 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1722 gimple_stmt_iterator gsi2 = *gsi;
1723 basic_block then_bb, fallthru_bb;
1724 *gsi = create_cond_insert_point (gsi, true, false, true,
1725 &then_bb, &fallthru_bb);
1726 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1727 int_const_binop (MINUS_EXPR, maxv, minv),
1728 NULL_TREE, NULL_TREE);
1729 gimple_set_location (g, loc);
1730 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1732 if (!ends_bb)
1734 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1735 update_stmt (stmt);
1738 gsi2 = gsi_after_labels (then_bb);
1739 if (flag_sanitize_undefined_trap_on_error)
1740 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1741 else
1743 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1744 ubsan_type_descriptor (type), NULL_TREE,
1745 NULL_TREE);
1746 data = build_fold_addr_expr_loc (loc, data);
1747 enum built_in_function bcode
1748 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1749 ? SANITIZE_BOOL : SANITIZE_ENUM))
1750 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1751 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1752 tree fn = builtin_decl_explicit (bcode);
1754 tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE);
1755 val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true,
1756 GSI_SAME_STMT);
1757 g = gimple_build_call (fn, 2, data, val);
1759 gimple_set_location (g, loc);
1760 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1761 ubsan_create_edge (g);
1762 *gsi = gsi_for_stmt (stmt);
1765 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1766 new style handlers. Libubsan uses heuristics to destinguish between old and
1767 new styles and relies on these properties for filename:
1769 a) Location's filename must not be NULL.
1770 b) Location's filename must not be equal to "".
1771 c) Location's filename must not be equal to "\1".
1772 d) First two bytes of filename must not contain '\xff' symbol. */
1774 static bool
1775 ubsan_use_new_style_p (location_t loc)
1777 if (loc == UNKNOWN_LOCATION)
1778 return false;
1780 expanded_location xloc = expand_location (loc);
1781 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1782 || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1783 || xloc.file[1] == '\xff')
1784 return false;
1786 return true;
1789 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1790 destination, EXPR is floating-point expression. */
1792 tree
1793 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1795 tree expr_type = TREE_TYPE (expr);
1796 tree t, tt, fn, min, max;
1797 machine_mode mode = TYPE_MODE (expr_type);
1798 int prec = TYPE_PRECISION (type);
1799 bool uns_p = TYPE_UNSIGNED (type);
1800 if (loc == UNKNOWN_LOCATION)
1801 loc = input_location;
1803 /* Float to integer conversion first truncates toward zero, so
1804 even signed char c = 127.875f; is not problematic.
1805 Therefore, we should complain only if EXPR is unordered or smaller
1806 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1807 TYPE_MAX_VALUE + 1.0. */
1808 if (REAL_MODE_FORMAT (mode)->b == 2)
1810 /* For maximum, TYPE_MAX_VALUE might not be representable
1811 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1812 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1813 either representable or infinity. */
1814 REAL_VALUE_TYPE maxval = dconst1;
1815 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1816 real_convert (&maxval, mode, &maxval);
1817 max = build_real (expr_type, maxval);
1819 /* For unsigned, assume -1.0 is always representable. */
1820 if (uns_p)
1821 min = build_minus_one_cst (expr_type);
1822 else
1824 /* TYPE_MIN_VALUE is generally representable (or -inf),
1825 but TYPE_MIN_VALUE - 1.0 might not be. */
1826 REAL_VALUE_TYPE minval = dconstm1, minval2;
1827 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1828 real_convert (&minval, mode, &minval);
1829 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1830 real_convert (&minval2, mode, &minval2);
1831 if (real_compare (EQ_EXPR, &minval, &minval2)
1832 && !real_isinf (&minval))
1834 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1835 rounds to TYPE_MIN_VALUE, we need to subtract
1836 more. As REAL_MODE_FORMAT (mode)->p is the number
1837 of base digits, we want to subtract a number that
1838 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1839 times smaller than minval. */
1840 minval2 = dconst1;
1841 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1842 SET_REAL_EXP (&minval2,
1843 REAL_EXP (&minval2) + prec - 1
1844 - REAL_MODE_FORMAT (mode)->p + 1);
1845 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1846 real_convert (&minval2, mode, &minval2);
1848 min = build_real (expr_type, minval2);
1851 else if (REAL_MODE_FORMAT (mode)->b == 10)
1853 /* For _Decimal128 up to 34 decimal digits, - sign,
1854 dot, e, exponent. */
1855 char buf[64];
1856 mpfr_t m;
1857 int p = REAL_MODE_FORMAT (mode)->p;
1858 REAL_VALUE_TYPE maxval, minval;
1860 /* Use mpfr_snprintf rounding to compute the smallest
1861 representable decimal number greater or equal than
1862 1 << (prec - !uns_p). */
1863 mpfr_init2 (m, prec + 2);
1864 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1865 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1866 decimal_real_from_string (&maxval, buf);
1867 max = build_real (expr_type, maxval);
1869 /* For unsigned, assume -1.0 is always representable. */
1870 if (uns_p)
1871 min = build_minus_one_cst (expr_type);
1872 else
1874 /* Use mpfr_snprintf rounding to compute the largest
1875 representable decimal number less or equal than
1876 (-1 << (prec - 1)) - 1. */
1877 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1878 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1879 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1880 decimal_real_from_string (&minval, buf);
1881 min = build_real (expr_type, minval);
1883 mpfr_clear (m);
1885 else
1886 return NULL_TREE;
1888 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1889 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1890 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1891 if (integer_zerop (t))
1892 return NULL_TREE;
1894 if (flag_sanitize_undefined_trap_on_error)
1895 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1896 else
1898 location_t *loc_ptr = NULL;
1899 unsigned num_locations = 0;
1900 /* Figure out if we can propagate location to ubsan_data and use new
1901 style handlers in libubsan. */
1902 if (ubsan_use_new_style_p (loc))
1904 loc_ptr = &loc;
1905 num_locations = 1;
1907 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1908 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1909 num_locations, loc_ptr,
1910 ubsan_type_descriptor (expr_type),
1911 ubsan_type_descriptor (type), NULL_TREE,
1912 NULL_TREE);
1913 enum built_in_function bcode
1914 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1915 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1916 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1917 fn = builtin_decl_explicit (bcode);
1918 fn = build_call_expr_loc (loc, fn, 2,
1919 build_fold_addr_expr_loc (loc, data),
1920 ubsan_encode_value (expr));
1923 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1926 /* Instrument values passed to function arguments with nonnull attribute. */
1928 static void
1929 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1931 gimple *stmt = gsi_stmt (*gsi);
1932 location_t loc[2];
1933 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1934 while for nonnull sanitization it is clear. */
1935 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1936 flag_delete_null_pointer_checks = 1;
1937 loc[0] = gimple_location (stmt);
1938 loc[1] = UNKNOWN_LOCATION;
1939 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1941 tree arg = gimple_call_arg (stmt, i);
1942 if (POINTER_TYPE_P (TREE_TYPE (arg))
1943 && infer_nonnull_range_by_attribute (stmt, arg))
1945 gimple *g;
1946 if (!is_gimple_val (arg))
1948 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1949 gimple_set_location (g, loc[0]);
1950 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1951 arg = gimple_assign_lhs (g);
1954 basic_block then_bb, fallthru_bb;
1955 *gsi = create_cond_insert_point (gsi, true, false, true,
1956 &then_bb, &fallthru_bb);
1957 g = gimple_build_cond (EQ_EXPR, arg,
1958 build_zero_cst (TREE_TYPE (arg)),
1959 NULL_TREE, NULL_TREE);
1960 gimple_set_location (g, loc[0]);
1961 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1963 *gsi = gsi_after_labels (then_bb);
1964 if (flag_sanitize_undefined_trap_on_error)
1965 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1966 else
1968 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1969 2, loc, NULL_TREE,
1970 build_int_cst (integer_type_node,
1971 i + 1),
1972 NULL_TREE);
1973 data = build_fold_addr_expr_loc (loc[0], data);
1974 enum built_in_function bcode
1975 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1976 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1977 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1978 tree fn = builtin_decl_explicit (bcode);
1980 g = gimple_build_call (fn, 1, data);
1982 gimple_set_location (g, loc[0]);
1983 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1984 ubsan_create_edge (g);
1986 *gsi = gsi_for_stmt (stmt);
1988 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1991 /* Instrument returns in functions with returns_nonnull attribute. */
1993 static void
1994 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1996 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1997 location_t loc[2];
1998 tree arg = gimple_return_retval (stmt);
1999 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
2000 while for nonnull return sanitization it is clear. */
2001 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
2002 flag_delete_null_pointer_checks = 1;
2003 loc[0] = gimple_location (stmt);
2004 loc[1] = UNKNOWN_LOCATION;
2005 if (arg
2006 && POINTER_TYPE_P (TREE_TYPE (arg))
2007 && is_gimple_val (arg)
2008 && infer_nonnull_range_by_attribute (stmt, arg))
2010 basic_block then_bb, fallthru_bb;
2011 *gsi = create_cond_insert_point (gsi, true, false, true,
2012 &then_bb, &fallthru_bb);
2013 gimple *g = gimple_build_cond (EQ_EXPR, arg,
2014 build_zero_cst (TREE_TYPE (arg)),
2015 NULL_TREE, NULL_TREE);
2016 gimple_set_location (g, loc[0]);
2017 gsi_insert_after (gsi, g, GSI_NEW_STMT);
2019 *gsi = gsi_after_labels (then_bb);
2020 if (flag_sanitize_undefined_trap_on_error)
2021 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2022 else
2024 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
2025 1, &loc[1], NULL_TREE, NULL_TREE);
2026 data = build_fold_addr_expr_loc (loc[0], data);
2027 tree data2 = ubsan_create_data ("__ubsan_nonnull_return_data",
2028 1, &loc[0], NULL_TREE, NULL_TREE);
2029 data2 = build_fold_addr_expr_loc (loc[0], data2);
2030 enum built_in_function bcode
2031 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2032 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1
2033 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1_ABORT;
2034 tree fn = builtin_decl_explicit (bcode);
2036 g = gimple_build_call (fn, 2, data, data2);
2038 gimple_set_location (g, loc[0]);
2039 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2040 ubsan_create_edge (g);
2041 *gsi = gsi_for_stmt (stmt);
2043 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
2046 /* Instrument memory references. Here we check whether the pointer
2047 points to an out-of-bounds location. */
2049 static void
2050 instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
2052 gimple *stmt = gsi_stmt (*gsi);
2053 location_t loc = gimple_location (stmt);
2054 tree type;
2055 tree index = NULL_TREE;
2056 HOST_WIDE_INT size_in_bytes;
2058 type = TREE_TYPE (t);
2059 if (VOID_TYPE_P (type))
2060 return;
2062 switch (TREE_CODE (t))
2064 case COMPONENT_REF:
2065 if (TREE_CODE (t) == COMPONENT_REF
2066 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
2068 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
2069 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
2070 repr, TREE_OPERAND (t, 2));
2072 break;
2073 case ARRAY_REF:
2074 index = TREE_OPERAND (t, 1);
2075 break;
2076 case INDIRECT_REF:
2077 case MEM_REF:
2078 case VAR_DECL:
2079 case PARM_DECL:
2080 case RESULT_DECL:
2081 break;
2082 default:
2083 return;
2086 size_in_bytes = int_size_in_bytes (type);
2087 if (size_in_bytes <= 0)
2088 return;
2090 HOST_WIDE_INT bitsize, bitpos;
2091 tree offset;
2092 machine_mode mode;
2093 int volatilep = 0, reversep, unsignedp = 0;
2094 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
2095 &unsignedp, &reversep, &volatilep);
2097 if (bitpos % BITS_PER_UNIT != 0
2098 || bitsize != size_in_bytes * BITS_PER_UNIT)
2099 return;
2101 bool decl_p = DECL_P (inner);
2102 tree base;
2103 if (decl_p)
2105 if (DECL_REGISTER (inner))
2106 return;
2107 base = inner;
2109 else if (TREE_CODE (inner) == MEM_REF)
2110 base = TREE_OPERAND (inner, 0);
2111 else
2112 return;
2113 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
2115 while (TREE_CODE (base) == SSA_NAME)
2117 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
2118 if (gimple_assign_ssa_name_copy_p (def_stmt)
2119 || (gimple_assign_cast_p (def_stmt)
2120 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
2121 || (is_gimple_assign (def_stmt)
2122 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
2124 tree rhs1 = gimple_assign_rhs1 (def_stmt);
2125 if (TREE_CODE (rhs1) == SSA_NAME
2126 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
2127 break;
2128 else
2129 base = rhs1;
2131 else
2132 break;
2135 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
2136 return;
2138 tree sizet;
2139 tree base_addr = base;
2140 gimple *bos_stmt = NULL;
2141 if (decl_p)
2142 base_addr = build1 (ADDR_EXPR,
2143 build_pointer_type (TREE_TYPE (base)), base);
2144 unsigned HOST_WIDE_INT size;
2145 if (compute_builtin_object_size (base_addr, 0, &size))
2146 sizet = build_int_cst (sizetype, size);
2147 else if (optimize)
2149 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
2150 loc = input_location;
2151 /* Generate __builtin_object_size call. */
2152 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
2153 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
2154 integer_zero_node);
2155 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
2156 GSI_SAME_STMT);
2157 /* If the call above didn't end up being an integer constant, go one
2158 statement back and get the __builtin_object_size stmt. Save it,
2159 we might need it later. */
2160 if (SSA_VAR_P (sizet))
2162 gsi_prev (gsi);
2163 bos_stmt = gsi_stmt (*gsi);
2165 /* Move on to where we were. */
2166 gsi_next (gsi);
2169 else
2170 return;
2172 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
2173 call. */
2174 /* ptr + sizeof (*ptr) - base */
2175 t = fold_build2 (MINUS_EXPR, sizetype,
2176 fold_convert (pointer_sized_int_node, ptr),
2177 fold_convert (pointer_sized_int_node, base_addr));
2178 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
2180 /* Perhaps we can omit the check. */
2181 if (TREE_CODE (t) == INTEGER_CST
2182 && TREE_CODE (sizet) == INTEGER_CST
2183 && tree_int_cst_le (t, sizet))
2184 return;
2186 if (index != NULL_TREE
2187 && TREE_CODE (index) == SSA_NAME
2188 && TREE_CODE (sizet) == INTEGER_CST)
2190 gimple *def = SSA_NAME_DEF_STMT (index);
2191 if (is_gimple_assign (def)
2192 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
2193 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
2195 tree cst = gimple_assign_rhs2 (def);
2196 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
2197 TYPE_SIZE_UNIT (type));
2198 if (tree_int_cst_sgn (cst) >= 0
2199 && tree_int_cst_lt (cst, sz))
2200 return;
2204 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
2205 ubsan_create_edge (bos_stmt);
2207 /* We have to emit the check. */
2208 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
2209 GSI_SAME_STMT);
2210 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
2211 GSI_SAME_STMT);
2212 tree ckind = build_int_cst (unsigned_char_type_node,
2213 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
2214 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
2215 ptr, t, sizet, ckind);
2216 gimple_set_location (g, loc);
2217 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2220 /* Instrument values passed to builtin functions. */
2222 static void
2223 instrument_builtin (gimple_stmt_iterator *gsi)
2225 gimple *stmt = gsi_stmt (*gsi);
2226 location_t loc = gimple_location (stmt);
2227 tree arg;
2228 enum built_in_function fcode
2229 = DECL_FUNCTION_CODE (gimple_call_fndecl (stmt));
2230 int kind = 0;
2231 switch (fcode)
2233 CASE_INT_FN (BUILT_IN_CLZ):
2234 kind = 1;
2235 gcc_fallthrough ();
2236 CASE_INT_FN (BUILT_IN_CTZ):
2237 arg = gimple_call_arg (stmt, 0);
2238 if (!integer_nonzerop (arg))
2240 gimple *g;
2241 if (!is_gimple_val (arg))
2243 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
2244 gimple_set_location (g, loc);
2245 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2246 arg = gimple_assign_lhs (g);
2249 basic_block then_bb, fallthru_bb;
2250 *gsi = create_cond_insert_point (gsi, true, false, true,
2251 &then_bb, &fallthru_bb);
2252 g = gimple_build_cond (EQ_EXPR, arg,
2253 build_zero_cst (TREE_TYPE (arg)),
2254 NULL_TREE, NULL_TREE);
2255 gimple_set_location (g, loc);
2256 gsi_insert_after (gsi, g, GSI_NEW_STMT);
2258 *gsi = gsi_after_labels (then_bb);
2259 if (flag_sanitize_undefined_trap_on_error)
2260 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2261 else
2263 tree t = build_int_cst (unsigned_char_type_node, kind);
2264 tree data = ubsan_create_data ("__ubsan_builtin_data",
2265 1, &loc, NULL_TREE, t, NULL_TREE);
2266 data = build_fold_addr_expr_loc (loc, data);
2267 enum built_in_function bcode
2268 = (flag_sanitize_recover & SANITIZE_BUILTIN)
2269 ? BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN
2270 : BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN_ABORT;
2271 tree fn = builtin_decl_explicit (bcode);
2273 g = gimple_build_call (fn, 1, data);
2275 gimple_set_location (g, loc);
2276 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2277 ubsan_create_edge (g);
2279 *gsi = gsi_for_stmt (stmt);
2280 break;
2281 default:
2282 break;
2286 namespace {
2288 const pass_data pass_data_ubsan =
2290 GIMPLE_PASS, /* type */
2291 "ubsan", /* name */
2292 OPTGROUP_NONE, /* optinfo_flags */
2293 TV_TREE_UBSAN, /* tv_id */
2294 ( PROP_cfg | PROP_ssa ), /* properties_required */
2295 0, /* properties_provided */
2296 0, /* properties_destroyed */
2297 0, /* todo_flags_start */
2298 TODO_update_ssa, /* todo_flags_finish */
2301 class pass_ubsan : public gimple_opt_pass
2303 public:
2304 pass_ubsan (gcc::context *ctxt)
2305 : gimple_opt_pass (pass_data_ubsan, ctxt)
2308 /* opt_pass methods: */
2309 virtual bool gate (function *)
2311 return sanitize_flags_p ((SANITIZE_NULL | SANITIZE_SI_OVERFLOW
2312 | SANITIZE_BOOL | SANITIZE_ENUM
2313 | SANITIZE_ALIGNMENT
2314 | SANITIZE_NONNULL_ATTRIBUTE
2315 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
2316 | SANITIZE_OBJECT_SIZE
2317 | SANITIZE_POINTER_OVERFLOW
2318 | SANITIZE_BUILTIN));
2321 virtual unsigned int execute (function *);
2323 }; // class pass_ubsan
2325 unsigned int
2326 pass_ubsan::execute (function *fun)
2328 basic_block bb;
2329 gimple_stmt_iterator gsi;
2330 unsigned int ret = 0;
2332 initialize_sanitizer_builtins ();
2334 FOR_EACH_BB_FN (bb, fun)
2336 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
2338 gimple *stmt = gsi_stmt (gsi);
2339 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
2341 gsi_next (&gsi);
2342 continue;
2345 if ((sanitize_flags_p (SANITIZE_SI_OVERFLOW, fun->decl))
2346 && is_gimple_assign (stmt))
2347 instrument_si_overflow (gsi);
2349 if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT, fun->decl))
2351 if (gimple_store_p (stmt))
2352 instrument_null (gsi, gimple_get_lhs (stmt), true);
2353 if (gimple_assign_single_p (stmt))
2354 instrument_null (gsi, gimple_assign_rhs1 (stmt), false);
2355 if (is_gimple_call (stmt))
2357 unsigned args_num = gimple_call_num_args (stmt);
2358 for (unsigned i = 0; i < args_num; ++i)
2360 tree arg = gimple_call_arg (stmt, i);
2361 if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2362 continue;
2363 instrument_null (gsi, arg, false);
2368 if (sanitize_flags_p (SANITIZE_BOOL | SANITIZE_ENUM, fun->decl)
2369 && gimple_assign_load_p (stmt))
2371 instrument_bool_enum_load (&gsi);
2372 bb = gimple_bb (stmt);
2375 if (sanitize_flags_p (SANITIZE_NONNULL_ATTRIBUTE, fun->decl)
2376 && is_gimple_call (stmt)
2377 && !gimple_call_internal_p (stmt))
2379 instrument_nonnull_arg (&gsi);
2380 bb = gimple_bb (stmt);
2383 if (sanitize_flags_p (SANITIZE_BUILTIN, fun->decl)
2384 && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
2386 instrument_builtin (&gsi);
2387 bb = gimple_bb (stmt);
2390 if (sanitize_flags_p (SANITIZE_RETURNS_NONNULL_ATTRIBUTE, fun->decl)
2391 && gimple_code (stmt) == GIMPLE_RETURN)
2393 instrument_nonnull_return (&gsi);
2394 bb = gimple_bb (stmt);
2397 if (sanitize_flags_p (SANITIZE_OBJECT_SIZE, fun->decl))
2399 if (gimple_store_p (stmt))
2400 instrument_object_size (&gsi, gimple_get_lhs (stmt), true);
2401 if (gimple_assign_load_p (stmt))
2402 instrument_object_size (&gsi, gimple_assign_rhs1 (stmt),
2403 false);
2404 if (is_gimple_call (stmt))
2406 unsigned args_num = gimple_call_num_args (stmt);
2407 for (unsigned i = 0; i < args_num; ++i)
2409 tree arg = gimple_call_arg (stmt, i);
2410 if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2411 continue;
2412 instrument_object_size (&gsi, arg, false);
2417 if (sanitize_flags_p (SANITIZE_POINTER_OVERFLOW, fun->decl))
2419 if (is_gimple_assign (stmt)
2420 && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
2421 instrument_pointer_overflow (&gsi,
2422 gimple_assign_rhs1 (stmt),
2423 gimple_assign_rhs2 (stmt));
2424 if (gimple_store_p (stmt))
2425 maybe_instrument_pointer_overflow (&gsi,
2426 gimple_get_lhs (stmt));
2427 if (gimple_assign_single_p (stmt))
2428 maybe_instrument_pointer_overflow (&gsi,
2429 gimple_assign_rhs1 (stmt));
2430 if (is_gimple_call (stmt))
2432 unsigned args_num = gimple_call_num_args (stmt);
2433 for (unsigned i = 0; i < args_num; ++i)
2435 tree arg = gimple_call_arg (stmt, i);
2436 if (is_gimple_reg (arg))
2437 continue;
2438 maybe_instrument_pointer_overflow (&gsi, arg);
2443 gsi_next (&gsi);
2445 if (gimple_purge_dead_eh_edges (bb))
2446 ret = TODO_cleanup_cfg;
2448 return ret;
2451 } // anon namespace
2453 gimple_opt_pass *
2454 make_pass_ubsan (gcc::context *ctxt)
2456 return new pass_ubsan (ctxt);
2459 #include "gt-ubsan.h"