2015-06-11 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / ubsan.c
blob4e2214d66188b4e42dd2227dca6ec4a60f9551c7
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 "input.h"
25 #include "alias.h"
26 #include "symtab.h"
27 #include "options.h"
28 #include "tree.h"
29 #include "fold-const.h"
30 #include "stor-layout.h"
31 #include "stringpool.h"
32 #include "predict.h"
33 #include "dominance.h"
34 #include "cfg.h"
35 #include "cfganal.h"
36 #include "basic-block.h"
37 #include "is-a.h"
38 #include "plugin-api.h"
39 #include "tm.h"
40 #include "hard-reg-set.h"
41 #include "function.h"
42 #include "ipa-ref.h"
43 #include "cgraph.h"
44 #include "tree-pass.h"
45 #include "tree-ssa-alias.h"
46 #include "tree-pretty-print.h"
47 #include "internal-fn.h"
48 #include "gimple-expr.h"
49 #include "gimple.h"
50 #include "gimple-iterator.h"
51 #include "gimple-ssa.h"
52 #include "gimple-walk.h"
53 #include "output.h"
54 #include "tm_p.h"
55 #include "toplev.h"
56 #include "cfgloop.h"
57 #include "ubsan.h"
58 #include "c-family/c-common.h"
59 #include "rtl.h"
60 #include "flags.h"
61 #include "insn-config.h"
62 #include "expmed.h"
63 #include "dojump.h"
64 #include "explow.h"
65 #include "calls.h"
66 #include "emit-rtl.h"
67 #include "varasm.h"
68 #include "stmt.h"
69 #include "expr.h"
70 #include "tree-ssanames.h"
71 #include "asan.h"
72 #include "gimplify-me.h"
73 #include "intl.h"
74 #include "realmpfr.h"
75 #include "dfp.h"
76 #include "builtins.h"
77 #include "tree-object-size.h"
78 #include "tree-eh.h"
79 #include "tree-cfg.h"
81 /* Map from a tree to a VAR_DECL tree. */
83 struct GTY((for_user)) tree_type_map {
84 struct tree_map_base type;
85 tree decl;
88 struct tree_type_map_cache_hasher : ggc_cache_hasher<tree_type_map *>
90 static inline hashval_t
91 hash (tree_type_map *t)
93 return TYPE_UID (t->type.from);
96 static inline bool
97 equal (tree_type_map *a, tree_type_map *b)
99 return a->type.from == b->type.from;
102 static void
103 handle_cache_entry (tree_type_map *&m)
105 extern void gt_ggc_mx (tree_type_map *&);
106 if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
107 return;
108 else if (ggc_marked_p (m->type.from))
109 gt_ggc_mx (m);
110 else
111 m = static_cast<tree_type_map *> (HTAB_DELETED_ENTRY);
115 static GTY ((cache))
116 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
118 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
120 static tree
121 decl_for_type_lookup (tree type)
123 /* If the hash table is not initialized yet, create it now. */
124 if (decl_tree_for_type == NULL)
126 decl_tree_for_type
127 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
128 /* That also means we don't have to bother with the lookup. */
129 return NULL_TREE;
132 struct tree_type_map *h, in;
133 in.type.from = type;
135 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
136 return h ? h->decl : NULL_TREE;
139 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
141 static void
142 decl_for_type_insert (tree type, tree decl)
144 struct tree_type_map *h;
146 h = ggc_alloc<tree_type_map> ();
147 h->type.from = type;
148 h->decl = decl;
149 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
152 /* Helper routine, which encodes a value in the pointer_sized_int_node.
153 Arguments with precision <= POINTER_SIZE are passed directly,
154 the rest is passed by reference. T is a value we are to encode.
155 IN_EXPAND_P is true if this function is called during expansion. */
157 tree
158 ubsan_encode_value (tree t, bool in_expand_p)
160 tree type = TREE_TYPE (t);
161 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
162 if (bitsize <= POINTER_SIZE)
163 switch (TREE_CODE (type))
165 case BOOLEAN_TYPE:
166 case ENUMERAL_TYPE:
167 case INTEGER_TYPE:
168 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
169 case REAL_TYPE:
171 tree itype = build_nonstandard_integer_type (bitsize, true);
172 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
173 return fold_convert (pointer_sized_int_node, t);
175 default:
176 gcc_unreachable ();
178 else
180 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
182 /* The reason for this is that we don't want to pessimize
183 code by making vars unnecessarily addressable. */
184 tree var = create_tmp_var (type);
185 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
186 if (in_expand_p)
188 rtx mem
189 = assign_stack_temp_for_type (TYPE_MODE (type),
190 GET_MODE_SIZE (TYPE_MODE (type)),
191 type);
192 SET_DECL_RTL (var, mem);
193 expand_assignment (var, t, false);
194 return build_fold_addr_expr (var);
196 t = build_fold_addr_expr (var);
197 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
199 else
200 return build_fold_addr_expr (t);
204 /* Cached ubsan_get_type_descriptor_type () return value. */
205 static GTY(()) tree ubsan_type_descriptor_type;
207 /* Build
208 struct __ubsan_type_descriptor
210 unsigned short __typekind;
211 unsigned short __typeinfo;
212 char __typename[];
214 type. */
216 static tree
217 ubsan_get_type_descriptor_type (void)
219 static const char *field_names[3]
220 = { "__typekind", "__typeinfo", "__typename" };
221 tree fields[3], ret;
223 if (ubsan_type_descriptor_type)
224 return ubsan_type_descriptor_type;
226 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
227 tree flex_arr_type = build_array_type (char_type_node, itype);
229 ret = make_node (RECORD_TYPE);
230 for (int i = 0; i < 3; i++)
232 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
233 get_identifier (field_names[i]),
234 (i == 2) ? flex_arr_type
235 : short_unsigned_type_node);
236 DECL_CONTEXT (fields[i]) = ret;
237 if (i)
238 DECL_CHAIN (fields[i - 1]) = fields[i];
240 tree type_decl = build_decl (input_location, TYPE_DECL,
241 get_identifier ("__ubsan_type_descriptor"),
242 ret);
243 DECL_IGNORED_P (type_decl) = 1;
244 DECL_ARTIFICIAL (type_decl) = 1;
245 TYPE_FIELDS (ret) = fields[0];
246 TYPE_NAME (ret) = type_decl;
247 TYPE_STUB_DECL (ret) = type_decl;
248 layout_type (ret);
249 ubsan_type_descriptor_type = ret;
250 return ret;
253 /* Cached ubsan_get_source_location_type () return value. */
254 static GTY(()) tree ubsan_source_location_type;
256 /* Build
257 struct __ubsan_source_location
259 const char *__filename;
260 unsigned int __line;
261 unsigned int __column;
263 type. */
265 tree
266 ubsan_get_source_location_type (void)
268 static const char *field_names[3]
269 = { "__filename", "__line", "__column" };
270 tree fields[3], ret;
271 if (ubsan_source_location_type)
272 return ubsan_source_location_type;
274 tree const_char_type = build_qualified_type (char_type_node,
275 TYPE_QUAL_CONST);
277 ret = make_node (RECORD_TYPE);
278 for (int i = 0; i < 3; i++)
280 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
281 get_identifier (field_names[i]),
282 (i == 0) ? build_pointer_type (const_char_type)
283 : unsigned_type_node);
284 DECL_CONTEXT (fields[i]) = ret;
285 if (i)
286 DECL_CHAIN (fields[i - 1]) = fields[i];
288 tree type_decl = build_decl (input_location, TYPE_DECL,
289 get_identifier ("__ubsan_source_location"),
290 ret);
291 DECL_IGNORED_P (type_decl) = 1;
292 DECL_ARTIFICIAL (type_decl) = 1;
293 TYPE_FIELDS (ret) = fields[0];
294 TYPE_NAME (ret) = type_decl;
295 TYPE_STUB_DECL (ret) = type_decl;
296 layout_type (ret);
297 ubsan_source_location_type = ret;
298 return ret;
301 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
302 type with its fields filled from a location_t LOC. */
304 static tree
305 ubsan_source_location (location_t loc)
307 expanded_location xloc;
308 tree type = ubsan_get_source_location_type ();
310 xloc = expand_location (loc);
311 tree str;
312 if (xloc.file == NULL)
314 str = build_int_cst (ptr_type_node, 0);
315 xloc.line = 0;
316 xloc.column = 0;
318 else
320 /* Fill in the values from LOC. */
321 size_t len = strlen (xloc.file) + 1;
322 str = build_string (len, xloc.file);
323 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
324 TREE_READONLY (str) = 1;
325 TREE_STATIC (str) = 1;
326 str = build_fold_addr_expr (str);
328 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
329 build_int_cst (unsigned_type_node,
330 xloc.line), NULL_TREE,
331 build_int_cst (unsigned_type_node,
332 xloc.column));
333 TREE_CONSTANT (ctor) = 1;
334 TREE_STATIC (ctor) = 1;
336 return ctor;
339 /* This routine returns a magic number for TYPE. */
341 static unsigned short
342 get_ubsan_type_info_for_type (tree type)
344 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
345 if (TREE_CODE (type) == REAL_TYPE)
346 return tree_to_uhwi (TYPE_SIZE (type));
347 else if (INTEGRAL_TYPE_P (type))
349 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
350 gcc_assert (prec != -1);
351 return (prec << 1) | !TYPE_UNSIGNED (type);
353 else
354 return 0;
357 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
358 descriptor. It first looks into the hash table; if not found,
359 create the VAR_DECL, put it into the hash table and return the
360 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
361 an enum controlling how we want to print the type. */
363 tree
364 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
366 /* See through any typedefs. */
367 type = TYPE_MAIN_VARIANT (type);
369 tree decl = decl_for_type_lookup (type);
370 /* It is possible that some of the earlier created DECLs were found
371 unused, in that case they weren't emitted and varpool_node::get
372 returns NULL node on them. But now we really need them. Thus,
373 renew them here. */
374 if (decl != NULL_TREE && varpool_node::get (decl))
375 return build_fold_addr_expr (decl);
377 tree dtype = ubsan_get_type_descriptor_type ();
378 tree type2 = type;
379 const char *tname = NULL;
380 pretty_printer pretty_name;
381 unsigned char deref_depth = 0;
382 unsigned short tkind, tinfo;
384 /* Get the name of the type, or the name of the pointer type. */
385 if (pstyle == UBSAN_PRINT_POINTER)
387 gcc_assert (POINTER_TYPE_P (type));
388 type2 = TREE_TYPE (type);
390 /* Remove any '*' operators from TYPE. */
391 while (POINTER_TYPE_P (type2))
392 deref_depth++, type2 = TREE_TYPE (type2);
394 if (TREE_CODE (type2) == METHOD_TYPE)
395 type2 = TYPE_METHOD_BASETYPE (type2);
398 /* If an array, get its type. */
399 type2 = strip_array_types (type2);
401 if (pstyle == UBSAN_PRINT_ARRAY)
403 while (POINTER_TYPE_P (type2))
404 deref_depth++, type2 = TREE_TYPE (type2);
407 if (TYPE_NAME (type2) != NULL)
409 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
410 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
411 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
412 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
415 if (tname == NULL)
416 /* We weren't able to determine the type name. */
417 tname = "<unknown>";
419 if (pstyle == UBSAN_PRINT_POINTER)
421 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
422 TYPE_VOLATILE (type2) ? "volatile " : "",
423 TYPE_READONLY (type2) ? "const " : "",
424 TYPE_RESTRICT (type2) ? "restrict " : "",
425 TYPE_ATOMIC (type2) ? "_Atomic " : "",
426 TREE_CODE (type2) == RECORD_TYPE
427 ? "struct "
428 : TREE_CODE (type2) == UNION_TYPE
429 ? "union " : "", tname,
430 deref_depth == 0 ? "" : " ");
431 while (deref_depth-- > 0)
432 pp_star (&pretty_name);
433 pp_quote (&pretty_name);
435 else if (pstyle == UBSAN_PRINT_ARRAY)
437 /* Pretty print the array dimensions. */
438 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
439 tree t = type;
440 pp_printf (&pretty_name, "'%s ", tname);
441 while (deref_depth-- > 0)
442 pp_star (&pretty_name);
443 while (TREE_CODE (t) == ARRAY_TYPE)
445 pp_left_bracket (&pretty_name);
446 tree dom = TYPE_DOMAIN (t);
447 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
449 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
450 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
451 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
452 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
453 else
454 pp_wide_int (&pretty_name,
455 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
456 TYPE_SIGN (TREE_TYPE (dom)));
458 else
459 /* ??? We can't determine the variable name; print VLA unspec. */
460 pp_star (&pretty_name);
461 pp_right_bracket (&pretty_name);
462 t = TREE_TYPE (t);
464 pp_quote (&pretty_name);
466 /* Save the tree with stripped types. */
467 type = t;
469 else
470 pp_printf (&pretty_name, "'%s'", tname);
472 switch (TREE_CODE (type))
474 case BOOLEAN_TYPE:
475 case ENUMERAL_TYPE:
476 case INTEGER_TYPE:
477 tkind = 0x0000;
478 break;
479 case REAL_TYPE:
480 /* FIXME: libubsan right now only supports float, double and
481 long double type formats. */
482 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
483 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
484 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
485 tkind = 0x0001;
486 else
487 tkind = 0xffff;
488 break;
489 default:
490 tkind = 0xffff;
491 break;
493 tinfo = get_ubsan_type_info_for_type (type);
495 /* Create a new VAR_DECL of type descriptor. */
496 const char *tmp = pp_formatted_text (&pretty_name);
497 size_t len = strlen (tmp) + 1;
498 tree str = build_string (len, tmp);
499 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
500 TREE_READONLY (str) = 1;
501 TREE_STATIC (str) = 1;
503 char tmp_name[32];
504 static unsigned int type_var_id_num;
505 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
506 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
507 dtype);
508 TREE_STATIC (decl) = 1;
509 TREE_PUBLIC (decl) = 0;
510 DECL_ARTIFICIAL (decl) = 1;
511 DECL_IGNORED_P (decl) = 1;
512 DECL_EXTERNAL (decl) = 0;
513 DECL_SIZE (decl)
514 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
515 DECL_SIZE_UNIT (decl)
516 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
517 TYPE_SIZE_UNIT (TREE_TYPE (str)));
519 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
520 build_int_cst (short_unsigned_type_node,
521 tkind), NULL_TREE,
522 build_int_cst (short_unsigned_type_node,
523 tinfo), NULL_TREE, str);
524 TREE_CONSTANT (ctor) = 1;
525 TREE_STATIC (ctor) = 1;
526 DECL_INITIAL (decl) = ctor;
527 varpool_node::finalize_decl (decl);
529 /* Save the VAR_DECL into the hash table. */
530 decl_for_type_insert (type, decl);
532 return build_fold_addr_expr (decl);
535 /* Create a structure for the ubsan library. NAME is a name of the new
536 structure. LOCCNT is number of locations, PLOC points to array of
537 locations. The arguments in ... are of __ubsan_type_descriptor type
538 and there are at most two of them, followed by NULL_TREE, followed
539 by optional extra arguments and another NULL_TREE. */
541 tree
542 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
544 va_list args;
545 tree ret, t;
546 tree fields[6];
547 vec<tree, va_gc> *saved_args = NULL;
548 size_t i = 0;
549 int j;
551 /* Firstly, create a pointer to type descriptor type. */
552 tree td_type = ubsan_get_type_descriptor_type ();
553 td_type = build_pointer_type (td_type);
555 /* Create the structure type. */
556 ret = make_node (RECORD_TYPE);
557 for (j = 0; j < loccnt; j++)
559 gcc_checking_assert (i < 2);
560 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
561 ubsan_get_source_location_type ());
562 DECL_CONTEXT (fields[i]) = ret;
563 if (i)
564 DECL_CHAIN (fields[i - 1]) = fields[i];
565 i++;
568 va_start (args, ploc);
569 for (t = va_arg (args, tree); t != NULL_TREE;
570 i++, t = va_arg (args, tree))
572 gcc_checking_assert (i < 4);
573 /* Save the tree arguments for later use. */
574 vec_safe_push (saved_args, t);
575 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
576 td_type);
577 DECL_CONTEXT (fields[i]) = ret;
578 if (i)
579 DECL_CHAIN (fields[i - 1]) = fields[i];
582 for (t = va_arg (args, tree); t != NULL_TREE;
583 i++, t = va_arg (args, tree))
585 gcc_checking_assert (i < 6);
586 /* Save the tree arguments for later use. */
587 vec_safe_push (saved_args, t);
588 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
589 TREE_TYPE (t));
590 DECL_CONTEXT (fields[i]) = ret;
591 if (i)
592 DECL_CHAIN (fields[i - 1]) = fields[i];
594 va_end (args);
596 tree type_decl = build_decl (input_location, TYPE_DECL,
597 get_identifier (name), ret);
598 DECL_IGNORED_P (type_decl) = 1;
599 DECL_ARTIFICIAL (type_decl) = 1;
600 TYPE_FIELDS (ret) = fields[0];
601 TYPE_NAME (ret) = type_decl;
602 TYPE_STUB_DECL (ret) = type_decl;
603 layout_type (ret);
605 /* Now, fill in the type. */
606 char tmp_name[32];
607 static unsigned int ubsan_var_id_num;
608 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
609 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
610 ret);
611 TREE_STATIC (var) = 1;
612 TREE_PUBLIC (var) = 0;
613 DECL_ARTIFICIAL (var) = 1;
614 DECL_IGNORED_P (var) = 1;
615 DECL_EXTERNAL (var) = 0;
617 vec<constructor_elt, va_gc> *v;
618 vec_alloc (v, i);
619 tree ctor = build_constructor (ret, v);
621 /* If desirable, set the __ubsan_source_location element. */
622 for (j = 0; j < loccnt; j++)
624 location_t loc = LOCATION_LOCUS (ploc[j]);
625 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
628 size_t nelts = vec_safe_length (saved_args);
629 for (i = 0; i < nelts; i++)
631 t = (*saved_args)[i];
632 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
635 TREE_CONSTANT (ctor) = 1;
636 TREE_STATIC (ctor) = 1;
637 DECL_INITIAL (var) = ctor;
638 varpool_node::finalize_decl (var);
640 return var;
643 /* Instrument the __builtin_unreachable call. We just call the libubsan
644 routine instead. */
646 bool
647 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
649 gimple g;
650 location_t loc = gimple_location (gsi_stmt (*gsi));
652 if (flag_sanitize_undefined_trap_on_error)
653 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
654 else
656 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
657 NULL_TREE, NULL_TREE);
658 data = build_fold_addr_expr_loc (loc, data);
659 tree fn
660 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
661 g = gimple_build_call (fn, 1, data);
663 gimple_set_location (g, loc);
664 gsi_replace (gsi, g, false);
665 return false;
668 /* Return true if T is a call to a libubsan routine. */
670 bool
671 is_ubsan_builtin_p (tree t)
673 return TREE_CODE (t) == FUNCTION_DECL
674 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
675 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
676 "__builtin___ubsan_", 18) == 0;
679 /* Create a callgraph edge for statement STMT. */
681 static void
682 ubsan_create_edge (gimple stmt)
684 gcall *call_stmt = dyn_cast <gcall *> (stmt);
685 basic_block bb = gimple_bb (stmt);
686 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
687 cgraph_node *node = cgraph_node::get (current_function_decl);
688 tree decl = gimple_call_fndecl (call_stmt);
689 if (decl)
690 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
691 freq);
694 /* Expand the UBSAN_BOUNDS special builtin function. */
696 bool
697 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
699 gimple stmt = gsi_stmt (*gsi);
700 location_t loc = gimple_location (stmt);
701 gcc_assert (gimple_call_num_args (stmt) == 3);
703 /* Pick up the arguments of the UBSAN_BOUNDS call. */
704 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
705 tree index = gimple_call_arg (stmt, 1);
706 tree orig_index_type = TREE_TYPE (index);
707 tree bound = gimple_call_arg (stmt, 2);
709 gimple_stmt_iterator gsi_orig = *gsi;
711 /* Create condition "if (index > bound)". */
712 basic_block then_bb, fallthru_bb;
713 gimple_stmt_iterator cond_insert_point
714 = create_cond_insert_point (gsi, false, false, true,
715 &then_bb, &fallthru_bb);
716 index = fold_convert (TREE_TYPE (bound), index);
717 index = force_gimple_operand_gsi (&cond_insert_point, index,
718 true, NULL_TREE,
719 false, GSI_NEW_STMT);
720 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
721 gimple_set_location (g, loc);
722 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
724 /* Generate __ubsan_handle_out_of_bounds call. */
725 *gsi = gsi_after_labels (then_bb);
726 if (flag_sanitize_undefined_trap_on_error)
727 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
728 else
730 tree data
731 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
732 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
733 ubsan_type_descriptor (orig_index_type),
734 NULL_TREE, NULL_TREE);
735 data = build_fold_addr_expr_loc (loc, data);
736 enum built_in_function bcode
737 = (flag_sanitize_recover & SANITIZE_BOUNDS)
738 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
739 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
740 tree fn = builtin_decl_explicit (bcode);
741 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
742 true, NULL_TREE, true,
743 GSI_SAME_STMT);
744 g = gimple_build_call (fn, 2, data, val);
746 gimple_set_location (g, loc);
747 gsi_insert_before (gsi, g, GSI_SAME_STMT);
749 /* Get rid of the UBSAN_BOUNDS call from the IR. */
750 unlink_stmt_vdef (stmt);
751 gsi_remove (&gsi_orig, true);
753 /* Point GSI to next logical statement. */
754 *gsi = gsi_start_bb (fallthru_bb);
755 return true;
758 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
759 argument which is a constant, because the middle-end treats pointer
760 conversions as useless and therefore the type of the first argument
761 could be changed to any other pointer type. */
763 bool
764 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
766 gimple_stmt_iterator gsi = *gsip;
767 gimple stmt = gsi_stmt (gsi);
768 location_t loc = gimple_location (stmt);
769 gcc_assert (gimple_call_num_args (stmt) == 3);
770 tree ptr = gimple_call_arg (stmt, 0);
771 tree ckind = gimple_call_arg (stmt, 1);
772 tree align = gimple_call_arg (stmt, 2);
773 tree check_align = NULL_TREE;
774 bool check_null;
776 basic_block cur_bb = gsi_bb (gsi);
778 gimple g;
779 if (!integer_zerop (align))
781 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
782 if (compare_tree_int (align, ptralign) == 1)
784 check_align = make_ssa_name (pointer_sized_int_node);
785 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
786 gimple_set_location (g, loc);
787 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
790 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
792 if (check_align == NULL_TREE && !check_null)
794 gsi_remove (gsip, true);
795 /* Unlink the UBSAN_NULLs vops before replacing it. */
796 unlink_stmt_vdef (stmt);
797 return true;
800 /* Split the original block holding the pointer dereference. */
801 edge e = split_block (cur_bb, stmt);
803 /* Get a hold on the 'condition block', the 'then block' and the
804 'else block'. */
805 basic_block cond_bb = e->src;
806 basic_block fallthru_bb = e->dest;
807 basic_block then_bb = create_empty_bb (cond_bb);
808 add_bb_to_loop (then_bb, cond_bb->loop_father);
809 loops_state_set (LOOPS_NEED_FIXUP);
811 /* Make an edge coming from the 'cond block' into the 'then block';
812 this edge is unlikely taken, so set up the probability accordingly. */
813 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
814 e->probability = PROB_VERY_UNLIKELY;
816 /* Connect 'then block' with the 'else block'. This is needed
817 as the ubsan routines we call in the 'then block' are not noreturn.
818 The 'then block' only has one outcoming edge. */
819 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
821 /* Set up the fallthrough basic block. */
822 e = find_edge (cond_bb, fallthru_bb);
823 e->flags = EDGE_FALSE_VALUE;
824 e->count = cond_bb->count;
825 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
827 /* Update dominance info for the newly created then_bb; note that
828 fallthru_bb's dominance info has already been updated by
829 split_block. */
830 if (dom_info_available_p (CDI_DOMINATORS))
831 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
833 /* Put the ubsan builtin call into the newly created BB. */
834 if (flag_sanitize_undefined_trap_on_error)
835 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
836 else
838 enum built_in_function bcode
839 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
840 | (check_null ? SANITIZE_NULL : 0)))
841 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
842 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
843 tree fn = builtin_decl_implicit (bcode);
844 tree data
845 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
846 ubsan_type_descriptor (TREE_TYPE (ckind),
847 UBSAN_PRINT_POINTER),
848 NULL_TREE,
849 align,
850 fold_convert (unsigned_char_type_node, ckind),
851 NULL_TREE);
852 data = build_fold_addr_expr_loc (loc, data);
853 g = gimple_build_call (fn, 2, data,
854 check_align ? check_align
855 : build_zero_cst (pointer_sized_int_node));
857 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
858 gimple_set_location (g, loc);
859 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
861 /* Unlink the UBSAN_NULLs vops before replacing it. */
862 unlink_stmt_vdef (stmt);
864 if (check_null)
866 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
867 NULL_TREE, NULL_TREE);
868 gimple_set_location (g, loc);
870 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
871 gsi_replace (&gsi, g, false);
872 stmt = g;
875 if (check_align)
877 if (check_null)
879 /* Split the block with the condition again. */
880 e = split_block (cond_bb, stmt);
881 basic_block cond1_bb = e->src;
882 basic_block cond2_bb = e->dest;
884 /* Make an edge coming from the 'cond1 block' into the 'then block';
885 this edge is unlikely taken, so set up the probability
886 accordingly. */
887 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
888 e->probability = PROB_VERY_UNLIKELY;
890 /* Set up the fallthrough basic block. */
891 e = find_edge (cond1_bb, cond2_bb);
892 e->flags = EDGE_FALSE_VALUE;
893 e->count = cond1_bb->count;
894 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
896 /* Update dominance info. */
897 if (dom_info_available_p (CDI_DOMINATORS))
899 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
900 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
903 gsi2 = gsi_start_bb (cond2_bb);
906 tree mask = build_int_cst (pointer_sized_int_node,
907 tree_to_uhwi (align) - 1);
908 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
909 BIT_AND_EXPR, check_align, mask);
910 gimple_set_location (g, loc);
911 if (check_null)
912 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
913 else
914 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
916 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
917 build_int_cst (pointer_sized_int_node, 0),
918 NULL_TREE, NULL_TREE);
919 gimple_set_location (g, loc);
920 if (check_null)
921 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
922 else
923 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
924 gsi_replace (&gsi, g, false);
926 return false;
929 #define OBJSZ_MAX_OFFSET (1024 * 16)
931 /* Expand UBSAN_OBJECT_SIZE internal call. */
933 bool
934 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
936 gimple stmt = gsi_stmt (*gsi);
937 location_t loc = gimple_location (stmt);
938 gcc_assert (gimple_call_num_args (stmt) == 4);
940 tree ptr = gimple_call_arg (stmt, 0);
941 tree offset = gimple_call_arg (stmt, 1);
942 tree size = gimple_call_arg (stmt, 2);
943 tree ckind = gimple_call_arg (stmt, 3);
944 gimple_stmt_iterator gsi_orig = *gsi;
945 gimple g;
947 /* See if we can discard the check. */
948 if (TREE_CODE (size) != INTEGER_CST
949 || integer_all_onesp (size))
950 /* Yes, __builtin_object_size couldn't determine the
951 object size. */;
952 else if (TREE_CODE (offset) == INTEGER_CST
953 && wi::ges_p (wi::to_widest (offset), -OBJSZ_MAX_OFFSET)
954 && wi::les_p (wi::to_widest (offset), -1))
955 /* The offset is in range [-16K, -1]. */;
956 else
958 /* if (offset > objsize) */
959 basic_block then_bb, fallthru_bb;
960 gimple_stmt_iterator cond_insert_point
961 = create_cond_insert_point (gsi, false, false, true,
962 &then_bb, &fallthru_bb);
963 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
964 gimple_set_location (g, loc);
965 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
967 /* If the offset is small enough, we don't need the second
968 run-time check. */
969 if (TREE_CODE (offset) == INTEGER_CST
970 && wi::ges_p (wi::to_widest (offset), 0)
971 && wi::les_p (wi::to_widest (offset), OBJSZ_MAX_OFFSET))
972 *gsi = gsi_after_labels (then_bb);
973 else
975 /* Don't issue run-time error if (ptr > ptr + offset). That
976 may happen when computing a POINTER_PLUS_EXPR. */
977 basic_block then2_bb, fallthru2_bb;
979 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
980 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
981 true, &then2_bb,
982 &fallthru2_bb);
983 /* Convert the pointer to an integer type. */
984 tree p = make_ssa_name (pointer_sized_int_node);
985 g = gimple_build_assign (p, NOP_EXPR, ptr);
986 gimple_set_location (g, loc);
987 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
988 p = gimple_assign_lhs (g);
989 /* Compute ptr + offset. */
990 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
991 PLUS_EXPR, p, offset);
992 gimple_set_location (g, loc);
993 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
994 /* Now build the conditional and put it into the IR. */
995 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
996 NULL_TREE, NULL_TREE);
997 gimple_set_location (g, loc);
998 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
999 *gsi = gsi_after_labels (then2_bb);
1002 /* Generate __ubsan_handle_type_mismatch call. */
1003 if (flag_sanitize_undefined_trap_on_error)
1004 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1005 else
1007 tree data
1008 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
1009 ubsan_type_descriptor (TREE_TYPE (ptr),
1010 UBSAN_PRINT_POINTER),
1011 NULL_TREE,
1012 build_zero_cst (pointer_sized_int_node),
1013 ckind,
1014 NULL_TREE);
1015 data = build_fold_addr_expr_loc (loc, data);
1016 enum built_in_function bcode
1017 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1018 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1019 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
1020 tree p = make_ssa_name (pointer_sized_int_node);
1021 g = gimple_build_assign (p, NOP_EXPR, ptr);
1022 gimple_set_location (g, loc);
1023 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1024 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1026 gimple_set_location (g, loc);
1027 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1029 /* Point GSI to next logical statement. */
1030 *gsi = gsi_start_bb (fallthru_bb);
1032 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1033 unlink_stmt_vdef (stmt);
1034 gsi_remove (&gsi_orig, true);
1035 return true;
1038 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1039 unlink_stmt_vdef (stmt);
1040 gsi_remove (gsi, true);
1041 return true;
1044 /* Cached __ubsan_vptr_type_cache decl. */
1045 static GTY(()) tree ubsan_vptr_type_cache_decl;
1047 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1048 argument which is a constant, because the middle-end treats pointer
1049 conversions as useless and therefore the type of the first argument
1050 could be changed to any other pointer type. */
1052 bool
1053 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1055 gimple_stmt_iterator gsi = *gsip;
1056 gimple stmt = gsi_stmt (gsi);
1057 location_t loc = gimple_location (stmt);
1058 gcc_assert (gimple_call_num_args (stmt) == 5);
1059 tree op = gimple_call_arg (stmt, 0);
1060 tree vptr = gimple_call_arg (stmt, 1);
1061 tree str_hash = gimple_call_arg (stmt, 2);
1062 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1063 tree ckind_tree = gimple_call_arg (stmt, 4);
1064 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1065 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1066 gimple g;
1067 basic_block fallthru_bb = NULL;
1069 if (ckind == UBSAN_DOWNCAST_POINTER)
1071 /* Guard everything with if (op != NULL) { ... }. */
1072 basic_block then_bb;
1073 gimple_stmt_iterator cond_insert_point
1074 = create_cond_insert_point (gsip, false, false, true,
1075 &then_bb, &fallthru_bb);
1076 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1077 NULL_TREE, NULL_TREE);
1078 gimple_set_location (g, loc);
1079 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1080 *gsip = gsi_after_labels (then_bb);
1081 gsi_remove (&gsi, false);
1082 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1083 gsi = *gsip;
1086 tree htype = TREE_TYPE (str_hash);
1087 tree cst = wide_int_to_tree (htype,
1088 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1089 | 0xeb382d69, 64));
1090 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1091 vptr, str_hash);
1092 gimple_set_location (g, loc);
1093 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1094 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1095 gimple_assign_lhs (g), cst);
1096 gimple_set_location (g, loc);
1097 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1098 tree t1 = gimple_assign_lhs (g);
1099 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1100 t1, build_int_cst (integer_type_node, 47));
1101 gimple_set_location (g, loc);
1102 tree t2 = gimple_assign_lhs (g);
1103 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1104 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1105 vptr, t1);
1106 gimple_set_location (g, loc);
1107 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1108 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1109 t2, gimple_assign_lhs (g));
1110 gimple_set_location (g, loc);
1111 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1112 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1113 gimple_assign_lhs (g), cst);
1114 gimple_set_location (g, loc);
1115 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1116 tree t3 = gimple_assign_lhs (g);
1117 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1118 t3, build_int_cst (integer_type_node, 47));
1119 gimple_set_location (g, loc);
1120 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1121 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1122 t3, gimple_assign_lhs (g));
1123 gimple_set_location (g, loc);
1124 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1125 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1126 gimple_assign_lhs (g), cst);
1127 gimple_set_location (g, loc);
1128 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1129 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1131 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1132 NOP_EXPR, gimple_assign_lhs (g));
1133 gimple_set_location (g, loc);
1134 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1136 tree hash = gimple_assign_lhs (g);
1138 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1140 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1141 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1142 get_identifier ("__ubsan_vptr_type_cache"),
1143 atype);
1144 DECL_ARTIFICIAL (array) = 1;
1145 DECL_IGNORED_P (array) = 1;
1146 TREE_PUBLIC (array) = 1;
1147 TREE_STATIC (array) = 1;
1148 DECL_EXTERNAL (array) = 1;
1149 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1150 DECL_VISIBILITY_SPECIFIED (array) = 1;
1151 varpool_node::finalize_decl (array);
1152 ubsan_vptr_type_cache_decl = array;
1155 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1156 BIT_AND_EXPR, hash,
1157 build_int_cst (pointer_sized_int_node, 127));
1158 gimple_set_location (g, loc);
1159 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1161 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1162 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1163 NULL_TREE, NULL_TREE);
1164 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1165 ARRAY_REF, c);
1166 gimple_set_location (g, loc);
1167 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1169 basic_block then_bb, fallthru2_bb;
1170 gimple_stmt_iterator cond_insert_point
1171 = create_cond_insert_point (gsip, false, false, true,
1172 &then_bb, &fallthru2_bb);
1173 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1174 NULL_TREE, NULL_TREE);
1175 gimple_set_location (g, loc);
1176 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1177 *gsip = gsi_after_labels (then_bb);
1178 if (fallthru_bb == NULL)
1179 fallthru_bb = fallthru2_bb;
1181 tree data
1182 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1183 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1184 build_int_cst (unsigned_char_type_node, ckind),
1185 NULL_TREE);
1186 data = build_fold_addr_expr_loc (loc, data);
1187 enum built_in_function bcode
1188 = (flag_sanitize_recover & SANITIZE_VPTR)
1189 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1190 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1192 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1193 gimple_set_location (g, loc);
1194 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1196 /* Point GSI to next logical statement. */
1197 *gsip = gsi_start_bb (fallthru_bb);
1199 /* Get rid of the UBSAN_VPTR call from the IR. */
1200 unlink_stmt_vdef (stmt);
1201 gsi_remove (&gsi, true);
1202 return true;
1205 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1206 whether the pointer is on the left hand side of the assignment. */
1208 static void
1209 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1210 bool is_lhs)
1212 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1213 unsigned int align = 0;
1214 if (flag_sanitize & SANITIZE_ALIGNMENT)
1216 align = min_align_of_type (TREE_TYPE (base));
1217 if (align <= 1)
1218 align = 0;
1220 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1221 return;
1222 tree t = TREE_OPERAND (base, 0);
1223 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1224 return;
1225 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1226 ikind = UBSAN_MEMBER_ACCESS;
1227 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1228 tree alignt = build_int_cst (pointer_sized_int_node, align);
1229 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1230 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1231 gsi_insert_before (iter, g, GSI_SAME_STMT);
1234 /* Perform the pointer instrumentation. */
1236 static void
1237 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1239 gimple stmt = gsi_stmt (gsi);
1240 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1241 tree base = get_base_address (t);
1242 const enum tree_code code = TREE_CODE (base);
1243 if (code == MEM_REF
1244 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1245 instrument_mem_ref (t, base, &gsi, is_lhs);
1248 /* Build an ubsan builtin call for the signed-integer-overflow
1249 sanitization. CODE says what kind of builtin are we building,
1250 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1251 are operands of the binary operation. */
1253 tree
1254 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1255 tree op0, tree op1)
1257 if (flag_sanitize_undefined_trap_on_error)
1258 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1260 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1261 ubsan_type_descriptor (lhstype), NULL_TREE,
1262 NULL_TREE);
1263 enum built_in_function fn_code;
1265 switch (code)
1267 case PLUS_EXPR:
1268 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1269 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1270 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1271 break;
1272 case MINUS_EXPR:
1273 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1274 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1275 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1276 break;
1277 case MULT_EXPR:
1278 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1279 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1280 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1281 break;
1282 case NEGATE_EXPR:
1283 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1284 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1285 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1286 break;
1287 default:
1288 gcc_unreachable ();
1290 tree fn = builtin_decl_explicit (fn_code);
1291 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1292 build_fold_addr_expr_loc (loc, data),
1293 ubsan_encode_value (op0, true),
1294 op1 ? ubsan_encode_value (op1, true)
1295 : NULL_TREE);
1298 /* Perform the signed integer instrumentation. GSI is the iterator
1299 pointing at statement we are trying to instrument. */
1301 static void
1302 instrument_si_overflow (gimple_stmt_iterator gsi)
1304 gimple stmt = gsi_stmt (gsi);
1305 tree_code code = gimple_assign_rhs_code (stmt);
1306 tree lhs = gimple_assign_lhs (stmt);
1307 tree lhstype = TREE_TYPE (lhs);
1308 tree a, b;
1309 gimple g;
1311 /* If this is not a signed operation, don't instrument anything here.
1312 Also punt on bit-fields. */
1313 if (!INTEGRAL_TYPE_P (lhstype)
1314 || TYPE_OVERFLOW_WRAPS (lhstype)
1315 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1316 return;
1318 switch (code)
1320 case MINUS_EXPR:
1321 case PLUS_EXPR:
1322 case MULT_EXPR:
1323 /* Transform
1324 i = u {+,-,*} 5;
1325 into
1326 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1327 a = gimple_assign_rhs1 (stmt);
1328 b = gimple_assign_rhs2 (stmt);
1329 g = gimple_build_call_internal (code == PLUS_EXPR
1330 ? IFN_UBSAN_CHECK_ADD
1331 : code == MINUS_EXPR
1332 ? IFN_UBSAN_CHECK_SUB
1333 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1334 gimple_call_set_lhs (g, lhs);
1335 gsi_replace (&gsi, g, false);
1336 break;
1337 case NEGATE_EXPR:
1338 /* Represent i = -u;
1340 i = UBSAN_CHECK_SUB (0, u); */
1341 a = build_int_cst (lhstype, 0);
1342 b = gimple_assign_rhs1 (stmt);
1343 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1344 gimple_call_set_lhs (g, lhs);
1345 gsi_replace (&gsi, g, false);
1346 break;
1347 case ABS_EXPR:
1348 /* Transform i = ABS_EXPR<u>;
1349 into
1350 _N = UBSAN_CHECK_SUB (0, u);
1351 i = ABS_EXPR<_N>; */
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 a = make_ssa_name (lhstype);
1356 gimple_call_set_lhs (g, a);
1357 gimple_set_location (g, gimple_location (stmt));
1358 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1359 gimple_assign_set_rhs1 (stmt, a);
1360 update_stmt (stmt);
1361 break;
1362 default:
1363 break;
1367 /* Instrument loads from (non-bitfield) bool and C++ enum values
1368 to check if the memory value is outside of the range of the valid
1369 type values. */
1371 static void
1372 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1374 gimple stmt = gsi_stmt (*gsi);
1375 tree rhs = gimple_assign_rhs1 (stmt);
1376 tree type = TREE_TYPE (rhs);
1377 tree minv = NULL_TREE, maxv = NULL_TREE;
1379 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1381 minv = boolean_false_node;
1382 maxv = boolean_true_node;
1384 else if (TREE_CODE (type) == ENUMERAL_TYPE
1385 && (flag_sanitize & SANITIZE_ENUM)
1386 && TREE_TYPE (type) != NULL_TREE
1387 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1388 && (TYPE_PRECISION (TREE_TYPE (type))
1389 < GET_MODE_PRECISION (TYPE_MODE (type))))
1391 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1392 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1394 else
1395 return;
1397 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1398 HOST_WIDE_INT bitsize, bitpos;
1399 tree offset;
1400 machine_mode mode;
1401 int volatilep = 0, unsignedp = 0;
1402 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1403 &unsignedp, &volatilep, false);
1404 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1406 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1407 || (bitpos % modebitsize) != 0
1408 || bitsize != modebitsize
1409 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1410 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1411 return;
1413 bool ends_bb = stmt_ends_bb_p (stmt);
1414 location_t loc = gimple_location (stmt);
1415 tree lhs = gimple_assign_lhs (stmt);
1416 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1417 tree atype = reference_alias_ptr_type (rhs);
1418 gimple g = gimple_build_assign (make_ssa_name (ptype),
1419 build_fold_addr_expr (rhs));
1420 gimple_set_location (g, loc);
1421 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1422 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1423 build_int_cst (atype, 0));
1424 tree urhs = make_ssa_name (utype);
1425 if (ends_bb)
1427 gimple_assign_set_lhs (stmt, urhs);
1428 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1429 gimple_set_location (g, loc);
1430 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1431 gsi_insert_on_edge_immediate (e, g);
1432 gimple_assign_set_rhs_from_tree (gsi, mem);
1433 update_stmt (stmt);
1434 *gsi = gsi_for_stmt (g);
1435 g = stmt;
1437 else
1439 g = gimple_build_assign (urhs, mem);
1440 gimple_set_location (g, loc);
1441 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1443 minv = fold_convert (utype, minv);
1444 maxv = fold_convert (utype, maxv);
1445 if (!integer_zerop (minv))
1447 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1448 gimple_set_location (g, loc);
1449 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1452 gimple_stmt_iterator gsi2 = *gsi;
1453 basic_block then_bb, fallthru_bb;
1454 *gsi = create_cond_insert_point (gsi, true, false, true,
1455 &then_bb, &fallthru_bb);
1456 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1457 int_const_binop (MINUS_EXPR, maxv, minv),
1458 NULL_TREE, NULL_TREE);
1459 gimple_set_location (g, loc);
1460 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1462 if (!ends_bb)
1464 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1465 update_stmt (stmt);
1468 gsi2 = gsi_after_labels (then_bb);
1469 if (flag_sanitize_undefined_trap_on_error)
1470 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1471 else
1473 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1474 ubsan_type_descriptor (type), NULL_TREE,
1475 NULL_TREE);
1476 data = build_fold_addr_expr_loc (loc, data);
1477 enum built_in_function bcode
1478 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1479 ? SANITIZE_BOOL : SANITIZE_ENUM))
1480 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1481 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1482 tree fn = builtin_decl_explicit (bcode);
1484 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1485 true, NULL_TREE, true,
1486 GSI_SAME_STMT);
1487 g = gimple_build_call (fn, 2, data, val);
1489 gimple_set_location (g, loc);
1490 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1491 ubsan_create_edge (g);
1492 *gsi = gsi_for_stmt (stmt);
1495 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1496 destination, EXPR is floating-point expression. ARG is what to pass
1497 the libubsan call as value, often EXPR itself. */
1499 tree
1500 ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
1502 tree expr_type = TREE_TYPE (expr);
1503 tree t, tt, fn, min, max;
1504 machine_mode mode = TYPE_MODE (expr_type);
1505 int prec = TYPE_PRECISION (type);
1506 bool uns_p = TYPE_UNSIGNED (type);
1508 /* Float to integer conversion first truncates toward zero, so
1509 even signed char c = 127.875f; is not problematic.
1510 Therefore, we should complain only if EXPR is unordered or smaller
1511 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1512 TYPE_MAX_VALUE + 1.0. */
1513 if (REAL_MODE_FORMAT (mode)->b == 2)
1515 /* For maximum, TYPE_MAX_VALUE might not be representable
1516 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1517 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1518 either representable or infinity. */
1519 REAL_VALUE_TYPE maxval = dconst1;
1520 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1521 real_convert (&maxval, mode, &maxval);
1522 max = build_real (expr_type, maxval);
1524 /* For unsigned, assume -1.0 is always representable. */
1525 if (uns_p)
1526 min = build_minus_one_cst (expr_type);
1527 else
1529 /* TYPE_MIN_VALUE is generally representable (or -inf),
1530 but TYPE_MIN_VALUE - 1.0 might not be. */
1531 REAL_VALUE_TYPE minval = dconstm1, minval2;
1532 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1533 real_convert (&minval, mode, &minval);
1534 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1535 real_convert (&minval2, mode, &minval2);
1536 if (real_compare (EQ_EXPR, &minval, &minval2)
1537 && !real_isinf (&minval))
1539 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1540 rounds to TYPE_MIN_VALUE, we need to subtract
1541 more. As REAL_MODE_FORMAT (mode)->p is the number
1542 of base digits, we want to subtract a number that
1543 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1544 times smaller than minval. */
1545 minval2 = dconst1;
1546 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1547 SET_REAL_EXP (&minval2,
1548 REAL_EXP (&minval2) + prec - 1
1549 - REAL_MODE_FORMAT (mode)->p + 1);
1550 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1551 real_convert (&minval2, mode, &minval2);
1553 min = build_real (expr_type, minval2);
1556 else if (REAL_MODE_FORMAT (mode)->b == 10)
1558 /* For _Decimal128 up to 34 decimal digits, - sign,
1559 dot, e, exponent. */
1560 char buf[64];
1561 mpfr_t m;
1562 int p = REAL_MODE_FORMAT (mode)->p;
1563 REAL_VALUE_TYPE maxval, minval;
1565 /* Use mpfr_snprintf rounding to compute the smallest
1566 representable decimal number greater or equal than
1567 1 << (prec - !uns_p). */
1568 mpfr_init2 (m, prec + 2);
1569 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1570 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1571 decimal_real_from_string (&maxval, buf);
1572 max = build_real (expr_type, maxval);
1574 /* For unsigned, assume -1.0 is always representable. */
1575 if (uns_p)
1576 min = build_minus_one_cst (expr_type);
1577 else
1579 /* Use mpfr_snprintf rounding to compute the largest
1580 representable decimal number less or equal than
1581 (-1 << (prec - 1)) - 1. */
1582 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1583 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1584 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1585 decimal_real_from_string (&minval, buf);
1586 min = build_real (expr_type, minval);
1588 mpfr_clear (m);
1590 else
1591 return NULL_TREE;
1593 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1594 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1595 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1596 if (integer_zerop (t))
1597 return NULL_TREE;
1599 if (flag_sanitize_undefined_trap_on_error)
1600 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1601 else
1603 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1604 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1605 NULL, ubsan_type_descriptor (expr_type),
1606 ubsan_type_descriptor (type), NULL_TREE,
1607 NULL_TREE);
1608 enum built_in_function bcode
1609 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1610 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1611 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1612 fn = builtin_decl_explicit (bcode);
1613 fn = build_call_expr_loc (loc, fn, 2,
1614 build_fold_addr_expr_loc (loc, data),
1615 ubsan_encode_value (arg, false));
1618 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1621 /* Instrument values passed to function arguments with nonnull attribute. */
1623 static void
1624 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1626 gimple stmt = gsi_stmt (*gsi);
1627 location_t loc[2];
1628 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1629 while for nonnull sanitization it is clear. */
1630 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1631 flag_delete_null_pointer_checks = 1;
1632 loc[0] = gimple_location (stmt);
1633 loc[1] = UNKNOWN_LOCATION;
1634 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1636 tree arg = gimple_call_arg (stmt, i);
1637 if (POINTER_TYPE_P (TREE_TYPE (arg))
1638 && infer_nonnull_range (stmt, arg, false, true))
1640 gimple g;
1641 if (!is_gimple_val (arg))
1643 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1644 gimple_set_location (g, loc[0]);
1645 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1646 arg = gimple_assign_lhs (g);
1649 basic_block then_bb, fallthru_bb;
1650 *gsi = create_cond_insert_point (gsi, true, false, true,
1651 &then_bb, &fallthru_bb);
1652 g = gimple_build_cond (EQ_EXPR, arg,
1653 build_zero_cst (TREE_TYPE (arg)),
1654 NULL_TREE, NULL_TREE);
1655 gimple_set_location (g, loc[0]);
1656 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1658 *gsi = gsi_after_labels (then_bb);
1659 if (flag_sanitize_undefined_trap_on_error)
1660 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1661 else
1663 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1664 2, loc, NULL_TREE,
1665 build_int_cst (integer_type_node,
1666 i + 1),
1667 NULL_TREE);
1668 data = build_fold_addr_expr_loc (loc[0], data);
1669 enum built_in_function bcode
1670 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1671 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1672 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1673 tree fn = builtin_decl_explicit (bcode);
1675 g = gimple_build_call (fn, 1, data);
1677 gimple_set_location (g, loc[0]);
1678 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1679 ubsan_create_edge (g);
1681 *gsi = gsi_for_stmt (stmt);
1683 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1686 /* Instrument returns in functions with returns_nonnull attribute. */
1688 static void
1689 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1691 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1692 location_t loc[2];
1693 tree arg = gimple_return_retval (stmt);
1694 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1695 while for nonnull return sanitization it is clear. */
1696 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1697 flag_delete_null_pointer_checks = 1;
1698 loc[0] = gimple_location (stmt);
1699 loc[1] = UNKNOWN_LOCATION;
1700 if (arg
1701 && POINTER_TYPE_P (TREE_TYPE (arg))
1702 && is_gimple_val (arg)
1703 && infer_nonnull_range (stmt, arg, false, true))
1705 basic_block then_bb, fallthru_bb;
1706 *gsi = create_cond_insert_point (gsi, true, false, true,
1707 &then_bb, &fallthru_bb);
1708 gimple g = gimple_build_cond (EQ_EXPR, arg,
1709 build_zero_cst (TREE_TYPE (arg)),
1710 NULL_TREE, NULL_TREE);
1711 gimple_set_location (g, loc[0]);
1712 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1714 *gsi = gsi_after_labels (then_bb);
1715 if (flag_sanitize_undefined_trap_on_error)
1716 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1717 else
1719 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1720 2, loc, NULL_TREE, NULL_TREE);
1721 data = build_fold_addr_expr_loc (loc[0], data);
1722 enum built_in_function bcode
1723 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1724 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1725 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1726 tree fn = builtin_decl_explicit (bcode);
1728 g = gimple_build_call (fn, 1, data);
1730 gimple_set_location (g, loc[0]);
1731 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1732 ubsan_create_edge (g);
1733 *gsi = gsi_for_stmt (stmt);
1735 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1738 /* Instrument memory references. Here we check whether the pointer
1739 points to an out-of-bounds location. */
1741 static void
1742 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1744 gimple stmt = gsi_stmt (*gsi);
1745 location_t loc = gimple_location (stmt);
1746 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1747 tree type;
1748 tree index = NULL_TREE;
1749 HOST_WIDE_INT size_in_bytes;
1751 type = TREE_TYPE (t);
1752 if (VOID_TYPE_P (type))
1753 return;
1755 switch (TREE_CODE (t))
1757 case COMPONENT_REF:
1758 if (TREE_CODE (t) == COMPONENT_REF
1759 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1761 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1762 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1763 repr, NULL_TREE);
1765 break;
1766 case ARRAY_REF:
1767 index = TREE_OPERAND (t, 1);
1768 break;
1769 case INDIRECT_REF:
1770 case MEM_REF:
1771 case VAR_DECL:
1772 case PARM_DECL:
1773 case RESULT_DECL:
1774 break;
1775 default:
1776 return;
1779 size_in_bytes = int_size_in_bytes (type);
1780 if (size_in_bytes <= 0)
1781 return;
1783 HOST_WIDE_INT bitsize, bitpos;
1784 tree offset;
1785 machine_mode mode;
1786 int volatilep = 0, unsignedp = 0;
1787 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1788 &unsignedp, &volatilep, false);
1790 if (bitpos % BITS_PER_UNIT != 0
1791 || bitsize != size_in_bytes * BITS_PER_UNIT)
1792 return;
1794 bool decl_p = DECL_P (inner);
1795 tree base;
1796 if (decl_p)
1797 base = inner;
1798 else if (TREE_CODE (inner) == MEM_REF)
1799 base = TREE_OPERAND (inner, 0);
1800 else
1801 return;
1802 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1804 while (TREE_CODE (base) == SSA_NAME)
1806 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1807 if (gimple_assign_ssa_name_copy_p (def_stmt)
1808 || (gimple_assign_cast_p (def_stmt)
1809 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1810 || (is_gimple_assign (def_stmt)
1811 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1813 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1814 if (TREE_CODE (rhs1) == SSA_NAME
1815 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1816 break;
1817 else
1818 base = rhs1;
1820 else
1821 break;
1824 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1825 return;
1827 tree sizet;
1828 tree base_addr = base;
1829 gimple bos_stmt = NULL;
1830 if (decl_p)
1831 base_addr = build1 (ADDR_EXPR,
1832 build_pointer_type (TREE_TYPE (base)), base);
1833 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1834 if (size != (unsigned HOST_WIDE_INT) -1)
1835 sizet = build_int_cst (sizetype, size);
1836 else if (optimize)
1838 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1839 loc = input_location;
1840 /* Generate __builtin_object_size call. */
1841 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1842 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1843 integer_zero_node);
1844 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1845 GSI_SAME_STMT);
1846 /* If the call above didn't end up being an integer constant, go one
1847 statement back and get the __builtin_object_size stmt. Save it,
1848 we might need it later. */
1849 if (SSA_VAR_P (sizet))
1851 gsi_prev (gsi);
1852 bos_stmt = gsi_stmt (*gsi);
1854 /* Move on to where we were. */
1855 gsi_next (gsi);
1858 else
1859 return;
1861 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1862 call. */
1863 /* ptr + sizeof (*ptr) - base */
1864 t = fold_build2 (MINUS_EXPR, sizetype,
1865 fold_convert (pointer_sized_int_node, ptr),
1866 fold_convert (pointer_sized_int_node, base_addr));
1867 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1869 /* Perhaps we can omit the check. */
1870 if (TREE_CODE (t) == INTEGER_CST
1871 && TREE_CODE (sizet) == INTEGER_CST
1872 && tree_int_cst_le (t, sizet))
1873 return;
1875 if (index != NULL_TREE
1876 && TREE_CODE (index) == SSA_NAME
1877 && TREE_CODE (sizet) == INTEGER_CST)
1879 gimple def = SSA_NAME_DEF_STMT (index);
1880 if (is_gimple_assign (def)
1881 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1882 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1884 tree cst = gimple_assign_rhs2 (def);
1885 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1886 TYPE_SIZE_UNIT (type));
1887 if (tree_int_cst_sgn (cst) >= 0
1888 && tree_int_cst_lt (cst, sz))
1889 return;
1893 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1894 ubsan_create_edge (bos_stmt);
1896 /* We have to emit the check. */
1897 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1898 GSI_SAME_STMT);
1899 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1900 GSI_SAME_STMT);
1901 tree ckind = build_int_cst (unsigned_char_type_node,
1902 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1903 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1904 ptr, t, sizet, ckind);
1905 gimple_set_location (g, loc);
1906 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1909 /* True if we want to play UBSan games in the current function. */
1911 bool
1912 do_ubsan_in_current_function ()
1914 return (current_function_decl != NULL_TREE
1915 && !lookup_attribute ("no_sanitize_undefined",
1916 DECL_ATTRIBUTES (current_function_decl)));
1919 namespace {
1921 const pass_data pass_data_ubsan =
1923 GIMPLE_PASS, /* type */
1924 "ubsan", /* name */
1925 OPTGROUP_NONE, /* optinfo_flags */
1926 TV_TREE_UBSAN, /* tv_id */
1927 ( PROP_cfg | PROP_ssa ), /* properties_required */
1928 0, /* properties_provided */
1929 0, /* properties_destroyed */
1930 0, /* todo_flags_start */
1931 TODO_update_ssa, /* todo_flags_finish */
1934 class pass_ubsan : public gimple_opt_pass
1936 public:
1937 pass_ubsan (gcc::context *ctxt)
1938 : gimple_opt_pass (pass_data_ubsan, ctxt)
1941 /* opt_pass methods: */
1942 virtual bool gate (function *)
1944 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1945 | SANITIZE_BOOL | SANITIZE_ENUM
1946 | SANITIZE_ALIGNMENT
1947 | SANITIZE_NONNULL_ATTRIBUTE
1948 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1949 | SANITIZE_OBJECT_SIZE)
1950 && do_ubsan_in_current_function ();
1953 virtual unsigned int execute (function *);
1955 }; // class pass_ubsan
1957 unsigned int
1958 pass_ubsan::execute (function *fun)
1960 basic_block bb;
1961 gimple_stmt_iterator gsi;
1963 initialize_sanitizer_builtins ();
1965 FOR_EACH_BB_FN (bb, fun)
1967 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1969 gimple stmt = gsi_stmt (gsi);
1970 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1972 gsi_next (&gsi);
1973 continue;
1976 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1977 && is_gimple_assign (stmt))
1978 instrument_si_overflow (gsi);
1980 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1982 if (gimple_store_p (stmt))
1983 instrument_null (gsi, true);
1984 if (gimple_assign_load_p (stmt))
1985 instrument_null (gsi, false);
1988 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1989 && gimple_assign_load_p (stmt))
1991 instrument_bool_enum_load (&gsi);
1992 bb = gimple_bb (stmt);
1995 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1996 && is_gimple_call (stmt)
1997 && !gimple_call_internal_p (stmt))
1999 instrument_nonnull_arg (&gsi);
2000 bb = gimple_bb (stmt);
2003 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2004 && gimple_code (stmt) == GIMPLE_RETURN)
2006 instrument_nonnull_return (&gsi);
2007 bb = gimple_bb (stmt);
2010 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2012 if (gimple_store_p (stmt))
2013 instrument_object_size (&gsi, true);
2014 if (gimple_assign_load_p (stmt))
2015 instrument_object_size (&gsi, false);
2018 gsi_next (&gsi);
2021 return 0;
2024 } // anon namespace
2026 gimple_opt_pass *
2027 make_pass_ubsan (gcc::context *ctxt)
2029 return new pass_ubsan (ctxt);
2032 #include "gt-ubsan.h"