debug/dwarf: support 64-bit DWARF in byte order check
[official-gcc.git] / gcc / ubsan.c
bloba6d446a69a84671afcf720ce4e5d3b09ee913cc0
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 ();
808 /* Connect 'then block' with the 'else block'. This is needed
809 as the ubsan routines we call in the 'then block' are not noreturn.
810 The 'then block' only has one outcoming edge. */
811 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
813 /* Set up the fallthrough basic block. */
814 e = find_edge (cond_bb, fallthru_bb);
815 e->flags = EDGE_FALSE_VALUE;
816 e->probability = profile_probability::very_likely ();
818 /* Update dominance info for the newly created then_bb; note that
819 fallthru_bb's dominance info has already been updated by
820 split_block. */
821 if (dom_info_available_p (CDI_DOMINATORS))
822 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
824 /* Put the ubsan builtin call into the newly created BB. */
825 if (flag_sanitize_undefined_trap_on_error)
826 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
827 else
829 enum built_in_function bcode
830 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
831 | (check_null ? SANITIZE_NULL : 0)))
832 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1
833 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_ABORT;
834 tree fn = builtin_decl_implicit (bcode);
835 int align_log = tree_log2 (align);
836 tree data
837 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
838 ubsan_type_descriptor (TREE_TYPE (ckind),
839 UBSAN_PRINT_POINTER),
840 NULL_TREE,
841 build_int_cst (unsigned_char_type_node,
842 MAX (align_log, 0)),
843 fold_convert (unsigned_char_type_node, ckind),
844 NULL_TREE);
845 data = build_fold_addr_expr_loc (loc, data);
846 g = gimple_build_call (fn, 2, data,
847 check_align ? check_align
848 : build_zero_cst (pointer_sized_int_node));
850 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
851 gimple_set_location (g, loc);
852 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
854 /* Unlink the UBSAN_NULLs vops before replacing it. */
855 unlink_stmt_vdef (stmt);
857 if (check_null)
859 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
860 NULL_TREE, NULL_TREE);
861 gimple_set_location (g, loc);
863 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
864 gsi_replace (&gsi, g, false);
865 stmt = g;
868 if (check_align)
870 if (check_null)
872 /* Split the block with the condition again. */
873 e = split_block (cond_bb, stmt);
874 basic_block cond1_bb = e->src;
875 basic_block cond2_bb = e->dest;
877 /* Make an edge coming from the 'cond1 block' into the 'then block';
878 this edge is unlikely taken, so set up the probability
879 accordingly. */
880 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
881 e->probability = profile_probability::very_unlikely ();
883 /* Set up the fallthrough basic block. */
884 e = find_edge (cond1_bb, cond2_bb);
885 e->flags = EDGE_FALSE_VALUE;
886 e->probability = profile_probability::very_likely ();
888 /* Update dominance info. */
889 if (dom_info_available_p (CDI_DOMINATORS))
891 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
892 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
895 gsi2 = gsi_start_bb (cond2_bb);
898 tree mask = build_int_cst (pointer_sized_int_node,
899 tree_to_uhwi (align) - 1);
900 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
901 BIT_AND_EXPR, check_align, mask);
902 gimple_set_location (g, loc);
903 if (check_null)
904 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
905 else
906 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
908 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
909 build_int_cst (pointer_sized_int_node, 0),
910 NULL_TREE, NULL_TREE);
911 gimple_set_location (g, loc);
912 if (check_null)
913 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
914 else
915 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
916 gsi_replace (&gsi, g, false);
918 return false;
921 #define OBJSZ_MAX_OFFSET (1024 * 16)
923 /* Expand UBSAN_OBJECT_SIZE internal call. */
925 bool
926 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
928 gimple *stmt = gsi_stmt (*gsi);
929 location_t loc = gimple_location (stmt);
930 gcc_assert (gimple_call_num_args (stmt) == 4);
932 tree ptr = gimple_call_arg (stmt, 0);
933 tree offset = gimple_call_arg (stmt, 1);
934 tree size = gimple_call_arg (stmt, 2);
935 tree ckind = gimple_call_arg (stmt, 3);
936 gimple_stmt_iterator gsi_orig = *gsi;
937 gimple *g;
939 /* See if we can discard the check. */
940 if (TREE_CODE (size) != INTEGER_CST
941 || integer_all_onesp (size))
942 /* Yes, __builtin_object_size couldn't determine the
943 object size. */;
944 else if (TREE_CODE (offset) == INTEGER_CST
945 && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
946 && wi::to_widest (offset) <= -1)
947 /* The offset is in range [-16K, -1]. */;
948 else
950 /* if (offset > objsize) */
951 basic_block then_bb, fallthru_bb;
952 gimple_stmt_iterator cond_insert_point
953 = create_cond_insert_point (gsi, false, false, true,
954 &then_bb, &fallthru_bb);
955 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
956 gimple_set_location (g, loc);
957 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
959 /* If the offset is small enough, we don't need the second
960 run-time check. */
961 if (TREE_CODE (offset) == INTEGER_CST
962 && wi::to_widest (offset) >= 0
963 && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
964 *gsi = gsi_after_labels (then_bb);
965 else
967 /* Don't issue run-time error if (ptr > ptr + offset). That
968 may happen when computing a POINTER_PLUS_EXPR. */
969 basic_block then2_bb, fallthru2_bb;
971 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
972 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
973 true, &then2_bb,
974 &fallthru2_bb);
975 /* Convert the pointer to an integer type. */
976 tree p = make_ssa_name (pointer_sized_int_node);
977 g = gimple_build_assign (p, NOP_EXPR, ptr);
978 gimple_set_location (g, loc);
979 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
980 p = gimple_assign_lhs (g);
981 /* Compute ptr + offset. */
982 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
983 PLUS_EXPR, p, offset);
984 gimple_set_location (g, loc);
985 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
986 /* Now build the conditional and put it into the IR. */
987 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
988 NULL_TREE, NULL_TREE);
989 gimple_set_location (g, loc);
990 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
991 *gsi = gsi_after_labels (then2_bb);
994 /* Generate __ubsan_handle_type_mismatch call. */
995 if (flag_sanitize_undefined_trap_on_error)
996 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
997 else
999 tree data
1000 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
1001 ubsan_type_descriptor (TREE_TYPE (ptr),
1002 UBSAN_PRINT_POINTER),
1003 NULL_TREE,
1004 build_zero_cst (unsigned_char_type_node),
1005 ckind,
1006 NULL_TREE);
1007 data = build_fold_addr_expr_loc (loc, data);
1008 enum built_in_function bcode
1009 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1010 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1
1011 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_ABORT;
1012 tree p = make_ssa_name (pointer_sized_int_node);
1013 g = gimple_build_assign (p, NOP_EXPR, ptr);
1014 gimple_set_location (g, loc);
1015 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1016 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1018 gimple_set_location (g, loc);
1019 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1021 /* Point GSI to next logical statement. */
1022 *gsi = gsi_start_bb (fallthru_bb);
1024 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1025 unlink_stmt_vdef (stmt);
1026 gsi_remove (&gsi_orig, true);
1027 return true;
1030 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1031 unlink_stmt_vdef (stmt);
1032 gsi_remove (gsi, true);
1033 return true;
1036 /* Expand UBSAN_PTR internal call. */
1038 bool
1039 ubsan_expand_ptr_ifn (gimple_stmt_iterator *gsip)
1041 gimple_stmt_iterator gsi = *gsip;
1042 gimple *stmt = gsi_stmt (gsi);
1043 location_t loc = gimple_location (stmt);
1044 gcc_assert (gimple_call_num_args (stmt) == 2);
1045 tree ptr = gimple_call_arg (stmt, 0);
1046 tree off = gimple_call_arg (stmt, 1);
1048 if (integer_zerop (off))
1050 gsi_remove (gsip, true);
1051 unlink_stmt_vdef (stmt);
1052 return true;
1055 basic_block cur_bb = gsi_bb (gsi);
1056 tree ptrplusoff = make_ssa_name (pointer_sized_int_node);
1057 tree ptri = make_ssa_name (pointer_sized_int_node);
1058 int pos_neg = get_range_pos_neg (off);
1060 /* Split the original block holding the pointer dereference. */
1061 edge e = split_block (cur_bb, stmt);
1063 /* Get a hold on the 'condition block', the 'then block' and the
1064 'else block'. */
1065 basic_block cond_bb = e->src;
1066 basic_block fallthru_bb = e->dest;
1067 basic_block then_bb = create_empty_bb (cond_bb);
1068 basic_block cond_pos_bb = NULL, cond_neg_bb = NULL;
1069 add_bb_to_loop (then_bb, cond_bb->loop_father);
1070 loops_state_set (LOOPS_NEED_FIXUP);
1072 /* Set up the fallthrough basic block. */
1073 e->flags = EDGE_FALSE_VALUE;
1074 if (pos_neg != 3)
1076 e->probability = profile_probability::very_likely ();
1078 /* Connect 'then block' with the 'else block'. This is needed
1079 as the ubsan routines we call in the 'then block' are not noreturn.
1080 The 'then block' only has one outcoming edge. */
1081 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
1083 /* Make an edge coming from the 'cond block' into the 'then block';
1084 this edge is unlikely taken, so set up the probability
1085 accordingly. */
1086 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
1087 e->probability = profile_probability::very_unlikely ();
1089 else
1091 e->probability = profile_probability::even ();
1093 e = split_block (fallthru_bb, (gimple *) NULL);
1094 cond_neg_bb = e->src;
1095 fallthru_bb = e->dest;
1096 e->probability = profile_probability::very_likely ();
1097 e->flags = EDGE_FALSE_VALUE;
1099 e = make_edge (cond_neg_bb, then_bb, EDGE_TRUE_VALUE);
1100 e->probability = profile_probability::very_unlikely ();
1102 cond_pos_bb = create_empty_bb (cond_bb);
1103 add_bb_to_loop (cond_pos_bb, cond_bb->loop_father);
1105 e = make_edge (cond_bb, cond_pos_bb, EDGE_TRUE_VALUE);
1106 e->probability = profile_probability::even ();
1108 e = make_edge (cond_pos_bb, then_bb, EDGE_TRUE_VALUE);
1109 e->probability = profile_probability::very_unlikely ();
1111 e = make_edge (cond_pos_bb, fallthru_bb, EDGE_FALSE_VALUE);
1112 e->probability = profile_probability::very_likely ();
1114 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
1117 gimple *g = gimple_build_assign (ptri, NOP_EXPR, ptr);
1118 gimple_set_location (g, loc);
1119 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1120 g = gimple_build_assign (ptrplusoff, PLUS_EXPR, ptri, off);
1121 gimple_set_location (g, loc);
1122 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1124 /* Update dominance info for the newly created then_bb; note that
1125 fallthru_bb's dominance info has already been updated by
1126 split_block. */
1127 if (dom_info_available_p (CDI_DOMINATORS))
1129 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
1130 if (pos_neg == 3)
1132 set_immediate_dominator (CDI_DOMINATORS, cond_pos_bb, cond_bb);
1133 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond_bb);
1137 /* Put the ubsan builtin call into the newly created BB. */
1138 if (flag_sanitize_undefined_trap_on_error)
1139 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
1140 else
1142 enum built_in_function bcode
1143 = (flag_sanitize_recover & SANITIZE_POINTER_OVERFLOW)
1144 ? BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW
1145 : BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW_ABORT;
1146 tree fn = builtin_decl_implicit (bcode);
1147 tree data
1148 = ubsan_create_data ("__ubsan_ptrovf_data", 1, &loc,
1149 NULL_TREE, NULL_TREE);
1150 data = build_fold_addr_expr_loc (loc, data);
1151 g = gimple_build_call (fn, 3, data, ptr, ptrplusoff);
1153 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
1154 gimple_set_location (g, loc);
1155 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1157 /* Unlink the UBSAN_PTRs vops before replacing it. */
1158 unlink_stmt_vdef (stmt);
1160 if (TREE_CODE (off) == INTEGER_CST)
1161 g = gimple_build_cond (wi::neg_p (wi::to_wide (off)) ? LT_EXPR : GE_EXPR,
1162 ptri, fold_build1 (NEGATE_EXPR, sizetype, off),
1163 NULL_TREE, NULL_TREE);
1164 else if (pos_neg != 3)
1165 g = gimple_build_cond (pos_neg == 1 ? LT_EXPR : GT_EXPR,
1166 ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1167 else
1169 gsi2 = gsi_start_bb (cond_pos_bb);
1170 g = gimple_build_cond (LT_EXPR, ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1171 gimple_set_location (g, loc);
1172 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1174 gsi2 = gsi_start_bb (cond_neg_bb);
1175 g = gimple_build_cond (GT_EXPR, ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1176 gimple_set_location (g, loc);
1177 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1179 gimple_seq seq = NULL;
1180 tree t = gimple_build (&seq, loc, NOP_EXPR, ssizetype, off);
1181 t = gimple_build (&seq, loc, GE_EXPR, boolean_type_node,
1182 t, ssize_int (0));
1183 gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
1184 g = gimple_build_cond (NE_EXPR, t, boolean_false_node,
1185 NULL_TREE, NULL_TREE);
1187 gimple_set_location (g, loc);
1188 /* Replace the UBSAN_PTR with a GIMPLE_COND stmt. */
1189 gsi_replace (&gsi, g, false);
1190 return false;
1194 /* Cached __ubsan_vptr_type_cache decl. */
1195 static GTY(()) tree ubsan_vptr_type_cache_decl;
1197 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1198 argument which is a constant, because the middle-end treats pointer
1199 conversions as useless and therefore the type of the first argument
1200 could be changed to any other pointer type. */
1202 bool
1203 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1205 gimple_stmt_iterator gsi = *gsip;
1206 gimple *stmt = gsi_stmt (gsi);
1207 location_t loc = gimple_location (stmt);
1208 gcc_assert (gimple_call_num_args (stmt) == 5);
1209 tree op = gimple_call_arg (stmt, 0);
1210 tree vptr = gimple_call_arg (stmt, 1);
1211 tree str_hash = gimple_call_arg (stmt, 2);
1212 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1213 tree ckind_tree = gimple_call_arg (stmt, 4);
1214 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1215 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1216 gimple *g;
1217 basic_block fallthru_bb = NULL;
1219 if (ckind == UBSAN_DOWNCAST_POINTER)
1221 /* Guard everything with if (op != NULL) { ... }. */
1222 basic_block then_bb;
1223 gimple_stmt_iterator cond_insert_point
1224 = create_cond_insert_point (gsip, false, false, true,
1225 &then_bb, &fallthru_bb);
1226 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1227 NULL_TREE, NULL_TREE);
1228 gimple_set_location (g, loc);
1229 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1230 *gsip = gsi_after_labels (then_bb);
1231 gsi_remove (&gsi, false);
1232 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1233 gsi = *gsip;
1236 tree htype = TREE_TYPE (str_hash);
1237 tree cst = wide_int_to_tree (htype,
1238 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1239 | 0xeb382d69, 64));
1240 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1241 vptr, str_hash);
1242 gimple_set_location (g, loc);
1243 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1244 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1245 gimple_assign_lhs (g), cst);
1246 gimple_set_location (g, loc);
1247 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1248 tree t1 = gimple_assign_lhs (g);
1249 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1250 t1, build_int_cst (integer_type_node, 47));
1251 gimple_set_location (g, loc);
1252 tree t2 = gimple_assign_lhs (g);
1253 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1254 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1255 vptr, t1);
1256 gimple_set_location (g, loc);
1257 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1258 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1259 t2, gimple_assign_lhs (g));
1260 gimple_set_location (g, loc);
1261 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1262 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1263 gimple_assign_lhs (g), cst);
1264 gimple_set_location (g, loc);
1265 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1266 tree t3 = gimple_assign_lhs (g);
1267 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1268 t3, build_int_cst (integer_type_node, 47));
1269 gimple_set_location (g, loc);
1270 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1271 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1272 t3, gimple_assign_lhs (g));
1273 gimple_set_location (g, loc);
1274 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1275 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1276 gimple_assign_lhs (g), cst);
1277 gimple_set_location (g, loc);
1278 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1279 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1281 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1282 NOP_EXPR, gimple_assign_lhs (g));
1283 gimple_set_location (g, loc);
1284 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1286 tree hash = gimple_assign_lhs (g);
1288 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1290 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1291 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1292 get_identifier ("__ubsan_vptr_type_cache"),
1293 atype);
1294 DECL_ARTIFICIAL (array) = 1;
1295 DECL_IGNORED_P (array) = 1;
1296 TREE_PUBLIC (array) = 1;
1297 TREE_STATIC (array) = 1;
1298 DECL_EXTERNAL (array) = 1;
1299 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1300 DECL_VISIBILITY_SPECIFIED (array) = 1;
1301 varpool_node::finalize_decl (array);
1302 ubsan_vptr_type_cache_decl = array;
1305 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1306 BIT_AND_EXPR, hash,
1307 build_int_cst (pointer_sized_int_node, 127));
1308 gimple_set_location (g, loc);
1309 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1311 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1312 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1313 NULL_TREE, NULL_TREE);
1314 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1315 ARRAY_REF, c);
1316 gimple_set_location (g, loc);
1317 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1319 basic_block then_bb, fallthru2_bb;
1320 gimple_stmt_iterator cond_insert_point
1321 = create_cond_insert_point (gsip, false, false, true,
1322 &then_bb, &fallthru2_bb);
1323 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1324 NULL_TREE, NULL_TREE);
1325 gimple_set_location (g, loc);
1326 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1327 *gsip = gsi_after_labels (then_bb);
1328 if (fallthru_bb == NULL)
1329 fallthru_bb = fallthru2_bb;
1331 tree data
1332 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1333 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1334 build_int_cst (unsigned_char_type_node, ckind),
1335 NULL_TREE);
1336 data = build_fold_addr_expr_loc (loc, data);
1337 enum built_in_function bcode
1338 = (flag_sanitize_recover & SANITIZE_VPTR)
1339 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1340 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1342 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1343 gimple_set_location (g, loc);
1344 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1346 /* Point GSI to next logical statement. */
1347 *gsip = gsi_start_bb (fallthru_bb);
1349 /* Get rid of the UBSAN_VPTR call from the IR. */
1350 unlink_stmt_vdef (stmt);
1351 gsi_remove (&gsi, true);
1352 return true;
1355 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1356 whether the pointer is on the left hand side of the assignment. */
1358 static void
1359 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1360 bool is_lhs)
1362 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1363 unsigned int align = 0;
1364 if (sanitize_flags_p (SANITIZE_ALIGNMENT))
1366 align = min_align_of_type (TREE_TYPE (base));
1367 if (align <= 1)
1368 align = 0;
1370 if (align == 0 && !sanitize_flags_p (SANITIZE_NULL))
1371 return;
1372 tree t = TREE_OPERAND (base, 0);
1373 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1374 return;
1375 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1376 ikind = UBSAN_MEMBER_ACCESS;
1377 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1378 tree alignt = build_int_cst (pointer_sized_int_node, align);
1379 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1380 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1381 gsi_insert_before (iter, g, GSI_SAME_STMT);
1384 /* Perform the pointer instrumentation. */
1386 static void
1387 instrument_null (gimple_stmt_iterator gsi, tree t, bool is_lhs)
1389 /* Handle also e.g. &s->i. */
1390 if (TREE_CODE (t) == ADDR_EXPR)
1391 t = TREE_OPERAND (t, 0);
1392 tree base = get_base_address (t);
1393 if (base != NULL_TREE
1394 && TREE_CODE (base) == MEM_REF
1395 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1396 instrument_mem_ref (t, base, &gsi, is_lhs);
1399 /* Instrument pointer arithmetics PTR p+ OFF. */
1401 static void
1402 instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree ptr, tree off)
1404 if (TYPE_PRECISION (sizetype) != POINTER_SIZE)
1405 return;
1406 gcall *g = gimple_build_call_internal (IFN_UBSAN_PTR, 2, ptr, off);
1407 gimple_set_location (g, gimple_location (gsi_stmt (*gsi)));
1408 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1411 /* Instrument pointer arithmetics if any. */
1413 static void
1414 maybe_instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree t)
1416 if (TYPE_PRECISION (sizetype) != POINTER_SIZE)
1417 return;
1419 /* Handle also e.g. &s->i. */
1420 if (TREE_CODE (t) == ADDR_EXPR)
1421 t = TREE_OPERAND (t, 0);
1423 if (!handled_component_p (t) && TREE_CODE (t) != MEM_REF)
1424 return;
1426 HOST_WIDE_INT bitsize, bitpos, bytepos;
1427 tree offset;
1428 machine_mode mode;
1429 int volatilep = 0, reversep, unsignedp = 0;
1430 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1431 &unsignedp, &reversep, &volatilep);
1432 tree moff = NULL_TREE;
1434 bool decl_p = DECL_P (inner);
1435 tree base;
1436 if (decl_p)
1438 if (DECL_REGISTER (inner))
1439 return;
1440 base = inner;
1441 /* If BASE is a fixed size automatic variable or
1442 global variable defined in the current TU and bitpos
1443 fits, don't instrument anything. */
1444 if (offset == NULL_TREE
1445 && bitpos > 0
1446 && (VAR_P (base)
1447 || TREE_CODE (base) == PARM_DECL
1448 || TREE_CODE (base) == RESULT_DECL)
1449 && DECL_SIZE (base)
1450 && TREE_CODE (DECL_SIZE (base)) == INTEGER_CST
1451 && compare_tree_int (DECL_SIZE (base), bitpos) >= 0
1452 && (!is_global_var (base) || decl_binds_to_current_def_p (base)))
1453 return;
1455 else if (TREE_CODE (inner) == MEM_REF)
1457 base = TREE_OPERAND (inner, 0);
1458 if (TREE_CODE (base) == ADDR_EXPR
1459 && DECL_P (TREE_OPERAND (base, 0))
1460 && !TREE_ADDRESSABLE (TREE_OPERAND (base, 0))
1461 && !is_global_var (TREE_OPERAND (base, 0)))
1462 return;
1463 moff = TREE_OPERAND (inner, 1);
1464 if (integer_zerop (moff))
1465 moff = NULL_TREE;
1467 else
1468 return;
1470 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1471 return;
1472 bytepos = bitpos / BITS_PER_UNIT;
1473 if (offset == NULL_TREE && bytepos == 0 && moff == NULL_TREE)
1474 return;
1476 tree base_addr = base;
1477 if (decl_p)
1478 base_addr = build1 (ADDR_EXPR,
1479 build_pointer_type (TREE_TYPE (base)), base);
1480 t = offset;
1481 if (bytepos)
1483 if (t)
1484 t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t,
1485 build_int_cst (TREE_TYPE (t), bytepos));
1486 else
1487 t = size_int (bytepos);
1489 if (moff)
1491 if (t)
1492 t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t,
1493 fold_convert (TREE_TYPE (t), moff));
1494 else
1495 t = fold_convert (sizetype, moff);
1497 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1498 GSI_SAME_STMT);
1499 base_addr = force_gimple_operand_gsi (gsi, base_addr, true, NULL_TREE, true,
1500 GSI_SAME_STMT);
1501 instrument_pointer_overflow (gsi, base_addr, t);
1504 /* Build an ubsan builtin call for the signed-integer-overflow
1505 sanitization. CODE says what kind of builtin are we building,
1506 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1507 are operands of the binary operation. */
1509 tree
1510 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1511 tree op0, tree op1, tree *datap)
1513 if (flag_sanitize_undefined_trap_on_error)
1514 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1516 tree data;
1517 if (datap && *datap)
1518 data = *datap;
1519 else
1520 data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1521 ubsan_type_descriptor (lhstype), NULL_TREE,
1522 NULL_TREE);
1523 if (datap)
1524 *datap = data;
1525 enum built_in_function fn_code;
1527 switch (code)
1529 case PLUS_EXPR:
1530 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1531 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1532 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1533 break;
1534 case MINUS_EXPR:
1535 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1536 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1537 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1538 break;
1539 case MULT_EXPR:
1540 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1541 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1542 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1543 break;
1544 case NEGATE_EXPR:
1545 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1546 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1547 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1548 break;
1549 default:
1550 gcc_unreachable ();
1552 tree fn = builtin_decl_explicit (fn_code);
1553 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1554 build_fold_addr_expr_loc (loc, data),
1555 ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL),
1557 ? ubsan_encode_value (op1,
1558 UBSAN_ENCODE_VALUE_RTL)
1559 : NULL_TREE);
1562 /* Perform the signed integer instrumentation. GSI is the iterator
1563 pointing at statement we are trying to instrument. */
1565 static void
1566 instrument_si_overflow (gimple_stmt_iterator gsi)
1568 gimple *stmt = gsi_stmt (gsi);
1569 tree_code code = gimple_assign_rhs_code (stmt);
1570 tree lhs = gimple_assign_lhs (stmt);
1571 tree lhstype = TREE_TYPE (lhs);
1572 tree lhsinner = VECTOR_TYPE_P (lhstype) ? TREE_TYPE (lhstype) : lhstype;
1573 tree a, b;
1574 gimple *g;
1576 /* If this is not a signed operation, don't instrument anything here.
1577 Also punt on bit-fields. */
1578 if (!INTEGRAL_TYPE_P (lhsinner)
1579 || TYPE_OVERFLOW_WRAPS (lhsinner)
1580 || GET_MODE_BITSIZE (TYPE_MODE (lhsinner)) != TYPE_PRECISION (lhsinner))
1581 return;
1583 switch (code)
1585 case MINUS_EXPR:
1586 case PLUS_EXPR:
1587 case MULT_EXPR:
1588 /* Transform
1589 i = u {+,-,*} 5;
1590 into
1591 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1592 a = gimple_assign_rhs1 (stmt);
1593 b = gimple_assign_rhs2 (stmt);
1594 g = gimple_build_call_internal (code == PLUS_EXPR
1595 ? IFN_UBSAN_CHECK_ADD
1596 : code == MINUS_EXPR
1597 ? IFN_UBSAN_CHECK_SUB
1598 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1599 gimple_call_set_lhs (g, lhs);
1600 gsi_replace (&gsi, g, true);
1601 break;
1602 case NEGATE_EXPR:
1603 /* Represent i = -u;
1605 i = UBSAN_CHECK_SUB (0, u); */
1606 a = build_zero_cst (lhstype);
1607 b = gimple_assign_rhs1 (stmt);
1608 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1609 gimple_call_set_lhs (g, lhs);
1610 gsi_replace (&gsi, g, true);
1611 break;
1612 case ABS_EXPR:
1613 /* Transform i = ABS_EXPR<u>;
1614 into
1615 _N = UBSAN_CHECK_SUB (0, u);
1616 i = ABS_EXPR<_N>; */
1617 a = build_zero_cst (lhstype);
1618 b = gimple_assign_rhs1 (stmt);
1619 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1620 a = make_ssa_name (lhstype);
1621 gimple_call_set_lhs (g, a);
1622 gimple_set_location (g, gimple_location (stmt));
1623 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1624 gimple_assign_set_rhs1 (stmt, a);
1625 update_stmt (stmt);
1626 break;
1627 default:
1628 break;
1632 /* Instrument loads from (non-bitfield) bool and C++ enum values
1633 to check if the memory value is outside of the range of the valid
1634 type values. */
1636 static void
1637 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1639 gimple *stmt = gsi_stmt (*gsi);
1640 tree rhs = gimple_assign_rhs1 (stmt);
1641 tree type = TREE_TYPE (rhs);
1642 tree minv = NULL_TREE, maxv = NULL_TREE;
1644 if (TREE_CODE (type) == BOOLEAN_TYPE
1645 && sanitize_flags_p (SANITIZE_BOOL))
1647 minv = boolean_false_node;
1648 maxv = boolean_true_node;
1650 else if (TREE_CODE (type) == ENUMERAL_TYPE
1651 && sanitize_flags_p (SANITIZE_ENUM)
1652 && TREE_TYPE (type) != NULL_TREE
1653 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1654 && (TYPE_PRECISION (TREE_TYPE (type))
1655 < GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (type))))
1657 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1658 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1660 else
1661 return;
1663 int modebitsize = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type));
1664 HOST_WIDE_INT bitsize, bitpos;
1665 tree offset;
1666 machine_mode mode;
1667 int volatilep = 0, reversep, unsignedp = 0;
1668 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1669 &unsignedp, &reversep, &volatilep);
1670 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1672 if ((VAR_P (base) && DECL_HARD_REGISTER (base))
1673 || (bitpos % modebitsize) != 0
1674 || bitsize != modebitsize
1675 || GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (utype)) != modebitsize
1676 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1677 return;
1679 bool ends_bb = stmt_ends_bb_p (stmt);
1680 location_t loc = gimple_location (stmt);
1681 tree lhs = gimple_assign_lhs (stmt);
1682 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1683 tree atype = reference_alias_ptr_type (rhs);
1684 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1685 build_fold_addr_expr (rhs));
1686 gimple_set_location (g, loc);
1687 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1688 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1689 build_int_cst (atype, 0));
1690 tree urhs = make_ssa_name (utype);
1691 if (ends_bb)
1693 gimple_assign_set_lhs (stmt, urhs);
1694 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1695 gimple_set_location (g, loc);
1696 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1697 gsi_insert_on_edge_immediate (e, g);
1698 gimple_assign_set_rhs_from_tree (gsi, mem);
1699 update_stmt (stmt);
1700 *gsi = gsi_for_stmt (g);
1701 g = stmt;
1703 else
1705 g = gimple_build_assign (urhs, mem);
1706 gimple_set_location (g, loc);
1707 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1709 minv = fold_convert (utype, minv);
1710 maxv = fold_convert (utype, maxv);
1711 if (!integer_zerop (minv))
1713 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1714 gimple_set_location (g, loc);
1715 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1718 gimple_stmt_iterator gsi2 = *gsi;
1719 basic_block then_bb, fallthru_bb;
1720 *gsi = create_cond_insert_point (gsi, true, false, true,
1721 &then_bb, &fallthru_bb);
1722 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1723 int_const_binop (MINUS_EXPR, maxv, minv),
1724 NULL_TREE, NULL_TREE);
1725 gimple_set_location (g, loc);
1726 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1728 if (!ends_bb)
1730 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1731 update_stmt (stmt);
1734 gsi2 = gsi_after_labels (then_bb);
1735 if (flag_sanitize_undefined_trap_on_error)
1736 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1737 else
1739 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1740 ubsan_type_descriptor (type), NULL_TREE,
1741 NULL_TREE);
1742 data = build_fold_addr_expr_loc (loc, data);
1743 enum built_in_function bcode
1744 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1745 ? SANITIZE_BOOL : SANITIZE_ENUM))
1746 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1747 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1748 tree fn = builtin_decl_explicit (bcode);
1750 tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE);
1751 val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true,
1752 GSI_SAME_STMT);
1753 g = gimple_build_call (fn, 2, data, val);
1755 gimple_set_location (g, loc);
1756 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1757 ubsan_create_edge (g);
1758 *gsi = gsi_for_stmt (stmt);
1761 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1762 new style handlers. Libubsan uses heuristics to destinguish between old and
1763 new styles and relies on these properties for filename:
1765 a) Location's filename must not be NULL.
1766 b) Location's filename must not be equal to "".
1767 c) Location's filename must not be equal to "\1".
1768 d) First two bytes of filename must not contain '\xff' symbol. */
1770 static bool
1771 ubsan_use_new_style_p (location_t loc)
1773 if (loc == UNKNOWN_LOCATION)
1774 return false;
1776 expanded_location xloc = expand_location (loc);
1777 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1778 || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1779 || xloc.file[1] == '\xff')
1780 return false;
1782 return true;
1785 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1786 destination, EXPR is floating-point expression. */
1788 tree
1789 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1791 tree expr_type = TREE_TYPE (expr);
1792 tree t, tt, fn, min, max;
1793 machine_mode mode = TYPE_MODE (expr_type);
1794 int prec = TYPE_PRECISION (type);
1795 bool uns_p = TYPE_UNSIGNED (type);
1796 if (loc == UNKNOWN_LOCATION)
1797 loc = input_location;
1799 /* Float to integer conversion first truncates toward zero, so
1800 even signed char c = 127.875f; is not problematic.
1801 Therefore, we should complain only if EXPR is unordered or smaller
1802 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1803 TYPE_MAX_VALUE + 1.0. */
1804 if (REAL_MODE_FORMAT (mode)->b == 2)
1806 /* For maximum, TYPE_MAX_VALUE might not be representable
1807 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1808 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1809 either representable or infinity. */
1810 REAL_VALUE_TYPE maxval = dconst1;
1811 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1812 real_convert (&maxval, mode, &maxval);
1813 max = build_real (expr_type, maxval);
1815 /* For unsigned, assume -1.0 is always representable. */
1816 if (uns_p)
1817 min = build_minus_one_cst (expr_type);
1818 else
1820 /* TYPE_MIN_VALUE is generally representable (or -inf),
1821 but TYPE_MIN_VALUE - 1.0 might not be. */
1822 REAL_VALUE_TYPE minval = dconstm1, minval2;
1823 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1824 real_convert (&minval, mode, &minval);
1825 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1826 real_convert (&minval2, mode, &minval2);
1827 if (real_compare (EQ_EXPR, &minval, &minval2)
1828 && !real_isinf (&minval))
1830 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1831 rounds to TYPE_MIN_VALUE, we need to subtract
1832 more. As REAL_MODE_FORMAT (mode)->p is the number
1833 of base digits, we want to subtract a number that
1834 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1835 times smaller than minval. */
1836 minval2 = dconst1;
1837 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1838 SET_REAL_EXP (&minval2,
1839 REAL_EXP (&minval2) + prec - 1
1840 - REAL_MODE_FORMAT (mode)->p + 1);
1841 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1842 real_convert (&minval2, mode, &minval2);
1844 min = build_real (expr_type, minval2);
1847 else if (REAL_MODE_FORMAT (mode)->b == 10)
1849 /* For _Decimal128 up to 34 decimal digits, - sign,
1850 dot, e, exponent. */
1851 char buf[64];
1852 mpfr_t m;
1853 int p = REAL_MODE_FORMAT (mode)->p;
1854 REAL_VALUE_TYPE maxval, minval;
1856 /* Use mpfr_snprintf rounding to compute the smallest
1857 representable decimal number greater or equal than
1858 1 << (prec - !uns_p). */
1859 mpfr_init2 (m, prec + 2);
1860 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1861 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1862 decimal_real_from_string (&maxval, buf);
1863 max = build_real (expr_type, maxval);
1865 /* For unsigned, assume -1.0 is always representable. */
1866 if (uns_p)
1867 min = build_minus_one_cst (expr_type);
1868 else
1870 /* Use mpfr_snprintf rounding to compute the largest
1871 representable decimal number less or equal than
1872 (-1 << (prec - 1)) - 1. */
1873 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1874 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1875 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1876 decimal_real_from_string (&minval, buf);
1877 min = build_real (expr_type, minval);
1879 mpfr_clear (m);
1881 else
1882 return NULL_TREE;
1884 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1885 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1886 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1887 if (integer_zerop (t))
1888 return NULL_TREE;
1890 if (flag_sanitize_undefined_trap_on_error)
1891 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1892 else
1894 location_t *loc_ptr = NULL;
1895 unsigned num_locations = 0;
1896 /* Figure out if we can propagate location to ubsan_data and use new
1897 style handlers in libubsan. */
1898 if (ubsan_use_new_style_p (loc))
1900 loc_ptr = &loc;
1901 num_locations = 1;
1903 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1904 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1905 num_locations, loc_ptr,
1906 ubsan_type_descriptor (expr_type),
1907 ubsan_type_descriptor (type), NULL_TREE,
1908 NULL_TREE);
1909 enum built_in_function bcode
1910 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1911 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1912 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1913 fn = builtin_decl_explicit (bcode);
1914 fn = build_call_expr_loc (loc, fn, 2,
1915 build_fold_addr_expr_loc (loc, data),
1916 ubsan_encode_value (expr));
1919 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1922 /* Instrument values passed to function arguments with nonnull attribute. */
1924 static void
1925 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1927 gimple *stmt = gsi_stmt (*gsi);
1928 location_t loc[2];
1929 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1930 while for nonnull sanitization it is clear. */
1931 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1932 flag_delete_null_pointer_checks = 1;
1933 loc[0] = gimple_location (stmt);
1934 loc[1] = UNKNOWN_LOCATION;
1935 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1937 tree arg = gimple_call_arg (stmt, i);
1938 if (POINTER_TYPE_P (TREE_TYPE (arg))
1939 && infer_nonnull_range_by_attribute (stmt, arg))
1941 gimple *g;
1942 if (!is_gimple_val (arg))
1944 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1945 gimple_set_location (g, loc[0]);
1946 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1947 arg = gimple_assign_lhs (g);
1950 basic_block then_bb, fallthru_bb;
1951 *gsi = create_cond_insert_point (gsi, true, false, true,
1952 &then_bb, &fallthru_bb);
1953 g = gimple_build_cond (EQ_EXPR, arg,
1954 build_zero_cst (TREE_TYPE (arg)),
1955 NULL_TREE, NULL_TREE);
1956 gimple_set_location (g, loc[0]);
1957 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1959 *gsi = gsi_after_labels (then_bb);
1960 if (flag_sanitize_undefined_trap_on_error)
1961 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1962 else
1964 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1965 2, loc, NULL_TREE,
1966 build_int_cst (integer_type_node,
1967 i + 1),
1968 NULL_TREE);
1969 data = build_fold_addr_expr_loc (loc[0], data);
1970 enum built_in_function bcode
1971 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1972 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1973 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1974 tree fn = builtin_decl_explicit (bcode);
1976 g = gimple_build_call (fn, 1, data);
1978 gimple_set_location (g, loc[0]);
1979 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1980 ubsan_create_edge (g);
1982 *gsi = gsi_for_stmt (stmt);
1984 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1987 /* Instrument returns in functions with returns_nonnull attribute. */
1989 static void
1990 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1992 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1993 location_t loc[2];
1994 tree arg = gimple_return_retval (stmt);
1995 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1996 while for nonnull return sanitization it is clear. */
1997 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1998 flag_delete_null_pointer_checks = 1;
1999 loc[0] = gimple_location (stmt);
2000 loc[1] = UNKNOWN_LOCATION;
2001 if (arg
2002 && POINTER_TYPE_P (TREE_TYPE (arg))
2003 && is_gimple_val (arg)
2004 && infer_nonnull_range_by_attribute (stmt, arg))
2006 basic_block then_bb, fallthru_bb;
2007 *gsi = create_cond_insert_point (gsi, true, false, true,
2008 &then_bb, &fallthru_bb);
2009 gimple *g = gimple_build_cond (EQ_EXPR, arg,
2010 build_zero_cst (TREE_TYPE (arg)),
2011 NULL_TREE, NULL_TREE);
2012 gimple_set_location (g, loc[0]);
2013 gsi_insert_after (gsi, g, GSI_NEW_STMT);
2015 *gsi = gsi_after_labels (then_bb);
2016 if (flag_sanitize_undefined_trap_on_error)
2017 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2018 else
2020 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
2021 1, &loc[1], NULL_TREE, NULL_TREE);
2022 data = build_fold_addr_expr_loc (loc[0], data);
2023 tree data2 = ubsan_create_data ("__ubsan_nonnull_return_data",
2024 1, &loc[0], NULL_TREE, NULL_TREE);
2025 data2 = build_fold_addr_expr_loc (loc[0], data2);
2026 enum built_in_function bcode
2027 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2028 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1
2029 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1_ABORT;
2030 tree fn = builtin_decl_explicit (bcode);
2032 g = gimple_build_call (fn, 2, data, data2);
2034 gimple_set_location (g, loc[0]);
2035 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2036 ubsan_create_edge (g);
2037 *gsi = gsi_for_stmt (stmt);
2039 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
2042 /* Instrument memory references. Here we check whether the pointer
2043 points to an out-of-bounds location. */
2045 static void
2046 instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
2048 gimple *stmt = gsi_stmt (*gsi);
2049 location_t loc = gimple_location (stmt);
2050 tree type;
2051 tree index = NULL_TREE;
2052 HOST_WIDE_INT size_in_bytes;
2054 type = TREE_TYPE (t);
2055 if (VOID_TYPE_P (type))
2056 return;
2058 switch (TREE_CODE (t))
2060 case COMPONENT_REF:
2061 if (TREE_CODE (t) == COMPONENT_REF
2062 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
2064 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
2065 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
2066 repr, TREE_OPERAND (t, 2));
2068 break;
2069 case ARRAY_REF:
2070 index = TREE_OPERAND (t, 1);
2071 break;
2072 case INDIRECT_REF:
2073 case MEM_REF:
2074 case VAR_DECL:
2075 case PARM_DECL:
2076 case RESULT_DECL:
2077 break;
2078 default:
2079 return;
2082 size_in_bytes = int_size_in_bytes (type);
2083 if (size_in_bytes <= 0)
2084 return;
2086 HOST_WIDE_INT bitsize, bitpos;
2087 tree offset;
2088 machine_mode mode;
2089 int volatilep = 0, reversep, unsignedp = 0;
2090 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
2091 &unsignedp, &reversep, &volatilep);
2093 if (bitpos % BITS_PER_UNIT != 0
2094 || bitsize != size_in_bytes * BITS_PER_UNIT)
2095 return;
2097 bool decl_p = DECL_P (inner);
2098 tree base;
2099 if (decl_p)
2101 if (DECL_REGISTER (inner))
2102 return;
2103 base = inner;
2105 else if (TREE_CODE (inner) == MEM_REF)
2106 base = TREE_OPERAND (inner, 0);
2107 else
2108 return;
2109 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
2111 while (TREE_CODE (base) == SSA_NAME)
2113 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
2114 if (gimple_assign_ssa_name_copy_p (def_stmt)
2115 || (gimple_assign_cast_p (def_stmt)
2116 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
2117 || (is_gimple_assign (def_stmt)
2118 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
2120 tree rhs1 = gimple_assign_rhs1 (def_stmt);
2121 if (TREE_CODE (rhs1) == SSA_NAME
2122 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
2123 break;
2124 else
2125 base = rhs1;
2127 else
2128 break;
2131 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
2132 return;
2134 tree sizet;
2135 tree base_addr = base;
2136 gimple *bos_stmt = NULL;
2137 if (decl_p)
2138 base_addr = build1 (ADDR_EXPR,
2139 build_pointer_type (TREE_TYPE (base)), base);
2140 unsigned HOST_WIDE_INT size;
2141 if (compute_builtin_object_size (base_addr, 0, &size))
2142 sizet = build_int_cst (sizetype, size);
2143 else if (optimize)
2145 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
2146 loc = input_location;
2147 /* Generate __builtin_object_size call. */
2148 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
2149 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
2150 integer_zero_node);
2151 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
2152 GSI_SAME_STMT);
2153 /* If the call above didn't end up being an integer constant, go one
2154 statement back and get the __builtin_object_size stmt. Save it,
2155 we might need it later. */
2156 if (SSA_VAR_P (sizet))
2158 gsi_prev (gsi);
2159 bos_stmt = gsi_stmt (*gsi);
2161 /* Move on to where we were. */
2162 gsi_next (gsi);
2165 else
2166 return;
2168 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
2169 call. */
2170 /* ptr + sizeof (*ptr) - base */
2171 t = fold_build2 (MINUS_EXPR, sizetype,
2172 fold_convert (pointer_sized_int_node, ptr),
2173 fold_convert (pointer_sized_int_node, base_addr));
2174 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
2176 /* Perhaps we can omit the check. */
2177 if (TREE_CODE (t) == INTEGER_CST
2178 && TREE_CODE (sizet) == INTEGER_CST
2179 && tree_int_cst_le (t, sizet))
2180 return;
2182 if (index != NULL_TREE
2183 && TREE_CODE (index) == SSA_NAME
2184 && TREE_CODE (sizet) == INTEGER_CST)
2186 gimple *def = SSA_NAME_DEF_STMT (index);
2187 if (is_gimple_assign (def)
2188 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
2189 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
2191 tree cst = gimple_assign_rhs2 (def);
2192 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
2193 TYPE_SIZE_UNIT (type));
2194 if (tree_int_cst_sgn (cst) >= 0
2195 && tree_int_cst_lt (cst, sz))
2196 return;
2200 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
2201 ubsan_create_edge (bos_stmt);
2203 /* We have to emit the check. */
2204 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
2205 GSI_SAME_STMT);
2206 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
2207 GSI_SAME_STMT);
2208 tree ckind = build_int_cst (unsigned_char_type_node,
2209 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
2210 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
2211 ptr, t, sizet, ckind);
2212 gimple_set_location (g, loc);
2213 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2216 /* Instrument values passed to builtin functions. */
2218 static void
2219 instrument_builtin (gimple_stmt_iterator *gsi)
2221 gimple *stmt = gsi_stmt (*gsi);
2222 location_t loc = gimple_location (stmt);
2223 tree arg;
2224 enum built_in_function fcode
2225 = DECL_FUNCTION_CODE (gimple_call_fndecl (stmt));
2226 int kind = 0;
2227 switch (fcode)
2229 CASE_INT_FN (BUILT_IN_CLZ):
2230 kind = 1;
2231 gcc_fallthrough ();
2232 CASE_INT_FN (BUILT_IN_CTZ):
2233 arg = gimple_call_arg (stmt, 0);
2234 if (!integer_nonzerop (arg))
2236 gimple *g;
2237 if (!is_gimple_val (arg))
2239 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
2240 gimple_set_location (g, loc);
2241 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2242 arg = gimple_assign_lhs (g);
2245 basic_block then_bb, fallthru_bb;
2246 *gsi = create_cond_insert_point (gsi, true, false, true,
2247 &then_bb, &fallthru_bb);
2248 g = gimple_build_cond (EQ_EXPR, arg,
2249 build_zero_cst (TREE_TYPE (arg)),
2250 NULL_TREE, NULL_TREE);
2251 gimple_set_location (g, loc);
2252 gsi_insert_after (gsi, g, GSI_NEW_STMT);
2254 *gsi = gsi_after_labels (then_bb);
2255 if (flag_sanitize_undefined_trap_on_error)
2256 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2257 else
2259 tree t = build_int_cst (unsigned_char_type_node, kind);
2260 tree data = ubsan_create_data ("__ubsan_builtin_data",
2261 1, &loc, NULL_TREE, t, NULL_TREE);
2262 data = build_fold_addr_expr_loc (loc, data);
2263 enum built_in_function bcode
2264 = (flag_sanitize_recover & SANITIZE_BUILTIN)
2265 ? BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN
2266 : BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN_ABORT;
2267 tree fn = builtin_decl_explicit (bcode);
2269 g = gimple_build_call (fn, 1, data);
2271 gimple_set_location (g, loc);
2272 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2273 ubsan_create_edge (g);
2275 *gsi = gsi_for_stmt (stmt);
2276 break;
2277 default:
2278 break;
2282 namespace {
2284 const pass_data pass_data_ubsan =
2286 GIMPLE_PASS, /* type */
2287 "ubsan", /* name */
2288 OPTGROUP_NONE, /* optinfo_flags */
2289 TV_TREE_UBSAN, /* tv_id */
2290 ( PROP_cfg | PROP_ssa ), /* properties_required */
2291 0, /* properties_provided */
2292 0, /* properties_destroyed */
2293 0, /* todo_flags_start */
2294 TODO_update_ssa, /* todo_flags_finish */
2297 class pass_ubsan : public gimple_opt_pass
2299 public:
2300 pass_ubsan (gcc::context *ctxt)
2301 : gimple_opt_pass (pass_data_ubsan, ctxt)
2304 /* opt_pass methods: */
2305 virtual bool gate (function *)
2307 return sanitize_flags_p ((SANITIZE_NULL | SANITIZE_SI_OVERFLOW
2308 | SANITIZE_BOOL | SANITIZE_ENUM
2309 | SANITIZE_ALIGNMENT
2310 | SANITIZE_NONNULL_ATTRIBUTE
2311 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
2312 | SANITIZE_OBJECT_SIZE
2313 | SANITIZE_POINTER_OVERFLOW
2314 | SANITIZE_BUILTIN));
2317 virtual unsigned int execute (function *);
2319 }; // class pass_ubsan
2321 unsigned int
2322 pass_ubsan::execute (function *fun)
2324 basic_block bb;
2325 gimple_stmt_iterator gsi;
2326 unsigned int ret = 0;
2328 initialize_sanitizer_builtins ();
2330 FOR_EACH_BB_FN (bb, fun)
2332 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
2334 gimple *stmt = gsi_stmt (gsi);
2335 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
2337 gsi_next (&gsi);
2338 continue;
2341 if ((sanitize_flags_p (SANITIZE_SI_OVERFLOW, fun->decl))
2342 && is_gimple_assign (stmt))
2343 instrument_si_overflow (gsi);
2345 if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT, fun->decl))
2347 if (gimple_store_p (stmt))
2348 instrument_null (gsi, gimple_get_lhs (stmt), true);
2349 if (gimple_assign_single_p (stmt))
2350 instrument_null (gsi, gimple_assign_rhs1 (stmt), false);
2351 if (is_gimple_call (stmt))
2353 unsigned args_num = gimple_call_num_args (stmt);
2354 for (unsigned i = 0; i < args_num; ++i)
2356 tree arg = gimple_call_arg (stmt, i);
2357 if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2358 continue;
2359 instrument_null (gsi, arg, false);
2364 if (sanitize_flags_p (SANITIZE_BOOL | SANITIZE_ENUM, fun->decl)
2365 && gimple_assign_load_p (stmt))
2367 instrument_bool_enum_load (&gsi);
2368 bb = gimple_bb (stmt);
2371 if (sanitize_flags_p (SANITIZE_NONNULL_ATTRIBUTE, fun->decl)
2372 && is_gimple_call (stmt)
2373 && !gimple_call_internal_p (stmt))
2375 instrument_nonnull_arg (&gsi);
2376 bb = gimple_bb (stmt);
2379 if (sanitize_flags_p (SANITIZE_BUILTIN, fun->decl)
2380 && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
2382 instrument_builtin (&gsi);
2383 bb = gimple_bb (stmt);
2386 if (sanitize_flags_p (SANITIZE_RETURNS_NONNULL_ATTRIBUTE, fun->decl)
2387 && gimple_code (stmt) == GIMPLE_RETURN)
2389 instrument_nonnull_return (&gsi);
2390 bb = gimple_bb (stmt);
2393 if (sanitize_flags_p (SANITIZE_OBJECT_SIZE, fun->decl))
2395 if (gimple_store_p (stmt))
2396 instrument_object_size (&gsi, gimple_get_lhs (stmt), true);
2397 if (gimple_assign_load_p (stmt))
2398 instrument_object_size (&gsi, gimple_assign_rhs1 (stmt),
2399 false);
2400 if (is_gimple_call (stmt))
2402 unsigned args_num = gimple_call_num_args (stmt);
2403 for (unsigned i = 0; i < args_num; ++i)
2405 tree arg = gimple_call_arg (stmt, i);
2406 if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2407 continue;
2408 instrument_object_size (&gsi, arg, false);
2413 if (sanitize_flags_p (SANITIZE_POINTER_OVERFLOW, fun->decl))
2415 if (is_gimple_assign (stmt)
2416 && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
2417 instrument_pointer_overflow (&gsi,
2418 gimple_assign_rhs1 (stmt),
2419 gimple_assign_rhs2 (stmt));
2420 if (gimple_store_p (stmt))
2421 maybe_instrument_pointer_overflow (&gsi,
2422 gimple_get_lhs (stmt));
2423 if (gimple_assign_single_p (stmt))
2424 maybe_instrument_pointer_overflow (&gsi,
2425 gimple_assign_rhs1 (stmt));
2426 if (is_gimple_call (stmt))
2428 unsigned args_num = gimple_call_num_args (stmt);
2429 for (unsigned i = 0; i < args_num; ++i)
2431 tree arg = gimple_call_arg (stmt, i);
2432 if (is_gimple_reg (arg))
2433 continue;
2434 maybe_instrument_pointer_overflow (&gsi, arg);
2439 gsi_next (&gsi);
2441 if (gimple_purge_dead_eh_edges (bb))
2442 ret = TODO_cleanup_cfg;
2444 return ret;
2447 } // anon namespace
2449 gimple_opt_pass *
2450 make_pass_ubsan (gcc::context *ctxt)
2452 return new pass_ubsan (ctxt);
2455 #include "gt-ubsan.h"