[AArch64] PR target/65491: Classify V1TF vectors as AAPCS64 short vectors rather...
[official-gcc.git] / gcc / ubsan.c
blob96536c50881a5429b15ed48ca103038104b44dba
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2015 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 "hash-set.h"
25 #include "machmode.h"
26 #include "vec.h"
27 #include "double-int.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "options.h"
32 #include "wide-int.h"
33 #include "inchash.h"
34 #include "tree.h"
35 #include "fold-const.h"
36 #include "stor-layout.h"
37 #include "stringpool.h"
38 #include "predict.h"
39 #include "dominance.h"
40 #include "cfg.h"
41 #include "cfganal.h"
42 #include "basic-block.h"
43 #include "hash-map.h"
44 #include "is-a.h"
45 #include "plugin-api.h"
46 #include "tm.h"
47 #include "hard-reg-set.h"
48 #include "function.h"
49 #include "ipa-ref.h"
50 #include "cgraph.h"
51 #include "tree-pass.h"
52 #include "tree-ssa-alias.h"
53 #include "tree-pretty-print.h"
54 #include "internal-fn.h"
55 #include "gimple-expr.h"
56 #include "gimple.h"
57 #include "gimple-iterator.h"
58 #include "gimple-ssa.h"
59 #include "gimple-walk.h"
60 #include "output.h"
61 #include "tm_p.h"
62 #include "toplev.h"
63 #include "cfgloop.h"
64 #include "ubsan.h"
65 #include "c-family/c-common.h"
66 #include "rtl.h"
67 #include "hashtab.h"
68 #include "flags.h"
69 #include "statistics.h"
70 #include "real.h"
71 #include "fixed-value.h"
72 #include "insn-config.h"
73 #include "expmed.h"
74 #include "dojump.h"
75 #include "explow.h"
76 #include "calls.h"
77 #include "emit-rtl.h"
78 #include "varasm.h"
79 #include "stmt.h"
80 #include "expr.h"
81 #include "tree-ssanames.h"
82 #include "asan.h"
83 #include "gimplify-me.h"
84 #include "intl.h"
85 #include "realmpfr.h"
86 #include "dfp.h"
87 #include "builtins.h"
88 #include "tree-object-size.h"
89 #include "tree-eh.h"
90 #include "tree-cfg.h"
92 /* Map from a tree to a VAR_DECL tree. */
94 struct GTY((for_user)) tree_type_map {
95 struct tree_map_base type;
96 tree decl;
99 struct tree_type_map_cache_hasher : ggc_cache_hasher<tree_type_map *>
101 static inline hashval_t
102 hash (tree_type_map *t)
104 return TYPE_UID (t->type.from);
107 static inline bool
108 equal (tree_type_map *a, tree_type_map *b)
110 return a->type.from == b->type.from;
113 static void
114 handle_cache_entry (tree_type_map *&m)
116 extern void gt_ggc_mx (tree_type_map *&);
117 if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
118 return;
119 else if (ggc_marked_p (m->type.from))
120 gt_ggc_mx (m);
121 else
122 m = static_cast<tree_type_map *> (HTAB_DELETED_ENTRY);
126 static GTY ((cache))
127 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
129 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
131 static tree
132 decl_for_type_lookup (tree type)
134 /* If the hash table is not initialized yet, create it now. */
135 if (decl_tree_for_type == NULL)
137 decl_tree_for_type
138 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
139 /* That also means we don't have to bother with the lookup. */
140 return NULL_TREE;
143 struct tree_type_map *h, in;
144 in.type.from = type;
146 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
147 return h ? h->decl : NULL_TREE;
150 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
152 static void
153 decl_for_type_insert (tree type, tree decl)
155 struct tree_type_map *h;
157 h = ggc_alloc<tree_type_map> ();
158 h->type.from = type;
159 h->decl = decl;
160 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
163 /* Helper routine, which encodes a value in the pointer_sized_int_node.
164 Arguments with precision <= POINTER_SIZE are passed directly,
165 the rest is passed by reference. T is a value we are to encode.
166 IN_EXPAND_P is true if this function is called during expansion. */
168 tree
169 ubsan_encode_value (tree t, bool in_expand_p)
171 tree type = TREE_TYPE (t);
172 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
173 if (bitsize <= POINTER_SIZE)
174 switch (TREE_CODE (type))
176 case BOOLEAN_TYPE:
177 case ENUMERAL_TYPE:
178 case INTEGER_TYPE:
179 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
180 case REAL_TYPE:
182 tree itype = build_nonstandard_integer_type (bitsize, true);
183 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
184 return fold_convert (pointer_sized_int_node, t);
186 default:
187 gcc_unreachable ();
189 else
191 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
193 /* The reason for this is that we don't want to pessimize
194 code by making vars unnecessarily addressable. */
195 tree var = create_tmp_var (type);
196 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
197 if (in_expand_p)
199 rtx mem
200 = assign_stack_temp_for_type (TYPE_MODE (type),
201 GET_MODE_SIZE (TYPE_MODE (type)),
202 type);
203 SET_DECL_RTL (var, mem);
204 expand_assignment (var, t, false);
205 return build_fold_addr_expr (var);
207 t = build_fold_addr_expr (var);
208 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
210 else
211 return build_fold_addr_expr (t);
215 /* Cached ubsan_get_type_descriptor_type () return value. */
216 static GTY(()) tree ubsan_type_descriptor_type;
218 /* Build
219 struct __ubsan_type_descriptor
221 unsigned short __typekind;
222 unsigned short __typeinfo;
223 char __typename[];
225 type. */
227 static tree
228 ubsan_get_type_descriptor_type (void)
230 static const char *field_names[3]
231 = { "__typekind", "__typeinfo", "__typename" };
232 tree fields[3], ret;
234 if (ubsan_type_descriptor_type)
235 return ubsan_type_descriptor_type;
237 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
238 tree flex_arr_type = build_array_type (char_type_node, itype);
240 ret = make_node (RECORD_TYPE);
241 for (int i = 0; i < 3; i++)
243 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
244 get_identifier (field_names[i]),
245 (i == 2) ? flex_arr_type
246 : short_unsigned_type_node);
247 DECL_CONTEXT (fields[i]) = ret;
248 if (i)
249 DECL_CHAIN (fields[i - 1]) = fields[i];
251 tree type_decl = build_decl (input_location, TYPE_DECL,
252 get_identifier ("__ubsan_type_descriptor"),
253 ret);
254 DECL_IGNORED_P (type_decl) = 1;
255 DECL_ARTIFICIAL (type_decl) = 1;
256 TYPE_FIELDS (ret) = fields[0];
257 TYPE_NAME (ret) = type_decl;
258 TYPE_STUB_DECL (ret) = type_decl;
259 layout_type (ret);
260 ubsan_type_descriptor_type = ret;
261 return ret;
264 /* Cached ubsan_get_source_location_type () return value. */
265 static GTY(()) tree ubsan_source_location_type;
267 /* Build
268 struct __ubsan_source_location
270 const char *__filename;
271 unsigned int __line;
272 unsigned int __column;
274 type. */
276 tree
277 ubsan_get_source_location_type (void)
279 static const char *field_names[3]
280 = { "__filename", "__line", "__column" };
281 tree fields[3], ret;
282 if (ubsan_source_location_type)
283 return ubsan_source_location_type;
285 tree const_char_type = build_qualified_type (char_type_node,
286 TYPE_QUAL_CONST);
288 ret = make_node (RECORD_TYPE);
289 for (int i = 0; i < 3; i++)
291 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
292 get_identifier (field_names[i]),
293 (i == 0) ? build_pointer_type (const_char_type)
294 : unsigned_type_node);
295 DECL_CONTEXT (fields[i]) = ret;
296 if (i)
297 DECL_CHAIN (fields[i - 1]) = fields[i];
299 tree type_decl = build_decl (input_location, TYPE_DECL,
300 get_identifier ("__ubsan_source_location"),
301 ret);
302 DECL_IGNORED_P (type_decl) = 1;
303 DECL_ARTIFICIAL (type_decl) = 1;
304 TYPE_FIELDS (ret) = fields[0];
305 TYPE_NAME (ret) = type_decl;
306 TYPE_STUB_DECL (ret) = type_decl;
307 layout_type (ret);
308 ubsan_source_location_type = ret;
309 return ret;
312 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
313 type with its fields filled from a location_t LOC. */
315 static tree
316 ubsan_source_location (location_t loc)
318 expanded_location xloc;
319 tree type = ubsan_get_source_location_type ();
321 xloc = expand_location (loc);
322 tree str;
323 if (xloc.file == NULL)
325 str = build_int_cst (ptr_type_node, 0);
326 xloc.line = 0;
327 xloc.column = 0;
329 else
331 /* Fill in the values from LOC. */
332 size_t len = strlen (xloc.file) + 1;
333 str = build_string (len, xloc.file);
334 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
335 TREE_READONLY (str) = 1;
336 TREE_STATIC (str) = 1;
337 str = build_fold_addr_expr (str);
339 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
340 build_int_cst (unsigned_type_node,
341 xloc.line), NULL_TREE,
342 build_int_cst (unsigned_type_node,
343 xloc.column));
344 TREE_CONSTANT (ctor) = 1;
345 TREE_STATIC (ctor) = 1;
347 return ctor;
350 /* This routine returns a magic number for TYPE. */
352 static unsigned short
353 get_ubsan_type_info_for_type (tree type)
355 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
356 if (TREE_CODE (type) == REAL_TYPE)
357 return tree_to_uhwi (TYPE_SIZE (type));
358 else if (INTEGRAL_TYPE_P (type))
360 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
361 gcc_assert (prec != -1);
362 return (prec << 1) | !TYPE_UNSIGNED (type);
364 else
365 return 0;
368 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
369 descriptor. It first looks into the hash table; if not found,
370 create the VAR_DECL, put it into the hash table and return the
371 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
372 an enum controlling how we want to print the type. */
374 tree
375 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
377 /* See through any typedefs. */
378 type = TYPE_MAIN_VARIANT (type);
380 tree decl = decl_for_type_lookup (type);
381 /* It is possible that some of the earlier created DECLs were found
382 unused, in that case they weren't emitted and varpool_node::get
383 returns NULL node on them. But now we really need them. Thus,
384 renew them here. */
385 if (decl != NULL_TREE && varpool_node::get (decl))
386 return build_fold_addr_expr (decl);
388 tree dtype = ubsan_get_type_descriptor_type ();
389 tree type2 = type;
390 const char *tname = NULL;
391 pretty_printer pretty_name;
392 unsigned char deref_depth = 0;
393 unsigned short tkind, tinfo;
395 /* Get the name of the type, or the name of the pointer type. */
396 if (pstyle == UBSAN_PRINT_POINTER)
398 gcc_assert (POINTER_TYPE_P (type));
399 type2 = TREE_TYPE (type);
401 /* Remove any '*' operators from TYPE. */
402 while (POINTER_TYPE_P (type2))
403 deref_depth++, type2 = TREE_TYPE (type2);
405 if (TREE_CODE (type2) == METHOD_TYPE)
406 type2 = TYPE_METHOD_BASETYPE (type2);
409 /* If an array, get its type. */
410 type2 = strip_array_types (type2);
412 if (pstyle == UBSAN_PRINT_ARRAY)
414 while (POINTER_TYPE_P (type2))
415 deref_depth++, type2 = TREE_TYPE (type2);
418 if (TYPE_NAME (type2) != NULL)
420 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
421 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
422 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
423 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
426 if (tname == NULL)
427 /* We weren't able to determine the type name. */
428 tname = "<unknown>";
430 if (pstyle == UBSAN_PRINT_POINTER)
432 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
433 TYPE_VOLATILE (type2) ? "volatile " : "",
434 TYPE_READONLY (type2) ? "const " : "",
435 TYPE_RESTRICT (type2) ? "restrict " : "",
436 TYPE_ATOMIC (type2) ? "_Atomic " : "",
437 TREE_CODE (type2) == RECORD_TYPE
438 ? "struct "
439 : TREE_CODE (type2) == UNION_TYPE
440 ? "union " : "", tname,
441 deref_depth == 0 ? "" : " ");
442 while (deref_depth-- > 0)
443 pp_star (&pretty_name);
444 pp_quote (&pretty_name);
446 else if (pstyle == UBSAN_PRINT_ARRAY)
448 /* Pretty print the array dimensions. */
449 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
450 tree t = type;
451 pp_printf (&pretty_name, "'%s ", tname);
452 while (deref_depth-- > 0)
453 pp_star (&pretty_name);
454 while (TREE_CODE (t) == ARRAY_TYPE)
456 pp_left_bracket (&pretty_name);
457 tree dom = TYPE_DOMAIN (t);
458 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
460 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
461 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
462 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
463 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
464 else
465 pp_wide_int (&pretty_name,
466 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
467 TYPE_SIGN (TREE_TYPE (dom)));
469 else
470 /* ??? We can't determine the variable name; print VLA unspec. */
471 pp_star (&pretty_name);
472 pp_right_bracket (&pretty_name);
473 t = TREE_TYPE (t);
475 pp_quote (&pretty_name);
477 /* Save the tree with stripped types. */
478 type = t;
480 else
481 pp_printf (&pretty_name, "'%s'", tname);
483 switch (TREE_CODE (type))
485 case BOOLEAN_TYPE:
486 case ENUMERAL_TYPE:
487 case INTEGER_TYPE:
488 tkind = 0x0000;
489 break;
490 case REAL_TYPE:
491 /* FIXME: libubsan right now only supports float, double and
492 long double type formats. */
493 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
494 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
495 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
496 tkind = 0x0001;
497 else
498 tkind = 0xffff;
499 break;
500 default:
501 tkind = 0xffff;
502 break;
504 tinfo = get_ubsan_type_info_for_type (type);
506 /* Create a new VAR_DECL of type descriptor. */
507 const char *tmp = pp_formatted_text (&pretty_name);
508 size_t len = strlen (tmp) + 1;
509 tree str = build_string (len, tmp);
510 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
511 TREE_READONLY (str) = 1;
512 TREE_STATIC (str) = 1;
514 char tmp_name[32];
515 static unsigned int type_var_id_num;
516 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
517 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
518 dtype);
519 TREE_STATIC (decl) = 1;
520 TREE_PUBLIC (decl) = 0;
521 DECL_ARTIFICIAL (decl) = 1;
522 DECL_IGNORED_P (decl) = 1;
523 DECL_EXTERNAL (decl) = 0;
524 DECL_SIZE (decl)
525 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
526 DECL_SIZE_UNIT (decl)
527 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
528 TYPE_SIZE_UNIT (TREE_TYPE (str)));
530 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
531 build_int_cst (short_unsigned_type_node,
532 tkind), NULL_TREE,
533 build_int_cst (short_unsigned_type_node,
534 tinfo), NULL_TREE, str);
535 TREE_CONSTANT (ctor) = 1;
536 TREE_STATIC (ctor) = 1;
537 DECL_INITIAL (decl) = ctor;
538 varpool_node::finalize_decl (decl);
540 /* Save the VAR_DECL into the hash table. */
541 decl_for_type_insert (type, decl);
543 return build_fold_addr_expr (decl);
546 /* Create a structure for the ubsan library. NAME is a name of the new
547 structure. LOCCNT is number of locations, PLOC points to array of
548 locations. The arguments in ... are of __ubsan_type_descriptor type
549 and there are at most two of them, followed by NULL_TREE, followed
550 by optional extra arguments and another NULL_TREE. */
552 tree
553 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
555 va_list args;
556 tree ret, t;
557 tree fields[6];
558 vec<tree, va_gc> *saved_args = NULL;
559 size_t i = 0;
560 int j;
562 /* Firstly, create a pointer to type descriptor type. */
563 tree td_type = ubsan_get_type_descriptor_type ();
564 td_type = build_pointer_type (td_type);
566 /* Create the structure type. */
567 ret = make_node (RECORD_TYPE);
568 for (j = 0; j < loccnt; j++)
570 gcc_checking_assert (i < 2);
571 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
572 ubsan_get_source_location_type ());
573 DECL_CONTEXT (fields[i]) = ret;
574 if (i)
575 DECL_CHAIN (fields[i - 1]) = fields[i];
576 i++;
579 va_start (args, ploc);
580 for (t = va_arg (args, tree); t != NULL_TREE;
581 i++, t = va_arg (args, tree))
583 gcc_checking_assert (i < 4);
584 /* Save the tree arguments for later use. */
585 vec_safe_push (saved_args, t);
586 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
587 td_type);
588 DECL_CONTEXT (fields[i]) = ret;
589 if (i)
590 DECL_CHAIN (fields[i - 1]) = fields[i];
593 for (t = va_arg (args, tree); t != NULL_TREE;
594 i++, t = va_arg (args, tree))
596 gcc_checking_assert (i < 6);
597 /* Save the tree arguments for later use. */
598 vec_safe_push (saved_args, t);
599 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
600 TREE_TYPE (t));
601 DECL_CONTEXT (fields[i]) = ret;
602 if (i)
603 DECL_CHAIN (fields[i - 1]) = fields[i];
605 va_end (args);
607 tree type_decl = build_decl (input_location, TYPE_DECL,
608 get_identifier (name), ret);
609 DECL_IGNORED_P (type_decl) = 1;
610 DECL_ARTIFICIAL (type_decl) = 1;
611 TYPE_FIELDS (ret) = fields[0];
612 TYPE_NAME (ret) = type_decl;
613 TYPE_STUB_DECL (ret) = type_decl;
614 layout_type (ret);
616 /* Now, fill in the type. */
617 char tmp_name[32];
618 static unsigned int ubsan_var_id_num;
619 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
620 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
621 ret);
622 TREE_STATIC (var) = 1;
623 TREE_PUBLIC (var) = 0;
624 DECL_ARTIFICIAL (var) = 1;
625 DECL_IGNORED_P (var) = 1;
626 DECL_EXTERNAL (var) = 0;
628 vec<constructor_elt, va_gc> *v;
629 vec_alloc (v, i);
630 tree ctor = build_constructor (ret, v);
632 /* If desirable, set the __ubsan_source_location element. */
633 for (j = 0; j < loccnt; j++)
635 location_t loc = LOCATION_LOCUS (ploc[j]);
636 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
639 size_t nelts = vec_safe_length (saved_args);
640 for (i = 0; i < nelts; i++)
642 t = (*saved_args)[i];
643 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
646 TREE_CONSTANT (ctor) = 1;
647 TREE_STATIC (ctor) = 1;
648 DECL_INITIAL (var) = ctor;
649 varpool_node::finalize_decl (var);
651 return var;
654 /* Instrument the __builtin_unreachable call. We just call the libubsan
655 routine instead. */
657 bool
658 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
660 gimple g;
661 location_t loc = gimple_location (gsi_stmt (*gsi));
663 if (flag_sanitize_undefined_trap_on_error)
664 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
665 else
667 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
668 NULL_TREE, NULL_TREE);
669 data = build_fold_addr_expr_loc (loc, data);
670 tree fn
671 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
672 g = gimple_build_call (fn, 1, data);
674 gimple_set_location (g, loc);
675 gsi_replace (gsi, g, false);
676 return false;
679 /* Return true if T is a call to a libubsan routine. */
681 bool
682 is_ubsan_builtin_p (tree t)
684 return TREE_CODE (t) == FUNCTION_DECL
685 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
686 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
687 "__builtin___ubsan_", 18) == 0;
690 /* Create a callgraph edge for statement STMT. */
692 static void
693 ubsan_create_edge (gimple stmt)
695 gcall *call_stmt = dyn_cast <gcall *> (stmt);
696 basic_block bb = gimple_bb (stmt);
697 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
698 cgraph_node *node = cgraph_node::get (current_function_decl);
699 tree decl = gimple_call_fndecl (call_stmt);
700 if (decl)
701 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
702 freq);
705 /* Expand the UBSAN_BOUNDS special builtin function. */
707 bool
708 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
710 gimple stmt = gsi_stmt (*gsi);
711 location_t loc = gimple_location (stmt);
712 gcc_assert (gimple_call_num_args (stmt) == 3);
714 /* Pick up the arguments of the UBSAN_BOUNDS call. */
715 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
716 tree index = gimple_call_arg (stmt, 1);
717 tree orig_index_type = TREE_TYPE (index);
718 tree bound = gimple_call_arg (stmt, 2);
720 gimple_stmt_iterator gsi_orig = *gsi;
722 /* Create condition "if (index > bound)". */
723 basic_block then_bb, fallthru_bb;
724 gimple_stmt_iterator cond_insert_point
725 = create_cond_insert_point (gsi, false, false, true,
726 &then_bb, &fallthru_bb);
727 index = fold_convert (TREE_TYPE (bound), index);
728 index = force_gimple_operand_gsi (&cond_insert_point, index,
729 true, NULL_TREE,
730 false, GSI_NEW_STMT);
731 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
732 gimple_set_location (g, loc);
733 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
735 /* Generate __ubsan_handle_out_of_bounds call. */
736 *gsi = gsi_after_labels (then_bb);
737 if (flag_sanitize_undefined_trap_on_error)
738 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
739 else
741 tree data
742 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
743 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
744 ubsan_type_descriptor (orig_index_type),
745 NULL_TREE, NULL_TREE);
746 data = build_fold_addr_expr_loc (loc, data);
747 enum built_in_function bcode
748 = (flag_sanitize_recover & SANITIZE_BOUNDS)
749 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
750 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
751 tree fn = builtin_decl_explicit (bcode);
752 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
753 true, NULL_TREE, true,
754 GSI_SAME_STMT);
755 g = gimple_build_call (fn, 2, data, val);
757 gimple_set_location (g, loc);
758 gsi_insert_before (gsi, g, GSI_SAME_STMT);
760 /* Get rid of the UBSAN_BOUNDS call from the IR. */
761 unlink_stmt_vdef (stmt);
762 gsi_remove (&gsi_orig, true);
764 /* Point GSI to next logical statement. */
765 *gsi = gsi_start_bb (fallthru_bb);
766 return true;
769 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
770 argument which is a constant, because the middle-end treats pointer
771 conversions as useless and therefore the type of the first argument
772 could be changed to any other pointer type. */
774 bool
775 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
777 gimple_stmt_iterator gsi = *gsip;
778 gimple stmt = gsi_stmt (gsi);
779 location_t loc = gimple_location (stmt);
780 gcc_assert (gimple_call_num_args (stmt) == 3);
781 tree ptr = gimple_call_arg (stmt, 0);
782 tree ckind = gimple_call_arg (stmt, 1);
783 tree align = gimple_call_arg (stmt, 2);
784 tree check_align = NULL_TREE;
785 bool check_null;
787 basic_block cur_bb = gsi_bb (gsi);
789 gimple g;
790 if (!integer_zerop (align))
792 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
793 if (compare_tree_int (align, ptralign) == 1)
795 check_align = make_ssa_name (pointer_sized_int_node);
796 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
797 gimple_set_location (g, loc);
798 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
801 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
803 if (check_align == NULL_TREE && !check_null)
805 gsi_remove (gsip, true);
806 /* Unlink the UBSAN_NULLs vops before replacing it. */
807 unlink_stmt_vdef (stmt);
808 return true;
811 /* Split the original block holding the pointer dereference. */
812 edge e = split_block (cur_bb, stmt);
814 /* Get a hold on the 'condition block', the 'then block' and the
815 'else block'. */
816 basic_block cond_bb = e->src;
817 basic_block fallthru_bb = e->dest;
818 basic_block then_bb = create_empty_bb (cond_bb);
819 add_bb_to_loop (then_bb, cond_bb->loop_father);
820 loops_state_set (LOOPS_NEED_FIXUP);
822 /* Make an edge coming from the 'cond block' into the 'then block';
823 this edge is unlikely taken, so set up the probability accordingly. */
824 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
825 e->probability = PROB_VERY_UNLIKELY;
827 /* Connect 'then block' with the 'else block'. This is needed
828 as the ubsan routines we call in the 'then block' are not noreturn.
829 The 'then block' only has one outcoming edge. */
830 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
832 /* Set up the fallthrough basic block. */
833 e = find_edge (cond_bb, fallthru_bb);
834 e->flags = EDGE_FALSE_VALUE;
835 e->count = cond_bb->count;
836 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
838 /* Update dominance info for the newly created then_bb; note that
839 fallthru_bb's dominance info has already been updated by
840 split_block. */
841 if (dom_info_available_p (CDI_DOMINATORS))
842 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
844 /* Put the ubsan builtin call into the newly created BB. */
845 if (flag_sanitize_undefined_trap_on_error)
846 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
847 else
849 enum built_in_function bcode
850 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
851 | (check_null ? SANITIZE_NULL : 0)))
852 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
853 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
854 tree fn = builtin_decl_implicit (bcode);
855 tree data
856 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
857 ubsan_type_descriptor (TREE_TYPE (ckind),
858 UBSAN_PRINT_POINTER),
859 NULL_TREE,
860 align,
861 fold_convert (unsigned_char_type_node, ckind),
862 NULL_TREE);
863 data = build_fold_addr_expr_loc (loc, data);
864 g = gimple_build_call (fn, 2, data,
865 check_align ? check_align
866 : build_zero_cst (pointer_sized_int_node));
868 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
869 gimple_set_location (g, loc);
870 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
872 /* Unlink the UBSAN_NULLs vops before replacing it. */
873 unlink_stmt_vdef (stmt);
875 if (check_null)
877 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
878 NULL_TREE, NULL_TREE);
879 gimple_set_location (g, loc);
881 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
882 gsi_replace (&gsi, g, false);
883 stmt = g;
886 if (check_align)
888 if (check_null)
890 /* Split the block with the condition again. */
891 e = split_block (cond_bb, stmt);
892 basic_block cond1_bb = e->src;
893 basic_block cond2_bb = e->dest;
895 /* Make an edge coming from the 'cond1 block' into the 'then block';
896 this edge is unlikely taken, so set up the probability
897 accordingly. */
898 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
899 e->probability = PROB_VERY_UNLIKELY;
901 /* Set up the fallthrough basic block. */
902 e = find_edge (cond1_bb, cond2_bb);
903 e->flags = EDGE_FALSE_VALUE;
904 e->count = cond1_bb->count;
905 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
907 /* Update dominance info. */
908 if (dom_info_available_p (CDI_DOMINATORS))
910 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
911 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
914 gsi2 = gsi_start_bb (cond2_bb);
917 tree mask = build_int_cst (pointer_sized_int_node,
918 tree_to_uhwi (align) - 1);
919 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
920 BIT_AND_EXPR, check_align, mask);
921 gimple_set_location (g, loc);
922 if (check_null)
923 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
924 else
925 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
927 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
928 build_int_cst (pointer_sized_int_node, 0),
929 NULL_TREE, NULL_TREE);
930 gimple_set_location (g, loc);
931 if (check_null)
932 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
933 else
934 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
935 gsi_replace (&gsi, g, false);
937 return false;
940 #define OBJSZ_MAX_OFFSET (1024 * 16)
942 /* Expand UBSAN_OBJECT_SIZE internal call. */
944 bool
945 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
947 gimple stmt = gsi_stmt (*gsi);
948 location_t loc = gimple_location (stmt);
949 gcc_assert (gimple_call_num_args (stmt) == 4);
951 tree ptr = gimple_call_arg (stmt, 0);
952 tree offset = gimple_call_arg (stmt, 1);
953 tree size = gimple_call_arg (stmt, 2);
954 tree ckind = gimple_call_arg (stmt, 3);
955 gimple_stmt_iterator gsi_orig = *gsi;
956 gimple g;
958 /* See if we can discard the check. */
959 if (TREE_CODE (size) != INTEGER_CST
960 || integer_all_onesp (size))
961 /* Yes, __builtin_object_size couldn't determine the
962 object size. */;
963 else if (TREE_CODE (offset) == INTEGER_CST
964 && wi::ges_p (wi::to_widest (offset), -OBJSZ_MAX_OFFSET)
965 && wi::les_p (wi::to_widest (offset), -1))
966 /* The offset is in range [-16K, -1]. */;
967 else
969 /* if (offset > objsize) */
970 basic_block then_bb, fallthru_bb;
971 gimple_stmt_iterator cond_insert_point
972 = create_cond_insert_point (gsi, false, false, true,
973 &then_bb, &fallthru_bb);
974 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
975 gimple_set_location (g, loc);
976 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
978 /* If the offset is small enough, we don't need the second
979 run-time check. */
980 if (TREE_CODE (offset) == INTEGER_CST
981 && wi::ges_p (wi::to_widest (offset), 0)
982 && wi::les_p (wi::to_widest (offset), OBJSZ_MAX_OFFSET))
983 *gsi = gsi_after_labels (then_bb);
984 else
986 /* Don't issue run-time error if (ptr > ptr + offset). That
987 may happen when computing a POINTER_PLUS_EXPR. */
988 basic_block then2_bb, fallthru2_bb;
990 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
991 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
992 true, &then2_bb,
993 &fallthru2_bb);
994 /* Convert the pointer to an integer type. */
995 tree p = make_ssa_name (pointer_sized_int_node);
996 g = gimple_build_assign (p, NOP_EXPR, ptr);
997 gimple_set_location (g, loc);
998 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
999 p = gimple_assign_lhs (g);
1000 /* Compute ptr + offset. */
1001 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1002 PLUS_EXPR, p, offset);
1003 gimple_set_location (g, loc);
1004 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1005 /* Now build the conditional and put it into the IR. */
1006 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
1007 NULL_TREE, NULL_TREE);
1008 gimple_set_location (g, loc);
1009 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1010 *gsi = gsi_after_labels (then2_bb);
1013 /* Generate __ubsan_handle_type_mismatch call. */
1014 if (flag_sanitize_undefined_trap_on_error)
1015 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1016 else
1018 tree data
1019 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
1020 ubsan_type_descriptor (TREE_TYPE (ptr),
1021 UBSAN_PRINT_POINTER),
1022 NULL_TREE,
1023 build_zero_cst (pointer_sized_int_node),
1024 ckind,
1025 NULL_TREE);
1026 data = build_fold_addr_expr_loc (loc, data);
1027 enum built_in_function bcode
1028 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1029 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1030 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
1031 tree p = make_ssa_name (pointer_sized_int_node);
1032 g = gimple_build_assign (p, NOP_EXPR, ptr);
1033 gimple_set_location (g, loc);
1034 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1035 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1037 gimple_set_location (g, loc);
1038 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1040 /* Point GSI to next logical statement. */
1041 *gsi = gsi_start_bb (fallthru_bb);
1043 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1044 unlink_stmt_vdef (stmt);
1045 gsi_remove (&gsi_orig, true);
1046 return true;
1049 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1050 unlink_stmt_vdef (stmt);
1051 gsi_remove (gsi, true);
1052 return true;
1055 /* Cached __ubsan_vptr_type_cache decl. */
1056 static GTY(()) tree ubsan_vptr_type_cache_decl;
1058 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1059 argument which is a constant, because the middle-end treats pointer
1060 conversions as useless and therefore the type of the first argument
1061 could be changed to any other pointer type. */
1063 bool
1064 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1066 gimple_stmt_iterator gsi = *gsip;
1067 gimple stmt = gsi_stmt (gsi);
1068 location_t loc = gimple_location (stmt);
1069 gcc_assert (gimple_call_num_args (stmt) == 5);
1070 tree op = gimple_call_arg (stmt, 0);
1071 tree vptr = gimple_call_arg (stmt, 1);
1072 tree str_hash = gimple_call_arg (stmt, 2);
1073 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1074 tree ckind_tree = gimple_call_arg (stmt, 4);
1075 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1076 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1077 gimple g;
1078 basic_block fallthru_bb = NULL;
1080 if (ckind == UBSAN_DOWNCAST_POINTER)
1082 /* Guard everything with if (op != NULL) { ... }. */
1083 basic_block then_bb;
1084 gimple_stmt_iterator cond_insert_point
1085 = create_cond_insert_point (gsip, false, false, true,
1086 &then_bb, &fallthru_bb);
1087 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1088 NULL_TREE, NULL_TREE);
1089 gimple_set_location (g, loc);
1090 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1091 *gsip = gsi_after_labels (then_bb);
1092 gsi_remove (&gsi, false);
1093 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1094 gsi = *gsip;
1097 tree htype = TREE_TYPE (str_hash);
1098 tree cst = wide_int_to_tree (htype,
1099 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1100 | 0xeb382d69, 64));
1101 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1102 vptr, str_hash);
1103 gimple_set_location (g, loc);
1104 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1105 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1106 gimple_assign_lhs (g), cst);
1107 gimple_set_location (g, loc);
1108 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1109 tree t1 = gimple_assign_lhs (g);
1110 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1111 t1, build_int_cst (integer_type_node, 47));
1112 gimple_set_location (g, loc);
1113 tree t2 = gimple_assign_lhs (g);
1114 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1115 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1116 vptr, t1);
1117 gimple_set_location (g, loc);
1118 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1119 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1120 t2, gimple_assign_lhs (g));
1121 gimple_set_location (g, loc);
1122 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1123 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1124 gimple_assign_lhs (g), cst);
1125 gimple_set_location (g, loc);
1126 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1127 tree t3 = gimple_assign_lhs (g);
1128 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1129 t3, build_int_cst (integer_type_node, 47));
1130 gimple_set_location (g, loc);
1131 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1132 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1133 t3, gimple_assign_lhs (g));
1134 gimple_set_location (g, loc);
1135 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1136 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1137 gimple_assign_lhs (g), cst);
1138 gimple_set_location (g, loc);
1139 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1140 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1142 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1143 NOP_EXPR, gimple_assign_lhs (g));
1144 gimple_set_location (g, loc);
1145 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1147 tree hash = gimple_assign_lhs (g);
1149 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1151 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1152 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1153 get_identifier ("__ubsan_vptr_type_cache"),
1154 atype);
1155 DECL_ARTIFICIAL (array) = 1;
1156 DECL_IGNORED_P (array) = 1;
1157 TREE_PUBLIC (array) = 1;
1158 TREE_STATIC (array) = 1;
1159 DECL_EXTERNAL (array) = 1;
1160 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1161 DECL_VISIBILITY_SPECIFIED (array) = 1;
1162 varpool_node::finalize_decl (array);
1163 ubsan_vptr_type_cache_decl = array;
1166 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1167 BIT_AND_EXPR, hash,
1168 build_int_cst (pointer_sized_int_node, 127));
1169 gimple_set_location (g, loc);
1170 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1172 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1173 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1174 NULL_TREE, NULL_TREE);
1175 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1176 ARRAY_REF, c);
1177 gimple_set_location (g, loc);
1178 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1180 basic_block then_bb, fallthru2_bb;
1181 gimple_stmt_iterator cond_insert_point
1182 = create_cond_insert_point (gsip, false, false, true,
1183 &then_bb, &fallthru2_bb);
1184 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1185 NULL_TREE, NULL_TREE);
1186 gimple_set_location (g, loc);
1187 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1188 *gsip = gsi_after_labels (then_bb);
1189 if (fallthru_bb == NULL)
1190 fallthru_bb = fallthru2_bb;
1192 tree data
1193 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1194 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1195 build_int_cst (unsigned_char_type_node, ckind),
1196 NULL_TREE);
1197 data = build_fold_addr_expr_loc (loc, data);
1198 enum built_in_function bcode
1199 = (flag_sanitize_recover & SANITIZE_VPTR)
1200 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1201 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1203 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1204 gimple_set_location (g, loc);
1205 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1207 /* Point GSI to next logical statement. */
1208 *gsip = gsi_start_bb (fallthru_bb);
1210 /* Get rid of the UBSAN_VPTR call from the IR. */
1211 unlink_stmt_vdef (stmt);
1212 gsi_remove (&gsi, true);
1213 return true;
1216 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1217 whether the pointer is on the left hand side of the assignment. */
1219 static void
1220 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1221 bool is_lhs)
1223 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1224 unsigned int align = 0;
1225 if (flag_sanitize & SANITIZE_ALIGNMENT)
1227 align = min_align_of_type (TREE_TYPE (base));
1228 if (align <= 1)
1229 align = 0;
1231 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1232 return;
1233 tree t = TREE_OPERAND (base, 0);
1234 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1235 return;
1236 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1237 ikind = UBSAN_MEMBER_ACCESS;
1238 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1239 tree alignt = build_int_cst (pointer_sized_int_node, align);
1240 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1241 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1242 gsi_insert_before (iter, g, GSI_SAME_STMT);
1245 /* Perform the pointer instrumentation. */
1247 static void
1248 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1250 gimple stmt = gsi_stmt (gsi);
1251 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1252 tree base = get_base_address (t);
1253 const enum tree_code code = TREE_CODE (base);
1254 if (code == MEM_REF
1255 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1256 instrument_mem_ref (t, base, &gsi, is_lhs);
1259 /* Build an ubsan builtin call for the signed-integer-overflow
1260 sanitization. CODE says what kind of builtin are we building,
1261 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1262 are operands of the binary operation. */
1264 tree
1265 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1266 tree op0, tree op1)
1268 if (flag_sanitize_undefined_trap_on_error)
1269 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1271 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1272 ubsan_type_descriptor (lhstype), NULL_TREE,
1273 NULL_TREE);
1274 enum built_in_function fn_code;
1276 switch (code)
1278 case PLUS_EXPR:
1279 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1280 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1281 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1282 break;
1283 case MINUS_EXPR:
1284 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1285 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1286 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1287 break;
1288 case MULT_EXPR:
1289 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1290 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1291 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1292 break;
1293 case NEGATE_EXPR:
1294 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1295 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1296 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1297 break;
1298 default:
1299 gcc_unreachable ();
1301 tree fn = builtin_decl_explicit (fn_code);
1302 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1303 build_fold_addr_expr_loc (loc, data),
1304 ubsan_encode_value (op0, true),
1305 op1 ? ubsan_encode_value (op1, true)
1306 : NULL_TREE);
1309 /* Perform the signed integer instrumentation. GSI is the iterator
1310 pointing at statement we are trying to instrument. */
1312 static void
1313 instrument_si_overflow (gimple_stmt_iterator gsi)
1315 gimple stmt = gsi_stmt (gsi);
1316 tree_code code = gimple_assign_rhs_code (stmt);
1317 tree lhs = gimple_assign_lhs (stmt);
1318 tree lhstype = TREE_TYPE (lhs);
1319 tree a, b;
1320 gimple g;
1322 /* If this is not a signed operation, don't instrument anything here.
1323 Also punt on bit-fields. */
1324 if (!INTEGRAL_TYPE_P (lhstype)
1325 || TYPE_OVERFLOW_WRAPS (lhstype)
1326 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1327 return;
1329 switch (code)
1331 case MINUS_EXPR:
1332 case PLUS_EXPR:
1333 case MULT_EXPR:
1334 /* Transform
1335 i = u {+,-,*} 5;
1336 into
1337 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1338 a = gimple_assign_rhs1 (stmt);
1339 b = gimple_assign_rhs2 (stmt);
1340 g = gimple_build_call_internal (code == PLUS_EXPR
1341 ? IFN_UBSAN_CHECK_ADD
1342 : code == MINUS_EXPR
1343 ? IFN_UBSAN_CHECK_SUB
1344 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1345 gimple_call_set_lhs (g, lhs);
1346 gsi_replace (&gsi, g, false);
1347 break;
1348 case NEGATE_EXPR:
1349 /* Represent i = -u;
1351 i = UBSAN_CHECK_SUB (0, u); */
1352 a = build_int_cst (lhstype, 0);
1353 b = gimple_assign_rhs1 (stmt);
1354 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1355 gimple_call_set_lhs (g, lhs);
1356 gsi_replace (&gsi, g, false);
1357 break;
1358 case ABS_EXPR:
1359 /* Transform i = ABS_EXPR<u>;
1360 into
1361 _N = UBSAN_CHECK_SUB (0, u);
1362 i = ABS_EXPR<_N>; */
1363 a = build_int_cst (lhstype, 0);
1364 b = gimple_assign_rhs1 (stmt);
1365 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1366 a = make_ssa_name (lhstype);
1367 gimple_call_set_lhs (g, a);
1368 gimple_set_location (g, gimple_location (stmt));
1369 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1370 gimple_assign_set_rhs1 (stmt, a);
1371 update_stmt (stmt);
1372 break;
1373 default:
1374 break;
1378 /* Instrument loads from (non-bitfield) bool and C++ enum values
1379 to check if the memory value is outside of the range of the valid
1380 type values. */
1382 static void
1383 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1385 gimple stmt = gsi_stmt (*gsi);
1386 tree rhs = gimple_assign_rhs1 (stmt);
1387 tree type = TREE_TYPE (rhs);
1388 tree minv = NULL_TREE, maxv = NULL_TREE;
1390 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1392 minv = boolean_false_node;
1393 maxv = boolean_true_node;
1395 else if (TREE_CODE (type) == ENUMERAL_TYPE
1396 && (flag_sanitize & SANITIZE_ENUM)
1397 && TREE_TYPE (type) != NULL_TREE
1398 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1399 && (TYPE_PRECISION (TREE_TYPE (type))
1400 < GET_MODE_PRECISION (TYPE_MODE (type))))
1402 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1403 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1405 else
1406 return;
1408 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1409 HOST_WIDE_INT bitsize, bitpos;
1410 tree offset;
1411 machine_mode mode;
1412 int volatilep = 0, unsignedp = 0;
1413 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1414 &unsignedp, &volatilep, false);
1415 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1417 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1418 || (bitpos % modebitsize) != 0
1419 || bitsize != modebitsize
1420 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1421 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1422 return;
1424 bool ends_bb = stmt_ends_bb_p (stmt);
1425 location_t loc = gimple_location (stmt);
1426 tree lhs = gimple_assign_lhs (stmt);
1427 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1428 tree atype = reference_alias_ptr_type (rhs);
1429 gimple g = gimple_build_assign (make_ssa_name (ptype),
1430 build_fold_addr_expr (rhs));
1431 gimple_set_location (g, loc);
1432 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1433 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1434 build_int_cst (atype, 0));
1435 tree urhs = make_ssa_name (utype);
1436 if (ends_bb)
1438 gimple_assign_set_lhs (stmt, urhs);
1439 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1440 gimple_set_location (g, loc);
1441 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1442 gsi_insert_on_edge_immediate (e, g);
1443 gimple_assign_set_rhs_from_tree (gsi, mem);
1444 update_stmt (stmt);
1445 *gsi = gsi_for_stmt (g);
1446 g = stmt;
1448 else
1450 g = gimple_build_assign (urhs, mem);
1451 gimple_set_location (g, loc);
1452 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1454 minv = fold_convert (utype, minv);
1455 maxv = fold_convert (utype, maxv);
1456 if (!integer_zerop (minv))
1458 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1459 gimple_set_location (g, loc);
1460 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1463 gimple_stmt_iterator gsi2 = *gsi;
1464 basic_block then_bb, fallthru_bb;
1465 *gsi = create_cond_insert_point (gsi, true, false, true,
1466 &then_bb, &fallthru_bb);
1467 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1468 int_const_binop (MINUS_EXPR, maxv, minv),
1469 NULL_TREE, NULL_TREE);
1470 gimple_set_location (g, loc);
1471 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1473 if (!ends_bb)
1475 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1476 update_stmt (stmt);
1479 gsi2 = gsi_after_labels (then_bb);
1480 if (flag_sanitize_undefined_trap_on_error)
1481 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1482 else
1484 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1485 ubsan_type_descriptor (type), NULL_TREE,
1486 NULL_TREE);
1487 data = build_fold_addr_expr_loc (loc, data);
1488 enum built_in_function bcode
1489 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1490 ? SANITIZE_BOOL : SANITIZE_ENUM))
1491 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1492 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1493 tree fn = builtin_decl_explicit (bcode);
1495 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1496 true, NULL_TREE, true,
1497 GSI_SAME_STMT);
1498 g = gimple_build_call (fn, 2, data, val);
1500 gimple_set_location (g, loc);
1501 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1502 ubsan_create_edge (g);
1503 *gsi = gsi_for_stmt (stmt);
1506 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1507 destination, EXPR is floating-point expression. ARG is what to pass
1508 the libubsan call as value, often EXPR itself. */
1510 tree
1511 ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
1513 tree expr_type = TREE_TYPE (expr);
1514 tree t, tt, fn, min, max;
1515 machine_mode mode = TYPE_MODE (expr_type);
1516 int prec = TYPE_PRECISION (type);
1517 bool uns_p = TYPE_UNSIGNED (type);
1519 /* Float to integer conversion first truncates toward zero, so
1520 even signed char c = 127.875f; is not problematic.
1521 Therefore, we should complain only if EXPR is unordered or smaller
1522 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1523 TYPE_MAX_VALUE + 1.0. */
1524 if (REAL_MODE_FORMAT (mode)->b == 2)
1526 /* For maximum, TYPE_MAX_VALUE might not be representable
1527 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1528 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1529 either representable or infinity. */
1530 REAL_VALUE_TYPE maxval = dconst1;
1531 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1532 real_convert (&maxval, mode, &maxval);
1533 max = build_real (expr_type, maxval);
1535 /* For unsigned, assume -1.0 is always representable. */
1536 if (uns_p)
1537 min = build_minus_one_cst (expr_type);
1538 else
1540 /* TYPE_MIN_VALUE is generally representable (or -inf),
1541 but TYPE_MIN_VALUE - 1.0 might not be. */
1542 REAL_VALUE_TYPE minval = dconstm1, minval2;
1543 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1544 real_convert (&minval, mode, &minval);
1545 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1546 real_convert (&minval2, mode, &minval2);
1547 if (real_compare (EQ_EXPR, &minval, &minval2)
1548 && !real_isinf (&minval))
1550 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1551 rounds to TYPE_MIN_VALUE, we need to subtract
1552 more. As REAL_MODE_FORMAT (mode)->p is the number
1553 of base digits, we want to subtract a number that
1554 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1555 times smaller than minval. */
1556 minval2 = dconst1;
1557 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1558 SET_REAL_EXP (&minval2,
1559 REAL_EXP (&minval2) + prec - 1
1560 - REAL_MODE_FORMAT (mode)->p + 1);
1561 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1562 real_convert (&minval2, mode, &minval2);
1564 min = build_real (expr_type, minval2);
1567 else if (REAL_MODE_FORMAT (mode)->b == 10)
1569 /* For _Decimal128 up to 34 decimal digits, - sign,
1570 dot, e, exponent. */
1571 char buf[64];
1572 mpfr_t m;
1573 int p = REAL_MODE_FORMAT (mode)->p;
1574 REAL_VALUE_TYPE maxval, minval;
1576 /* Use mpfr_snprintf rounding to compute the smallest
1577 representable decimal number greater or equal than
1578 1 << (prec - !uns_p). */
1579 mpfr_init2 (m, prec + 2);
1580 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1581 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1582 decimal_real_from_string (&maxval, buf);
1583 max = build_real (expr_type, maxval);
1585 /* For unsigned, assume -1.0 is always representable. */
1586 if (uns_p)
1587 min = build_minus_one_cst (expr_type);
1588 else
1590 /* Use mpfr_snprintf rounding to compute the largest
1591 representable decimal number less or equal than
1592 (-1 << (prec - 1)) - 1. */
1593 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1594 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1595 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1596 decimal_real_from_string (&minval, buf);
1597 min = build_real (expr_type, minval);
1599 mpfr_clear (m);
1601 else
1602 return NULL_TREE;
1604 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1605 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1606 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1607 if (integer_zerop (t))
1608 return NULL_TREE;
1610 if (flag_sanitize_undefined_trap_on_error)
1611 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1612 else
1614 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1615 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1616 NULL, ubsan_type_descriptor (expr_type),
1617 ubsan_type_descriptor (type), NULL_TREE,
1618 NULL_TREE);
1619 enum built_in_function bcode
1620 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1621 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1622 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1623 fn = builtin_decl_explicit (bcode);
1624 fn = build_call_expr_loc (loc, fn, 2,
1625 build_fold_addr_expr_loc (loc, data),
1626 ubsan_encode_value (arg, false));
1629 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1632 /* Instrument values passed to function arguments with nonnull attribute. */
1634 static void
1635 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1637 gimple stmt = gsi_stmt (*gsi);
1638 location_t loc[2];
1639 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1640 while for nonnull sanitization it is clear. */
1641 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1642 flag_delete_null_pointer_checks = 1;
1643 loc[0] = gimple_location (stmt);
1644 loc[1] = UNKNOWN_LOCATION;
1645 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1647 tree arg = gimple_call_arg (stmt, i);
1648 if (POINTER_TYPE_P (TREE_TYPE (arg))
1649 && infer_nonnull_range (stmt, arg, false, true))
1651 gimple g;
1652 if (!is_gimple_val (arg))
1654 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1655 gimple_set_location (g, loc[0]);
1656 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1657 arg = gimple_assign_lhs (g);
1660 basic_block then_bb, fallthru_bb;
1661 *gsi = create_cond_insert_point (gsi, true, false, true,
1662 &then_bb, &fallthru_bb);
1663 g = gimple_build_cond (EQ_EXPR, arg,
1664 build_zero_cst (TREE_TYPE (arg)),
1665 NULL_TREE, NULL_TREE);
1666 gimple_set_location (g, loc[0]);
1667 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1669 *gsi = gsi_after_labels (then_bb);
1670 if (flag_sanitize_undefined_trap_on_error)
1671 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1672 else
1674 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1675 2, loc, NULL_TREE,
1676 build_int_cst (integer_type_node,
1677 i + 1),
1678 NULL_TREE);
1679 data = build_fold_addr_expr_loc (loc[0], data);
1680 enum built_in_function bcode
1681 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1682 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1683 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1684 tree fn = builtin_decl_explicit (bcode);
1686 g = gimple_build_call (fn, 1, data);
1688 gimple_set_location (g, loc[0]);
1689 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1690 ubsan_create_edge (g);
1692 *gsi = gsi_for_stmt (stmt);
1694 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1697 /* Instrument returns in functions with returns_nonnull attribute. */
1699 static void
1700 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1702 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1703 location_t loc[2];
1704 tree arg = gimple_return_retval (stmt);
1705 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1706 while for nonnull return sanitization it is clear. */
1707 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1708 flag_delete_null_pointer_checks = 1;
1709 loc[0] = gimple_location (stmt);
1710 loc[1] = UNKNOWN_LOCATION;
1711 if (arg
1712 && POINTER_TYPE_P (TREE_TYPE (arg))
1713 && is_gimple_val (arg)
1714 && infer_nonnull_range (stmt, arg, false, true))
1716 basic_block then_bb, fallthru_bb;
1717 *gsi = create_cond_insert_point (gsi, true, false, true,
1718 &then_bb, &fallthru_bb);
1719 gimple g = gimple_build_cond (EQ_EXPR, arg,
1720 build_zero_cst (TREE_TYPE (arg)),
1721 NULL_TREE, NULL_TREE);
1722 gimple_set_location (g, loc[0]);
1723 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1725 *gsi = gsi_after_labels (then_bb);
1726 if (flag_sanitize_undefined_trap_on_error)
1727 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1728 else
1730 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1731 2, loc, NULL_TREE, NULL_TREE);
1732 data = build_fold_addr_expr_loc (loc[0], data);
1733 enum built_in_function bcode
1734 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1735 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1736 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1737 tree fn = builtin_decl_explicit (bcode);
1739 g = gimple_build_call (fn, 1, data);
1741 gimple_set_location (g, loc[0]);
1742 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1743 ubsan_create_edge (g);
1744 *gsi = gsi_for_stmt (stmt);
1746 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1749 /* Instrument memory references. Here we check whether the pointer
1750 points to an out-of-bounds location. */
1752 static void
1753 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1755 gimple stmt = gsi_stmt (*gsi);
1756 location_t loc = gimple_location (stmt);
1757 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1758 tree type;
1759 tree index = NULL_TREE;
1760 HOST_WIDE_INT size_in_bytes;
1762 type = TREE_TYPE (t);
1763 if (VOID_TYPE_P (type))
1764 return;
1766 switch (TREE_CODE (t))
1768 case COMPONENT_REF:
1769 if (TREE_CODE (t) == COMPONENT_REF
1770 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1772 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1773 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1774 repr, NULL_TREE);
1776 break;
1777 case ARRAY_REF:
1778 index = TREE_OPERAND (t, 1);
1779 break;
1780 case INDIRECT_REF:
1781 case MEM_REF:
1782 case VAR_DECL:
1783 case PARM_DECL:
1784 case RESULT_DECL:
1785 break;
1786 default:
1787 return;
1790 size_in_bytes = int_size_in_bytes (type);
1791 if (size_in_bytes <= 0)
1792 return;
1794 HOST_WIDE_INT bitsize, bitpos;
1795 tree offset;
1796 machine_mode mode;
1797 int volatilep = 0, unsignedp = 0;
1798 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1799 &unsignedp, &volatilep, false);
1801 if (bitpos % BITS_PER_UNIT != 0
1802 || bitsize != size_in_bytes * BITS_PER_UNIT)
1803 return;
1805 bool decl_p = DECL_P (inner);
1806 tree base;
1807 if (decl_p)
1808 base = inner;
1809 else if (TREE_CODE (inner) == MEM_REF)
1810 base = TREE_OPERAND (inner, 0);
1811 else
1812 return;
1813 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1815 while (TREE_CODE (base) == SSA_NAME)
1817 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1818 if (gimple_assign_ssa_name_copy_p (def_stmt)
1819 || (gimple_assign_cast_p (def_stmt)
1820 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1821 || (is_gimple_assign (def_stmt)
1822 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1824 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1825 if (TREE_CODE (rhs1) == SSA_NAME
1826 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1827 break;
1828 else
1829 base = rhs1;
1831 else
1832 break;
1835 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1836 return;
1838 tree sizet;
1839 tree base_addr = base;
1840 gimple bos_stmt = NULL;
1841 if (decl_p)
1842 base_addr = build1 (ADDR_EXPR,
1843 build_pointer_type (TREE_TYPE (base)), base);
1844 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1845 if (size != (unsigned HOST_WIDE_INT) -1)
1846 sizet = build_int_cst (sizetype, size);
1847 else if (optimize)
1849 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1850 loc = input_location;
1851 /* Generate __builtin_object_size call. */
1852 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1853 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1854 integer_zero_node);
1855 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1856 GSI_SAME_STMT);
1857 /* If the call above didn't end up being an integer constant, go one
1858 statement back and get the __builtin_object_size stmt. Save it,
1859 we might need it later. */
1860 if (SSA_VAR_P (sizet))
1862 gsi_prev (gsi);
1863 bos_stmt = gsi_stmt (*gsi);
1865 /* Move on to where we were. */
1866 gsi_next (gsi);
1869 else
1870 return;
1872 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1873 call. */
1874 /* ptr + sizeof (*ptr) - base */
1875 t = fold_build2 (MINUS_EXPR, sizetype,
1876 fold_convert (pointer_sized_int_node, ptr),
1877 fold_convert (pointer_sized_int_node, base_addr));
1878 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1880 /* Perhaps we can omit the check. */
1881 if (TREE_CODE (t) == INTEGER_CST
1882 && TREE_CODE (sizet) == INTEGER_CST
1883 && tree_int_cst_le (t, sizet))
1884 return;
1886 if (index != NULL_TREE
1887 && TREE_CODE (index) == SSA_NAME
1888 && TREE_CODE (sizet) == INTEGER_CST)
1890 gimple def = SSA_NAME_DEF_STMT (index);
1891 if (is_gimple_assign (def)
1892 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1893 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1895 tree cst = gimple_assign_rhs2 (def);
1896 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1897 TYPE_SIZE_UNIT (type));
1898 if (tree_int_cst_sgn (cst) >= 0
1899 && tree_int_cst_lt (cst, sz))
1900 return;
1904 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1905 ubsan_create_edge (bos_stmt);
1907 /* We have to emit the check. */
1908 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1909 GSI_SAME_STMT);
1910 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1911 GSI_SAME_STMT);
1912 tree ckind = build_int_cst (unsigned_char_type_node,
1913 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1914 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1915 ptr, t, sizet, ckind);
1916 gimple_set_location (g, loc);
1917 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1920 /* True if we want to play UBSan games in the current function. */
1922 bool
1923 do_ubsan_in_current_function ()
1925 return (current_function_decl != NULL_TREE
1926 && !lookup_attribute ("no_sanitize_undefined",
1927 DECL_ATTRIBUTES (current_function_decl)));
1930 namespace {
1932 const pass_data pass_data_ubsan =
1934 GIMPLE_PASS, /* type */
1935 "ubsan", /* name */
1936 OPTGROUP_NONE, /* optinfo_flags */
1937 TV_TREE_UBSAN, /* tv_id */
1938 ( PROP_cfg | PROP_ssa ), /* properties_required */
1939 0, /* properties_provided */
1940 0, /* properties_destroyed */
1941 0, /* todo_flags_start */
1942 TODO_update_ssa, /* todo_flags_finish */
1945 class pass_ubsan : public gimple_opt_pass
1947 public:
1948 pass_ubsan (gcc::context *ctxt)
1949 : gimple_opt_pass (pass_data_ubsan, ctxt)
1952 /* opt_pass methods: */
1953 virtual bool gate (function *)
1955 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1956 | SANITIZE_BOOL | SANITIZE_ENUM
1957 | SANITIZE_ALIGNMENT
1958 | SANITIZE_NONNULL_ATTRIBUTE
1959 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1960 | SANITIZE_OBJECT_SIZE)
1961 && do_ubsan_in_current_function ();
1964 virtual unsigned int execute (function *);
1966 }; // class pass_ubsan
1968 unsigned int
1969 pass_ubsan::execute (function *fun)
1971 basic_block bb;
1972 gimple_stmt_iterator gsi;
1974 initialize_sanitizer_builtins ();
1976 FOR_EACH_BB_FN (bb, fun)
1978 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1980 gimple stmt = gsi_stmt (gsi);
1981 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1983 gsi_next (&gsi);
1984 continue;
1987 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1988 && is_gimple_assign (stmt))
1989 instrument_si_overflow (gsi);
1991 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1993 if (gimple_store_p (stmt))
1994 instrument_null (gsi, true);
1995 if (gimple_assign_load_p (stmt))
1996 instrument_null (gsi, false);
1999 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
2000 && gimple_assign_load_p (stmt))
2002 instrument_bool_enum_load (&gsi);
2003 bb = gimple_bb (stmt);
2006 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
2007 && is_gimple_call (stmt)
2008 && !gimple_call_internal_p (stmt))
2010 instrument_nonnull_arg (&gsi);
2011 bb = gimple_bb (stmt);
2014 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2015 && gimple_code (stmt) == GIMPLE_RETURN)
2017 instrument_nonnull_return (&gsi);
2018 bb = gimple_bb (stmt);
2021 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2023 if (gimple_store_p (stmt))
2024 instrument_object_size (&gsi, true);
2025 if (gimple_assign_load_p (stmt))
2026 instrument_object_size (&gsi, false);
2029 gsi_next (&gsi);
2032 return 0;
2035 } // anon namespace
2037 gimple_opt_pass *
2038 make_pass_ubsan (gcc::context *ctxt)
2040 return new pass_ubsan (ctxt);
2043 #include "gt-ubsan.h"