Update ChangeLog and version files for release
[official-gcc.git] / gcc / ubsan.c
blob701e9f292289ba48d3ab03af8e5e7e5abb51438d
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"
91 /* Map from a tree to a VAR_DECL tree. */
93 struct GTY((for_user)) tree_type_map {
94 struct tree_map_base type;
95 tree decl;
98 struct tree_type_map_cache_hasher : ggc_cache_hasher<tree_type_map *>
100 static inline hashval_t
101 hash (tree_type_map *t)
103 return TYPE_UID (t->type.from);
106 static inline bool
107 equal (tree_type_map *a, tree_type_map *b)
109 return a->type.from == b->type.from;
112 static void
113 handle_cache_entry (tree_type_map *&m)
115 extern void gt_ggc_mx (tree_type_map *&);
116 if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
117 return;
118 else if (ggc_marked_p (m->type.from))
119 gt_ggc_mx (m);
120 else
121 m = static_cast<tree_type_map *> (HTAB_DELETED_ENTRY);
125 static GTY ((cache))
126 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
128 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
130 static tree
131 decl_for_type_lookup (tree type)
133 /* If the hash table is not initialized yet, create it now. */
134 if (decl_tree_for_type == NULL)
136 decl_tree_for_type
137 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
138 /* That also means we don't have to bother with the lookup. */
139 return NULL_TREE;
142 struct tree_type_map *h, in;
143 in.type.from = type;
145 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
146 return h ? h->decl : NULL_TREE;
149 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
151 static void
152 decl_for_type_insert (tree type, tree decl)
154 struct tree_type_map *h;
156 h = ggc_alloc<tree_type_map> ();
157 h->type.from = type;
158 h->decl = decl;
159 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
162 /* Helper routine, which encodes a value in the pointer_sized_int_node.
163 Arguments with precision <= POINTER_SIZE are passed directly,
164 the rest is passed by reference. T is a value we are to encode.
165 IN_EXPAND_P is true if this function is called during expansion. */
167 tree
168 ubsan_encode_value (tree t, bool in_expand_p)
170 tree type = TREE_TYPE (t);
171 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
172 if (bitsize <= POINTER_SIZE)
173 switch (TREE_CODE (type))
175 case BOOLEAN_TYPE:
176 case ENUMERAL_TYPE:
177 case INTEGER_TYPE:
178 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
179 case REAL_TYPE:
181 tree itype = build_nonstandard_integer_type (bitsize, true);
182 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
183 return fold_convert (pointer_sized_int_node, t);
185 default:
186 gcc_unreachable ();
188 else
190 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
192 /* The reason for this is that we don't want to pessimize
193 code by making vars unnecessarily addressable. */
194 tree var = create_tmp_var (type);
195 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
196 if (in_expand_p)
198 rtx mem
199 = assign_stack_temp_for_type (TYPE_MODE (type),
200 GET_MODE_SIZE (TYPE_MODE (type)),
201 type);
202 SET_DECL_RTL (var, mem);
203 expand_assignment (var, t, false);
204 return build_fold_addr_expr (var);
206 t = build_fold_addr_expr (var);
207 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
209 else
210 return build_fold_addr_expr (t);
214 /* Cached ubsan_get_type_descriptor_type () return value. */
215 static GTY(()) tree ubsan_type_descriptor_type;
217 /* Build
218 struct __ubsan_type_descriptor
220 unsigned short __typekind;
221 unsigned short __typeinfo;
222 char __typename[];
224 type. */
226 static tree
227 ubsan_get_type_descriptor_type (void)
229 static const char *field_names[3]
230 = { "__typekind", "__typeinfo", "__typename" };
231 tree fields[3], ret;
233 if (ubsan_type_descriptor_type)
234 return ubsan_type_descriptor_type;
236 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
237 tree flex_arr_type = build_array_type (char_type_node, itype);
239 ret = make_node (RECORD_TYPE);
240 for (int i = 0; i < 3; i++)
242 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
243 get_identifier (field_names[i]),
244 (i == 2) ? flex_arr_type
245 : short_unsigned_type_node);
246 DECL_CONTEXT (fields[i]) = ret;
247 if (i)
248 DECL_CHAIN (fields[i - 1]) = fields[i];
250 tree type_decl = build_decl (input_location, TYPE_DECL,
251 get_identifier ("__ubsan_type_descriptor"),
252 ret);
253 DECL_IGNORED_P (type_decl) = 1;
254 DECL_ARTIFICIAL (type_decl) = 1;
255 TYPE_FIELDS (ret) = fields[0];
256 TYPE_NAME (ret) = type_decl;
257 TYPE_STUB_DECL (ret) = type_decl;
258 layout_type (ret);
259 ubsan_type_descriptor_type = ret;
260 return ret;
263 /* Cached ubsan_get_source_location_type () return value. */
264 static GTY(()) tree ubsan_source_location_type;
266 /* Build
267 struct __ubsan_source_location
269 const char *__filename;
270 unsigned int __line;
271 unsigned int __column;
273 type. */
275 tree
276 ubsan_get_source_location_type (void)
278 static const char *field_names[3]
279 = { "__filename", "__line", "__column" };
280 tree fields[3], ret;
281 if (ubsan_source_location_type)
282 return ubsan_source_location_type;
284 tree const_char_type = build_qualified_type (char_type_node,
285 TYPE_QUAL_CONST);
287 ret = make_node (RECORD_TYPE);
288 for (int i = 0; i < 3; i++)
290 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
291 get_identifier (field_names[i]),
292 (i == 0) ? build_pointer_type (const_char_type)
293 : unsigned_type_node);
294 DECL_CONTEXT (fields[i]) = ret;
295 if (i)
296 DECL_CHAIN (fields[i - 1]) = fields[i];
298 tree type_decl = build_decl (input_location, TYPE_DECL,
299 get_identifier ("__ubsan_source_location"),
300 ret);
301 DECL_IGNORED_P (type_decl) = 1;
302 DECL_ARTIFICIAL (type_decl) = 1;
303 TYPE_FIELDS (ret) = fields[0];
304 TYPE_NAME (ret) = type_decl;
305 TYPE_STUB_DECL (ret) = type_decl;
306 layout_type (ret);
307 ubsan_source_location_type = ret;
308 return ret;
311 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
312 type with its fields filled from a location_t LOC. */
314 static tree
315 ubsan_source_location (location_t loc)
317 expanded_location xloc;
318 tree type = ubsan_get_source_location_type ();
320 xloc = expand_location (loc);
321 tree str;
322 if (xloc.file == NULL)
324 str = build_int_cst (ptr_type_node, 0);
325 xloc.line = 0;
326 xloc.column = 0;
328 else
330 /* Fill in the values from LOC. */
331 size_t len = strlen (xloc.file) + 1;
332 str = build_string (len, xloc.file);
333 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
334 TREE_READONLY (str) = 1;
335 TREE_STATIC (str) = 1;
336 str = build_fold_addr_expr (str);
338 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
339 build_int_cst (unsigned_type_node,
340 xloc.line), NULL_TREE,
341 build_int_cst (unsigned_type_node,
342 xloc.column));
343 TREE_CONSTANT (ctor) = 1;
344 TREE_STATIC (ctor) = 1;
346 return ctor;
349 /* This routine returns a magic number for TYPE. */
351 static unsigned short
352 get_ubsan_type_info_for_type (tree type)
354 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
355 if (TREE_CODE (type) == REAL_TYPE)
356 return tree_to_uhwi (TYPE_SIZE (type));
357 else if (INTEGRAL_TYPE_P (type))
359 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
360 gcc_assert (prec != -1);
361 return (prec << 1) | !TYPE_UNSIGNED (type);
363 else
364 return 0;
367 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
368 descriptor. It first looks into the hash table; if not found,
369 create the VAR_DECL, put it into the hash table and return the
370 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
371 an enum controlling how we want to print the type. */
373 tree
374 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
376 /* See through any typedefs. */
377 type = TYPE_MAIN_VARIANT (type);
379 tree decl = decl_for_type_lookup (type);
380 /* It is possible that some of the earlier created DECLs were found
381 unused, in that case they weren't emitted and varpool_node::get
382 returns NULL node on them. But now we really need them. Thus,
383 renew them here. */
384 if (decl != NULL_TREE && varpool_node::get (decl))
385 return build_fold_addr_expr (decl);
387 tree dtype = ubsan_get_type_descriptor_type ();
388 tree type2 = type;
389 const char *tname = NULL;
390 pretty_printer pretty_name;
391 unsigned char deref_depth = 0;
392 unsigned short tkind, tinfo;
394 /* Get the name of the type, or the name of the pointer type. */
395 if (pstyle == UBSAN_PRINT_POINTER)
397 gcc_assert (POINTER_TYPE_P (type));
398 type2 = TREE_TYPE (type);
400 /* Remove any '*' operators from TYPE. */
401 while (POINTER_TYPE_P (type2))
402 deref_depth++, type2 = TREE_TYPE (type2);
404 if (TREE_CODE (type2) == METHOD_TYPE)
405 type2 = TYPE_METHOD_BASETYPE (type2);
408 /* If an array, get its type. */
409 type2 = strip_array_types (type2);
411 if (pstyle == UBSAN_PRINT_ARRAY)
413 while (POINTER_TYPE_P (type2))
414 deref_depth++, type2 = TREE_TYPE (type2);
417 if (TYPE_NAME (type2) != NULL)
419 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
420 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
421 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
422 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
425 if (tname == NULL)
426 /* We weren't able to determine the type name. */
427 tname = "<unknown>";
429 if (pstyle == UBSAN_PRINT_POINTER)
431 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
432 TYPE_VOLATILE (type2) ? "volatile " : "",
433 TYPE_READONLY (type2) ? "const " : "",
434 TYPE_RESTRICT (type2) ? "restrict " : "",
435 TYPE_ATOMIC (type2) ? "_Atomic " : "",
436 TREE_CODE (type2) == RECORD_TYPE
437 ? "struct "
438 : TREE_CODE (type2) == UNION_TYPE
439 ? "union " : "", tname,
440 deref_depth == 0 ? "" : " ");
441 while (deref_depth-- > 0)
442 pp_star (&pretty_name);
443 pp_quote (&pretty_name);
445 else if (pstyle == UBSAN_PRINT_ARRAY)
447 /* Pretty print the array dimensions. */
448 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
449 tree t = type;
450 pp_printf (&pretty_name, "'%s ", tname);
451 while (deref_depth-- > 0)
452 pp_star (&pretty_name);
453 while (TREE_CODE (t) == ARRAY_TYPE)
455 pp_left_bracket (&pretty_name);
456 tree dom = TYPE_DOMAIN (t);
457 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
459 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
460 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
461 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
462 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
463 else
464 pp_wide_int (&pretty_name,
465 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
466 TYPE_SIGN (TREE_TYPE (dom)));
468 else
469 /* ??? We can't determine the variable name; print VLA unspec. */
470 pp_star (&pretty_name);
471 pp_right_bracket (&pretty_name);
472 t = TREE_TYPE (t);
474 pp_quote (&pretty_name);
476 /* Save the tree with stripped types. */
477 type = t;
479 else
480 pp_printf (&pretty_name, "'%s'", tname);
482 switch (TREE_CODE (type))
484 case BOOLEAN_TYPE:
485 case ENUMERAL_TYPE:
486 case INTEGER_TYPE:
487 tkind = 0x0000;
488 break;
489 case REAL_TYPE:
490 /* FIXME: libubsan right now only supports float, double and
491 long double type formats. */
492 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
493 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
494 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
495 tkind = 0x0001;
496 else
497 tkind = 0xffff;
498 break;
499 default:
500 tkind = 0xffff;
501 break;
503 tinfo = get_ubsan_type_info_for_type (type);
505 /* Create a new VAR_DECL of type descriptor. */
506 const char *tmp = pp_formatted_text (&pretty_name);
507 size_t len = strlen (tmp) + 1;
508 tree str = build_string (len, tmp);
509 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
510 TREE_READONLY (str) = 1;
511 TREE_STATIC (str) = 1;
513 char tmp_name[32];
514 static unsigned int type_var_id_num;
515 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
516 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
517 dtype);
518 TREE_STATIC (decl) = 1;
519 TREE_PUBLIC (decl) = 0;
520 DECL_ARTIFICIAL (decl) = 1;
521 DECL_IGNORED_P (decl) = 1;
522 DECL_EXTERNAL (decl) = 0;
523 DECL_SIZE (decl)
524 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
525 DECL_SIZE_UNIT (decl)
526 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
527 TYPE_SIZE_UNIT (TREE_TYPE (str)));
529 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
530 build_int_cst (short_unsigned_type_node,
531 tkind), NULL_TREE,
532 build_int_cst (short_unsigned_type_node,
533 tinfo), NULL_TREE, str);
534 TREE_CONSTANT (ctor) = 1;
535 TREE_STATIC (ctor) = 1;
536 DECL_INITIAL (decl) = ctor;
537 varpool_node::finalize_decl (decl);
539 /* Save the VAR_DECL into the hash table. */
540 decl_for_type_insert (type, decl);
542 return build_fold_addr_expr (decl);
545 /* Create a structure for the ubsan library. NAME is a name of the new
546 structure. LOCCNT is number of locations, PLOC points to array of
547 locations. The arguments in ... are of __ubsan_type_descriptor type
548 and there are at most two of them, followed by NULL_TREE, followed
549 by optional extra arguments and another NULL_TREE. */
551 tree
552 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
554 va_list args;
555 tree ret, t;
556 tree fields[6];
557 vec<tree, va_gc> *saved_args = NULL;
558 size_t i = 0;
559 int j;
561 /* Firstly, create a pointer to type descriptor type. */
562 tree td_type = ubsan_get_type_descriptor_type ();
563 td_type = build_pointer_type (td_type);
565 /* Create the structure type. */
566 ret = make_node (RECORD_TYPE);
567 for (j = 0; j < loccnt; j++)
569 gcc_checking_assert (i < 2);
570 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
571 ubsan_get_source_location_type ());
572 DECL_CONTEXT (fields[i]) = ret;
573 if (i)
574 DECL_CHAIN (fields[i - 1]) = fields[i];
575 i++;
578 va_start (args, ploc);
579 for (t = va_arg (args, tree); t != NULL_TREE;
580 i++, t = va_arg (args, tree))
582 gcc_checking_assert (i < 4);
583 /* Save the tree arguments for later use. */
584 vec_safe_push (saved_args, t);
585 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
586 td_type);
587 DECL_CONTEXT (fields[i]) = ret;
588 if (i)
589 DECL_CHAIN (fields[i - 1]) = fields[i];
592 for (t = va_arg (args, tree); t != NULL_TREE;
593 i++, t = va_arg (args, tree))
595 gcc_checking_assert (i < 6);
596 /* Save the tree arguments for later use. */
597 vec_safe_push (saved_args, t);
598 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
599 TREE_TYPE (t));
600 DECL_CONTEXT (fields[i]) = ret;
601 if (i)
602 DECL_CHAIN (fields[i - 1]) = fields[i];
604 va_end (args);
606 tree type_decl = build_decl (input_location, TYPE_DECL,
607 get_identifier (name), ret);
608 DECL_IGNORED_P (type_decl) = 1;
609 DECL_ARTIFICIAL (type_decl) = 1;
610 TYPE_FIELDS (ret) = fields[0];
611 TYPE_NAME (ret) = type_decl;
612 TYPE_STUB_DECL (ret) = type_decl;
613 layout_type (ret);
615 /* Now, fill in the type. */
616 char tmp_name[32];
617 static unsigned int ubsan_var_id_num;
618 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
619 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
620 ret);
621 TREE_STATIC (var) = 1;
622 TREE_PUBLIC (var) = 0;
623 DECL_ARTIFICIAL (var) = 1;
624 DECL_IGNORED_P (var) = 1;
625 DECL_EXTERNAL (var) = 0;
627 vec<constructor_elt, va_gc> *v;
628 vec_alloc (v, i);
629 tree ctor = build_constructor (ret, v);
631 /* If desirable, set the __ubsan_source_location element. */
632 for (j = 0; j < loccnt; j++)
634 location_t loc = LOCATION_LOCUS (ploc[j]);
635 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
638 size_t nelts = vec_safe_length (saved_args);
639 for (i = 0; i < nelts; i++)
641 t = (*saved_args)[i];
642 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
645 TREE_CONSTANT (ctor) = 1;
646 TREE_STATIC (ctor) = 1;
647 DECL_INITIAL (var) = ctor;
648 varpool_node::finalize_decl (var);
650 return var;
653 /* Instrument the __builtin_unreachable call. We just call the libubsan
654 routine instead. */
656 bool
657 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
659 gimple g;
660 location_t loc = gimple_location (gsi_stmt (*gsi));
662 if (flag_sanitize_undefined_trap_on_error)
663 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
664 else
666 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
667 NULL_TREE, NULL_TREE);
668 data = build_fold_addr_expr_loc (loc, data);
669 tree fn
670 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
671 g = gimple_build_call (fn, 1, data);
673 gimple_set_location (g, loc);
674 gsi_replace (gsi, g, false);
675 return false;
678 /* Return true if T is a call to a libubsan routine. */
680 bool
681 is_ubsan_builtin_p (tree t)
683 return TREE_CODE (t) == FUNCTION_DECL
684 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
685 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
686 "__builtin___ubsan_", 18) == 0;
689 /* Create a callgraph edge for statement STMT. */
691 static void
692 ubsan_create_edge (gimple stmt)
694 gcall *call_stmt = dyn_cast <gcall *> (stmt);
695 basic_block bb = gimple_bb (stmt);
696 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
697 cgraph_node *node = cgraph_node::get (current_function_decl);
698 tree decl = gimple_call_fndecl (call_stmt);
699 if (decl)
700 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
701 freq);
704 /* Expand the UBSAN_BOUNDS special builtin function. */
706 bool
707 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
709 gimple stmt = gsi_stmt (*gsi);
710 location_t loc = gimple_location (stmt);
711 gcc_assert (gimple_call_num_args (stmt) == 3);
713 /* Pick up the arguments of the UBSAN_BOUNDS call. */
714 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
715 tree index = gimple_call_arg (stmt, 1);
716 tree orig_index_type = TREE_TYPE (index);
717 tree bound = gimple_call_arg (stmt, 2);
719 gimple_stmt_iterator gsi_orig = *gsi;
721 /* Create condition "if (index > bound)". */
722 basic_block then_bb, fallthru_bb;
723 gimple_stmt_iterator cond_insert_point
724 = create_cond_insert_point (gsi, false, false, true,
725 &then_bb, &fallthru_bb);
726 index = fold_convert (TREE_TYPE (bound), index);
727 index = force_gimple_operand_gsi (&cond_insert_point, index,
728 true, NULL_TREE,
729 false, GSI_NEW_STMT);
730 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
731 gimple_set_location (g, loc);
732 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
734 /* Generate __ubsan_handle_out_of_bounds call. */
735 *gsi = gsi_after_labels (then_bb);
736 if (flag_sanitize_undefined_trap_on_error)
737 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
738 else
740 tree data
741 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
742 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
743 ubsan_type_descriptor (orig_index_type),
744 NULL_TREE, NULL_TREE);
745 data = build_fold_addr_expr_loc (loc, data);
746 enum built_in_function bcode
747 = (flag_sanitize_recover & SANITIZE_BOUNDS)
748 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
749 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
750 tree fn = builtin_decl_explicit (bcode);
751 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
752 true, NULL_TREE, true,
753 GSI_SAME_STMT);
754 g = gimple_build_call (fn, 2, data, val);
756 gimple_set_location (g, loc);
757 gsi_insert_before (gsi, g, GSI_SAME_STMT);
759 /* Get rid of the UBSAN_BOUNDS call from the IR. */
760 unlink_stmt_vdef (stmt);
761 gsi_remove (&gsi_orig, true);
763 /* Point GSI to next logical statement. */
764 *gsi = gsi_start_bb (fallthru_bb);
765 return true;
768 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
769 argument which is a constant, because the middle-end treats pointer
770 conversions as useless and therefore the type of the first argument
771 could be changed to any other pointer type. */
773 bool
774 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
776 gimple_stmt_iterator gsi = *gsip;
777 gimple stmt = gsi_stmt (gsi);
778 location_t loc = gimple_location (stmt);
779 gcc_assert (gimple_call_num_args (stmt) == 3);
780 tree ptr = gimple_call_arg (stmt, 0);
781 tree ckind = gimple_call_arg (stmt, 1);
782 tree align = gimple_call_arg (stmt, 2);
783 tree check_align = NULL_TREE;
784 bool check_null;
786 basic_block cur_bb = gsi_bb (gsi);
788 gimple g;
789 if (!integer_zerop (align))
791 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
792 if (compare_tree_int (align, ptralign) == 1)
794 check_align = make_ssa_name (pointer_sized_int_node);
795 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
796 gimple_set_location (g, loc);
797 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
800 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
802 if (check_align == NULL_TREE && !check_null)
804 gsi_remove (gsip, true);
805 /* Unlink the UBSAN_NULLs vops before replacing it. */
806 unlink_stmt_vdef (stmt);
807 return true;
810 /* Split the original block holding the pointer dereference. */
811 edge e = split_block (cur_bb, stmt);
813 /* Get a hold on the 'condition block', the 'then block' and the
814 'else block'. */
815 basic_block cond_bb = e->src;
816 basic_block fallthru_bb = e->dest;
817 basic_block then_bb = create_empty_bb (cond_bb);
818 add_bb_to_loop (then_bb, cond_bb->loop_father);
819 loops_state_set (LOOPS_NEED_FIXUP);
821 /* Make an edge coming from the 'cond block' into the 'then block';
822 this edge is unlikely taken, so set up the probability accordingly. */
823 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
824 e->probability = PROB_VERY_UNLIKELY;
826 /* Connect 'then block' with the 'else block'. This is needed
827 as the ubsan routines we call in the 'then block' are not noreturn.
828 The 'then block' only has one outcoming edge. */
829 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
831 /* Set up the fallthrough basic block. */
832 e = find_edge (cond_bb, fallthru_bb);
833 e->flags = EDGE_FALSE_VALUE;
834 e->count = cond_bb->count;
835 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
837 /* Update dominance info for the newly created then_bb; note that
838 fallthru_bb's dominance info has already been updated by
839 split_block. */
840 if (dom_info_available_p (CDI_DOMINATORS))
841 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
843 /* Put the ubsan builtin call into the newly created BB. */
844 if (flag_sanitize_undefined_trap_on_error)
845 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
846 else
848 enum built_in_function bcode
849 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
850 | (check_null ? SANITIZE_NULL : 0)))
851 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
852 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
853 tree fn = builtin_decl_implicit (bcode);
854 tree data
855 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
856 ubsan_type_descriptor (TREE_TYPE (ckind),
857 UBSAN_PRINT_POINTER),
858 NULL_TREE,
859 align,
860 fold_convert (unsigned_char_type_node, ckind),
861 NULL_TREE);
862 data = build_fold_addr_expr_loc (loc, data);
863 g = gimple_build_call (fn, 2, data,
864 check_align ? check_align
865 : build_zero_cst (pointer_sized_int_node));
867 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
868 gimple_set_location (g, loc);
869 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
871 /* Unlink the UBSAN_NULLs vops before replacing it. */
872 unlink_stmt_vdef (stmt);
874 if (check_null)
876 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
877 NULL_TREE, NULL_TREE);
878 gimple_set_location (g, loc);
880 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
881 gsi_replace (&gsi, g, false);
882 stmt = g;
885 if (check_align)
887 if (check_null)
889 /* Split the block with the condition again. */
890 e = split_block (cond_bb, stmt);
891 basic_block cond1_bb = e->src;
892 basic_block cond2_bb = e->dest;
894 /* Make an edge coming from the 'cond1 block' into the 'then block';
895 this edge is unlikely taken, so set up the probability
896 accordingly. */
897 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
898 e->probability = PROB_VERY_UNLIKELY;
900 /* Set up the fallthrough basic block. */
901 e = find_edge (cond1_bb, cond2_bb);
902 e->flags = EDGE_FALSE_VALUE;
903 e->count = cond1_bb->count;
904 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
906 /* Update dominance info. */
907 if (dom_info_available_p (CDI_DOMINATORS))
909 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
910 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
913 gsi2 = gsi_start_bb (cond2_bb);
916 tree mask = build_int_cst (pointer_sized_int_node,
917 tree_to_uhwi (align) - 1);
918 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
919 BIT_AND_EXPR, check_align, mask);
920 gimple_set_location (g, loc);
921 if (check_null)
922 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
923 else
924 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
926 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
927 build_int_cst (pointer_sized_int_node, 0),
928 NULL_TREE, NULL_TREE);
929 gimple_set_location (g, loc);
930 if (check_null)
931 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
932 else
933 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
934 gsi_replace (&gsi, g, false);
936 return false;
939 #define OBJSZ_MAX_OFFSET (1024 * 16)
941 /* Expand UBSAN_OBJECT_SIZE internal call. */
943 bool
944 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
946 gimple stmt = gsi_stmt (*gsi);
947 location_t loc = gimple_location (stmt);
948 gcc_assert (gimple_call_num_args (stmt) == 4);
950 tree ptr = gimple_call_arg (stmt, 0);
951 tree offset = gimple_call_arg (stmt, 1);
952 tree size = gimple_call_arg (stmt, 2);
953 tree ckind = gimple_call_arg (stmt, 3);
954 gimple_stmt_iterator gsi_orig = *gsi;
955 gimple g;
957 /* See if we can discard the check. */
958 if (TREE_CODE (size) != INTEGER_CST
959 || integer_all_onesp (size))
960 /* Yes, __builtin_object_size couldn't determine the
961 object size. */;
962 else if (TREE_CODE (offset) == INTEGER_CST
963 && wi::ges_p (wi::to_widest (offset), -OBJSZ_MAX_OFFSET)
964 && wi::les_p (wi::to_widest (offset), -1))
965 /* The offset is in range [-16K, -1]. */;
966 else
968 /* if (offset > objsize) */
969 basic_block then_bb, fallthru_bb;
970 gimple_stmt_iterator cond_insert_point
971 = create_cond_insert_point (gsi, false, false, true,
972 &then_bb, &fallthru_bb);
973 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
974 gimple_set_location (g, loc);
975 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
977 /* If the offset is small enough, we don't need the second
978 run-time check. */
979 if (TREE_CODE (offset) == INTEGER_CST
980 && wi::ges_p (wi::to_widest (offset), 0)
981 && wi::les_p (wi::to_widest (offset), OBJSZ_MAX_OFFSET))
982 *gsi = gsi_after_labels (then_bb);
983 else
985 /* Don't issue run-time error if (ptr > ptr + offset). That
986 may happen when computing a POINTER_PLUS_EXPR. */
987 basic_block then2_bb, fallthru2_bb;
989 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
990 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
991 true, &then2_bb,
992 &fallthru2_bb);
993 /* Convert the pointer to an integer type. */
994 tree p = make_ssa_name (pointer_sized_int_node);
995 g = gimple_build_assign (p, NOP_EXPR, ptr);
996 gimple_set_location (g, loc);
997 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
998 p = gimple_assign_lhs (g);
999 /* Compute ptr + offset. */
1000 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1001 PLUS_EXPR, p, offset);
1002 gimple_set_location (g, loc);
1003 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1004 /* Now build the conditional and put it into the IR. */
1005 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
1006 NULL_TREE, NULL_TREE);
1007 gimple_set_location (g, loc);
1008 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1009 *gsi = gsi_after_labels (then2_bb);
1012 /* Generate __ubsan_handle_type_mismatch call. */
1013 if (flag_sanitize_undefined_trap_on_error)
1014 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1015 else
1017 tree data
1018 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
1019 ubsan_type_descriptor (TREE_TYPE (ptr),
1020 UBSAN_PRINT_POINTER),
1021 NULL_TREE,
1022 build_zero_cst (pointer_sized_int_node),
1023 ckind,
1024 NULL_TREE);
1025 data = build_fold_addr_expr_loc (loc, data);
1026 enum built_in_function bcode
1027 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1028 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1029 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
1030 tree p = make_ssa_name (pointer_sized_int_node);
1031 g = gimple_build_assign (p, NOP_EXPR, ptr);
1032 gimple_set_location (g, loc);
1033 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1034 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1036 gimple_set_location (g, loc);
1037 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1039 /* Point GSI to next logical statement. */
1040 *gsi = gsi_start_bb (fallthru_bb);
1042 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1043 unlink_stmt_vdef (stmt);
1044 gsi_remove (&gsi_orig, true);
1045 return true;
1048 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1049 unlink_stmt_vdef (stmt);
1050 gsi_remove (gsi, true);
1051 return true;
1054 /* Cached __ubsan_vptr_type_cache decl. */
1055 static GTY(()) tree ubsan_vptr_type_cache_decl;
1057 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1058 argument which is a constant, because the middle-end treats pointer
1059 conversions as useless and therefore the type of the first argument
1060 could be changed to any other pointer type. */
1062 bool
1063 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1065 gimple_stmt_iterator gsi = *gsip;
1066 gimple stmt = gsi_stmt (gsi);
1067 location_t loc = gimple_location (stmt);
1068 gcc_assert (gimple_call_num_args (stmt) == 5);
1069 tree op = gimple_call_arg (stmt, 0);
1070 tree vptr = gimple_call_arg (stmt, 1);
1071 tree str_hash = gimple_call_arg (stmt, 2);
1072 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1073 tree ckind_tree = gimple_call_arg (stmt, 4);
1074 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1075 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1076 gimple g;
1077 basic_block fallthru_bb = NULL;
1079 if (ckind == UBSAN_DOWNCAST_POINTER)
1081 /* Guard everything with if (op != NULL) { ... }. */
1082 basic_block then_bb;
1083 gimple_stmt_iterator cond_insert_point
1084 = create_cond_insert_point (gsip, false, false, true,
1085 &then_bb, &fallthru_bb);
1086 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1087 NULL_TREE, NULL_TREE);
1088 gimple_set_location (g, loc);
1089 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1090 *gsip = gsi_after_labels (then_bb);
1091 gsi_remove (&gsi, false);
1092 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1093 gsi = *gsip;
1096 tree htype = TREE_TYPE (str_hash);
1097 tree cst = wide_int_to_tree (htype,
1098 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1099 | 0xeb382d69, 64));
1100 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1101 vptr, str_hash);
1102 gimple_set_location (g, loc);
1103 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1104 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1105 gimple_assign_lhs (g), cst);
1106 gimple_set_location (g, loc);
1107 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1108 tree t1 = gimple_assign_lhs (g);
1109 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1110 t1, build_int_cst (integer_type_node, 47));
1111 gimple_set_location (g, loc);
1112 tree t2 = gimple_assign_lhs (g);
1113 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1114 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1115 vptr, t1);
1116 gimple_set_location (g, loc);
1117 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1118 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1119 t2, gimple_assign_lhs (g));
1120 gimple_set_location (g, loc);
1121 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1122 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1123 gimple_assign_lhs (g), cst);
1124 gimple_set_location (g, loc);
1125 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1126 tree t3 = gimple_assign_lhs (g);
1127 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1128 t3, build_int_cst (integer_type_node, 47));
1129 gimple_set_location (g, loc);
1130 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1131 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1132 t3, gimple_assign_lhs (g));
1133 gimple_set_location (g, loc);
1134 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1135 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1136 gimple_assign_lhs (g), cst);
1137 gimple_set_location (g, loc);
1138 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1139 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1141 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1142 NOP_EXPR, gimple_assign_lhs (g));
1143 gimple_set_location (g, loc);
1144 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1146 tree hash = gimple_assign_lhs (g);
1148 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1150 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1151 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1152 get_identifier ("__ubsan_vptr_type_cache"),
1153 atype);
1154 DECL_ARTIFICIAL (array) = 1;
1155 DECL_IGNORED_P (array) = 1;
1156 TREE_PUBLIC (array) = 1;
1157 TREE_STATIC (array) = 1;
1158 DECL_EXTERNAL (array) = 1;
1159 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1160 DECL_VISIBILITY_SPECIFIED (array) = 1;
1161 varpool_node::finalize_decl (array);
1162 ubsan_vptr_type_cache_decl = array;
1165 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1166 BIT_AND_EXPR, hash,
1167 build_int_cst (pointer_sized_int_node, 127));
1168 gimple_set_location (g, loc);
1169 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1171 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1172 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1173 NULL_TREE, NULL_TREE);
1174 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1175 ARRAY_REF, c);
1176 gimple_set_location (g, loc);
1177 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1179 basic_block then_bb, fallthru2_bb;
1180 gimple_stmt_iterator cond_insert_point
1181 = create_cond_insert_point (gsip, false, false, true,
1182 &then_bb, &fallthru2_bb);
1183 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1184 NULL_TREE, NULL_TREE);
1185 gimple_set_location (g, loc);
1186 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1187 *gsip = gsi_after_labels (then_bb);
1188 if (fallthru_bb == NULL)
1189 fallthru_bb = fallthru2_bb;
1191 tree data
1192 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1193 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1194 build_int_cst (unsigned_char_type_node, ckind),
1195 NULL_TREE);
1196 data = build_fold_addr_expr_loc (loc, data);
1197 enum built_in_function bcode
1198 = (flag_sanitize_recover & SANITIZE_VPTR)
1199 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1200 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1202 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1203 gimple_set_location (g, loc);
1204 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1206 /* Point GSI to next logical statement. */
1207 *gsip = gsi_start_bb (fallthru_bb);
1209 /* Get rid of the UBSAN_VPTR call from the IR. */
1210 unlink_stmt_vdef (stmt);
1211 gsi_remove (&gsi, true);
1212 return true;
1215 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1216 whether the pointer is on the left hand side of the assignment. */
1218 static void
1219 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1220 bool is_lhs)
1222 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1223 unsigned int align = 0;
1224 if (flag_sanitize & SANITIZE_ALIGNMENT)
1226 align = min_align_of_type (TREE_TYPE (base));
1227 if (align <= 1)
1228 align = 0;
1230 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1231 return;
1232 tree t = TREE_OPERAND (base, 0);
1233 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1234 return;
1235 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1236 ikind = UBSAN_MEMBER_ACCESS;
1237 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1238 tree alignt = build_int_cst (pointer_sized_int_node, align);
1239 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1240 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1241 gsi_insert_before (iter, g, GSI_SAME_STMT);
1244 /* Perform the pointer instrumentation. */
1246 static void
1247 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1249 gimple stmt = gsi_stmt (gsi);
1250 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1251 tree base = get_base_address (t);
1252 const enum tree_code code = TREE_CODE (base);
1253 if (code == MEM_REF
1254 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1255 instrument_mem_ref (t, base, &gsi, is_lhs);
1258 /* Build an ubsan builtin call for the signed-integer-overflow
1259 sanitization. CODE says what kind of builtin are we building,
1260 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1261 are operands of the binary operation. */
1263 tree
1264 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1265 tree op0, tree op1)
1267 if (flag_sanitize_undefined_trap_on_error)
1268 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1270 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1271 ubsan_type_descriptor (lhstype), NULL_TREE,
1272 NULL_TREE);
1273 enum built_in_function fn_code;
1275 switch (code)
1277 case PLUS_EXPR:
1278 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1279 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1280 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1281 break;
1282 case MINUS_EXPR:
1283 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1284 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1285 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1286 break;
1287 case MULT_EXPR:
1288 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1289 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1290 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1291 break;
1292 case NEGATE_EXPR:
1293 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1294 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1295 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1296 break;
1297 default:
1298 gcc_unreachable ();
1300 tree fn = builtin_decl_explicit (fn_code);
1301 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1302 build_fold_addr_expr_loc (loc, data),
1303 ubsan_encode_value (op0, true),
1304 op1 ? ubsan_encode_value (op1, true)
1305 : NULL_TREE);
1308 /* Perform the signed integer instrumentation. GSI is the iterator
1309 pointing at statement we are trying to instrument. */
1311 static void
1312 instrument_si_overflow (gimple_stmt_iterator gsi)
1314 gimple stmt = gsi_stmt (gsi);
1315 tree_code code = gimple_assign_rhs_code (stmt);
1316 tree lhs = gimple_assign_lhs (stmt);
1317 tree lhstype = TREE_TYPE (lhs);
1318 tree a, b;
1319 gimple g;
1321 /* If this is not a signed operation, don't instrument anything here.
1322 Also punt on bit-fields. */
1323 if (!INTEGRAL_TYPE_P (lhstype)
1324 || TYPE_OVERFLOW_WRAPS (lhstype)
1325 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1326 return;
1328 switch (code)
1330 case MINUS_EXPR:
1331 case PLUS_EXPR:
1332 case MULT_EXPR:
1333 /* Transform
1334 i = u {+,-,*} 5;
1335 into
1336 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1337 a = gimple_assign_rhs1 (stmt);
1338 b = gimple_assign_rhs2 (stmt);
1339 g = gimple_build_call_internal (code == PLUS_EXPR
1340 ? IFN_UBSAN_CHECK_ADD
1341 : code == MINUS_EXPR
1342 ? IFN_UBSAN_CHECK_SUB
1343 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1344 gimple_call_set_lhs (g, lhs);
1345 gsi_replace (&gsi, g, false);
1346 break;
1347 case NEGATE_EXPR:
1348 /* Represent i = -u;
1350 i = UBSAN_CHECK_SUB (0, u); */
1351 a = build_int_cst (lhstype, 0);
1352 b = gimple_assign_rhs1 (stmt);
1353 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1354 gimple_call_set_lhs (g, lhs);
1355 gsi_replace (&gsi, g, false);
1356 break;
1357 case ABS_EXPR:
1358 /* Transform i = ABS_EXPR<u>;
1359 into
1360 _N = UBSAN_CHECK_SUB (0, u);
1361 i = ABS_EXPR<_N>; */
1362 a = build_int_cst (lhstype, 0);
1363 b = gimple_assign_rhs1 (stmt);
1364 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1365 a = make_ssa_name (lhstype);
1366 gimple_call_set_lhs (g, a);
1367 gimple_set_location (g, gimple_location (stmt));
1368 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1369 gimple_assign_set_rhs1 (stmt, a);
1370 update_stmt (stmt);
1371 break;
1372 default:
1373 break;
1377 /* Instrument loads from (non-bitfield) bool and C++ enum values
1378 to check if the memory value is outside of the range of the valid
1379 type values. */
1381 static void
1382 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1384 gimple stmt = gsi_stmt (*gsi);
1385 tree rhs = gimple_assign_rhs1 (stmt);
1386 tree type = TREE_TYPE (rhs);
1387 tree minv = NULL_TREE, maxv = NULL_TREE;
1389 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1391 minv = boolean_false_node;
1392 maxv = boolean_true_node;
1394 else if (TREE_CODE (type) == ENUMERAL_TYPE
1395 && (flag_sanitize & SANITIZE_ENUM)
1396 && TREE_TYPE (type) != NULL_TREE
1397 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1398 && (TYPE_PRECISION (TREE_TYPE (type))
1399 < GET_MODE_PRECISION (TYPE_MODE (type))))
1401 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1402 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1404 else
1405 return;
1407 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1408 HOST_WIDE_INT bitsize, bitpos;
1409 tree offset;
1410 machine_mode mode;
1411 int volatilep = 0, unsignedp = 0;
1412 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1413 &unsignedp, &volatilep, false);
1414 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1416 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1417 || (bitpos % modebitsize) != 0
1418 || bitsize != modebitsize
1419 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1420 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1421 return;
1423 bool can_throw = stmt_could_throw_p (stmt);
1424 location_t loc = gimple_location (stmt);
1425 tree lhs = gimple_assign_lhs (stmt);
1426 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1427 tree atype = reference_alias_ptr_type (rhs);
1428 gimple g = gimple_build_assign (make_ssa_name (ptype),
1429 build_fold_addr_expr (rhs));
1430 gimple_set_location (g, loc);
1431 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1432 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1433 build_int_cst (atype, 0));
1434 tree urhs = make_ssa_name (utype);
1435 if (can_throw)
1437 gimple_assign_set_lhs (stmt, urhs);
1438 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1439 gimple_set_location (g, loc);
1440 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1441 gsi_insert_on_edge_immediate (e, g);
1442 gimple_assign_set_rhs_from_tree (gsi, mem);
1443 update_stmt (stmt);
1444 *gsi = gsi_for_stmt (g);
1445 g = stmt;
1447 else
1449 g = gimple_build_assign (urhs, mem);
1450 gimple_set_location (g, loc);
1451 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1453 minv = fold_convert (utype, minv);
1454 maxv = fold_convert (utype, maxv);
1455 if (!integer_zerop (minv))
1457 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1458 gimple_set_location (g, loc);
1459 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1462 gimple_stmt_iterator gsi2 = *gsi;
1463 basic_block then_bb, fallthru_bb;
1464 *gsi = create_cond_insert_point (gsi, true, false, true,
1465 &then_bb, &fallthru_bb);
1466 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1467 int_const_binop (MINUS_EXPR, maxv, minv),
1468 NULL_TREE, NULL_TREE);
1469 gimple_set_location (g, loc);
1470 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1472 if (!can_throw)
1474 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1475 update_stmt (stmt);
1478 gsi2 = gsi_after_labels (then_bb);
1479 if (flag_sanitize_undefined_trap_on_error)
1480 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1481 else
1483 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1484 ubsan_type_descriptor (type), NULL_TREE,
1485 NULL_TREE);
1486 data = build_fold_addr_expr_loc (loc, data);
1487 enum built_in_function bcode
1488 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1489 ? SANITIZE_BOOL : SANITIZE_ENUM))
1490 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1491 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1492 tree fn = builtin_decl_explicit (bcode);
1494 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1495 true, NULL_TREE, true,
1496 GSI_SAME_STMT);
1497 g = gimple_build_call (fn, 2, data, val);
1499 gimple_set_location (g, loc);
1500 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1501 ubsan_create_edge (g);
1502 *gsi = gsi_for_stmt (stmt);
1505 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1506 destination, EXPR is floating-point expression. ARG is what to pass
1507 the libubsan call as value, often EXPR itself. */
1509 tree
1510 ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
1512 tree expr_type = TREE_TYPE (expr);
1513 tree t, tt, fn, min, max;
1514 machine_mode mode = TYPE_MODE (expr_type);
1515 int prec = TYPE_PRECISION (type);
1516 bool uns_p = TYPE_UNSIGNED (type);
1518 /* Float to integer conversion first truncates toward zero, so
1519 even signed char c = 127.875f; is not problematic.
1520 Therefore, we should complain only if EXPR is unordered or smaller
1521 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1522 TYPE_MAX_VALUE + 1.0. */
1523 if (REAL_MODE_FORMAT (mode)->b == 2)
1525 /* For maximum, TYPE_MAX_VALUE might not be representable
1526 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1527 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1528 either representable or infinity. */
1529 REAL_VALUE_TYPE maxval = dconst1;
1530 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1531 real_convert (&maxval, mode, &maxval);
1532 max = build_real (expr_type, maxval);
1534 /* For unsigned, assume -1.0 is always representable. */
1535 if (uns_p)
1536 min = build_minus_one_cst (expr_type);
1537 else
1539 /* TYPE_MIN_VALUE is generally representable (or -inf),
1540 but TYPE_MIN_VALUE - 1.0 might not be. */
1541 REAL_VALUE_TYPE minval = dconstm1, minval2;
1542 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1543 real_convert (&minval, mode, &minval);
1544 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1545 real_convert (&minval2, mode, &minval2);
1546 if (real_compare (EQ_EXPR, &minval, &minval2)
1547 && !real_isinf (&minval))
1549 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1550 rounds to TYPE_MIN_VALUE, we need to subtract
1551 more. As REAL_MODE_FORMAT (mode)->p is the number
1552 of base digits, we want to subtract a number that
1553 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1554 times smaller than minval. */
1555 minval2 = dconst1;
1556 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1557 SET_REAL_EXP (&minval2,
1558 REAL_EXP (&minval2) + prec - 1
1559 - REAL_MODE_FORMAT (mode)->p + 1);
1560 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1561 real_convert (&minval2, mode, &minval2);
1563 min = build_real (expr_type, minval2);
1566 else if (REAL_MODE_FORMAT (mode)->b == 10)
1568 /* For _Decimal128 up to 34 decimal digits, - sign,
1569 dot, e, exponent. */
1570 char buf[64];
1571 mpfr_t m;
1572 int p = REAL_MODE_FORMAT (mode)->p;
1573 REAL_VALUE_TYPE maxval, minval;
1575 /* Use mpfr_snprintf rounding to compute the smallest
1576 representable decimal number greater or equal than
1577 1 << (prec - !uns_p). */
1578 mpfr_init2 (m, prec + 2);
1579 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1580 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1581 decimal_real_from_string (&maxval, buf);
1582 max = build_real (expr_type, maxval);
1584 /* For unsigned, assume -1.0 is always representable. */
1585 if (uns_p)
1586 min = build_minus_one_cst (expr_type);
1587 else
1589 /* Use mpfr_snprintf rounding to compute the largest
1590 representable decimal number less or equal than
1591 (-1 << (prec - 1)) - 1. */
1592 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1593 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1594 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1595 decimal_real_from_string (&minval, buf);
1596 min = build_real (expr_type, minval);
1598 mpfr_clear (m);
1600 else
1601 return NULL_TREE;
1603 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1604 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1605 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1606 if (integer_zerop (t))
1607 return NULL_TREE;
1609 if (flag_sanitize_undefined_trap_on_error)
1610 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1611 else
1613 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1614 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1615 NULL, ubsan_type_descriptor (expr_type),
1616 ubsan_type_descriptor (type), NULL_TREE,
1617 NULL_TREE);
1618 enum built_in_function bcode
1619 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1620 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1621 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1622 fn = builtin_decl_explicit (bcode);
1623 fn = build_call_expr_loc (loc, fn, 2,
1624 build_fold_addr_expr_loc (loc, data),
1625 ubsan_encode_value (arg, false));
1628 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1631 /* Instrument values passed to function arguments with nonnull attribute. */
1633 static void
1634 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1636 gimple stmt = gsi_stmt (*gsi);
1637 location_t loc[2];
1638 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1639 while for nonnull sanitization it is clear. */
1640 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1641 flag_delete_null_pointer_checks = 1;
1642 loc[0] = gimple_location (stmt);
1643 loc[1] = UNKNOWN_LOCATION;
1644 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1646 tree arg = gimple_call_arg (stmt, i);
1647 if (POINTER_TYPE_P (TREE_TYPE (arg))
1648 && infer_nonnull_range (stmt, arg, false, true))
1650 gimple g;
1651 if (!is_gimple_val (arg))
1653 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1654 gimple_set_location (g, loc[0]);
1655 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1656 arg = gimple_assign_lhs (g);
1659 basic_block then_bb, fallthru_bb;
1660 *gsi = create_cond_insert_point (gsi, true, false, true,
1661 &then_bb, &fallthru_bb);
1662 g = gimple_build_cond (EQ_EXPR, arg,
1663 build_zero_cst (TREE_TYPE (arg)),
1664 NULL_TREE, NULL_TREE);
1665 gimple_set_location (g, loc[0]);
1666 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1668 *gsi = gsi_after_labels (then_bb);
1669 if (flag_sanitize_undefined_trap_on_error)
1670 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1671 else
1673 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1674 2, loc, NULL_TREE,
1675 build_int_cst (integer_type_node,
1676 i + 1),
1677 NULL_TREE);
1678 data = build_fold_addr_expr_loc (loc[0], data);
1679 enum built_in_function bcode
1680 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1681 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1682 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1683 tree fn = builtin_decl_explicit (bcode);
1685 g = gimple_build_call (fn, 1, data);
1687 gimple_set_location (g, loc[0]);
1688 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1689 ubsan_create_edge (g);
1691 *gsi = gsi_for_stmt (stmt);
1693 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1696 /* Instrument returns in functions with returns_nonnull attribute. */
1698 static void
1699 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1701 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1702 location_t loc[2];
1703 tree arg = gimple_return_retval (stmt);
1704 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1705 while for nonnull return sanitization it is clear. */
1706 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1707 flag_delete_null_pointer_checks = 1;
1708 loc[0] = gimple_location (stmt);
1709 loc[1] = UNKNOWN_LOCATION;
1710 if (arg
1711 && POINTER_TYPE_P (TREE_TYPE (arg))
1712 && is_gimple_val (arg)
1713 && infer_nonnull_range (stmt, arg, false, true))
1715 basic_block then_bb, fallthru_bb;
1716 *gsi = create_cond_insert_point (gsi, true, false, true,
1717 &then_bb, &fallthru_bb);
1718 gimple g = gimple_build_cond (EQ_EXPR, arg,
1719 build_zero_cst (TREE_TYPE (arg)),
1720 NULL_TREE, NULL_TREE);
1721 gimple_set_location (g, loc[0]);
1722 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1724 *gsi = gsi_after_labels (then_bb);
1725 if (flag_sanitize_undefined_trap_on_error)
1726 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1727 else
1729 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1730 2, loc, NULL_TREE, NULL_TREE);
1731 data = build_fold_addr_expr_loc (loc[0], data);
1732 enum built_in_function bcode
1733 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1734 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1735 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1736 tree fn = builtin_decl_explicit (bcode);
1738 g = gimple_build_call (fn, 1, data);
1740 gimple_set_location (g, loc[0]);
1741 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1742 ubsan_create_edge (g);
1743 *gsi = gsi_for_stmt (stmt);
1745 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1748 /* Instrument memory references. Here we check whether the pointer
1749 points to an out-of-bounds location. */
1751 static void
1752 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1754 gimple stmt = gsi_stmt (*gsi);
1755 location_t loc = gimple_location (stmt);
1756 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1757 tree type;
1758 tree index = NULL_TREE;
1759 HOST_WIDE_INT size_in_bytes;
1761 type = TREE_TYPE (t);
1762 if (VOID_TYPE_P (type))
1763 return;
1765 switch (TREE_CODE (t))
1767 case COMPONENT_REF:
1768 if (TREE_CODE (t) == COMPONENT_REF
1769 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1771 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1772 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1773 repr, NULL_TREE);
1775 break;
1776 case ARRAY_REF:
1777 index = TREE_OPERAND (t, 1);
1778 break;
1779 case INDIRECT_REF:
1780 case MEM_REF:
1781 case VAR_DECL:
1782 case PARM_DECL:
1783 case RESULT_DECL:
1784 break;
1785 default:
1786 return;
1789 size_in_bytes = int_size_in_bytes (type);
1790 if (size_in_bytes <= 0)
1791 return;
1793 HOST_WIDE_INT bitsize, bitpos;
1794 tree offset;
1795 machine_mode mode;
1796 int volatilep = 0, unsignedp = 0;
1797 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1798 &unsignedp, &volatilep, false);
1800 if (bitpos % BITS_PER_UNIT != 0
1801 || bitsize != size_in_bytes * BITS_PER_UNIT)
1802 return;
1804 bool decl_p = DECL_P (inner);
1805 tree base;
1806 if (decl_p)
1807 base = inner;
1808 else if (TREE_CODE (inner) == MEM_REF)
1809 base = TREE_OPERAND (inner, 0);
1810 else
1811 return;
1812 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1814 while (TREE_CODE (base) == SSA_NAME)
1816 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1817 if (gimple_assign_ssa_name_copy_p (def_stmt)
1818 || (gimple_assign_cast_p (def_stmt)
1819 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1820 || (is_gimple_assign (def_stmt)
1821 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1823 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1824 if (TREE_CODE (rhs1) == SSA_NAME
1825 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1826 break;
1827 else
1828 base = rhs1;
1830 else
1831 break;
1834 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1835 return;
1837 tree sizet;
1838 tree base_addr = base;
1839 gimple bos_stmt = NULL;
1840 if (decl_p)
1841 base_addr = build1 (ADDR_EXPR,
1842 build_pointer_type (TREE_TYPE (base)), base);
1843 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1844 if (size != (unsigned HOST_WIDE_INT) -1)
1845 sizet = build_int_cst (sizetype, size);
1846 else if (optimize)
1848 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1849 loc = input_location;
1850 /* Generate __builtin_object_size call. */
1851 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1852 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1853 integer_zero_node);
1854 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1855 GSI_SAME_STMT);
1856 /* If the call above didn't end up being an integer constant, go one
1857 statement back and get the __builtin_object_size stmt. Save it,
1858 we might need it later. */
1859 if (SSA_VAR_P (sizet))
1861 gsi_prev (gsi);
1862 bos_stmt = gsi_stmt (*gsi);
1864 /* Move on to where we were. */
1865 gsi_next (gsi);
1868 else
1869 return;
1871 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1872 call. */
1873 /* ptr + sizeof (*ptr) - base */
1874 t = fold_build2 (MINUS_EXPR, sizetype,
1875 fold_convert (pointer_sized_int_node, ptr),
1876 fold_convert (pointer_sized_int_node, base_addr));
1877 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1879 /* Perhaps we can omit the check. */
1880 if (TREE_CODE (t) == INTEGER_CST
1881 && TREE_CODE (sizet) == INTEGER_CST
1882 && tree_int_cst_le (t, sizet))
1883 return;
1885 if (index != NULL_TREE
1886 && TREE_CODE (index) == SSA_NAME
1887 && TREE_CODE (sizet) == INTEGER_CST)
1889 gimple def = SSA_NAME_DEF_STMT (index);
1890 if (is_gimple_assign (def)
1891 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1892 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1894 tree cst = gimple_assign_rhs2 (def);
1895 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1896 TYPE_SIZE_UNIT (type));
1897 if (tree_int_cst_sgn (cst) >= 0
1898 && tree_int_cst_lt (cst, sz))
1899 return;
1903 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1904 ubsan_create_edge (bos_stmt);
1906 /* We have to emit the check. */
1907 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1908 GSI_SAME_STMT);
1909 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1910 GSI_SAME_STMT);
1911 tree ckind = build_int_cst (unsigned_char_type_node,
1912 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1913 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1914 ptr, t, sizet, ckind);
1915 gimple_set_location (g, loc);
1916 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1919 /* True if we want to play UBSan games in the current function. */
1921 bool
1922 do_ubsan_in_current_function ()
1924 return (current_function_decl != NULL_TREE
1925 && !lookup_attribute ("no_sanitize_undefined",
1926 DECL_ATTRIBUTES (current_function_decl)));
1929 namespace {
1931 const pass_data pass_data_ubsan =
1933 GIMPLE_PASS, /* type */
1934 "ubsan", /* name */
1935 OPTGROUP_NONE, /* optinfo_flags */
1936 TV_TREE_UBSAN, /* tv_id */
1937 ( PROP_cfg | PROP_ssa ), /* properties_required */
1938 0, /* properties_provided */
1939 0, /* properties_destroyed */
1940 0, /* todo_flags_start */
1941 TODO_update_ssa, /* todo_flags_finish */
1944 class pass_ubsan : public gimple_opt_pass
1946 public:
1947 pass_ubsan (gcc::context *ctxt)
1948 : gimple_opt_pass (pass_data_ubsan, ctxt)
1951 /* opt_pass methods: */
1952 virtual bool gate (function *)
1954 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1955 | SANITIZE_BOOL | SANITIZE_ENUM
1956 | SANITIZE_ALIGNMENT
1957 | SANITIZE_NONNULL_ATTRIBUTE
1958 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1959 | SANITIZE_OBJECT_SIZE)
1960 && do_ubsan_in_current_function ();
1963 virtual unsigned int execute (function *);
1965 }; // class pass_ubsan
1967 unsigned int
1968 pass_ubsan::execute (function *fun)
1970 basic_block bb;
1971 gimple_stmt_iterator gsi;
1973 initialize_sanitizer_builtins ();
1975 FOR_EACH_BB_FN (bb, fun)
1977 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1979 gimple stmt = gsi_stmt (gsi);
1980 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1982 gsi_next (&gsi);
1983 continue;
1986 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1987 && is_gimple_assign (stmt))
1988 instrument_si_overflow (gsi);
1990 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1992 if (gimple_store_p (stmt))
1993 instrument_null (gsi, true);
1994 if (gimple_assign_load_p (stmt))
1995 instrument_null (gsi, false);
1998 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1999 && gimple_assign_load_p (stmt))
2001 instrument_bool_enum_load (&gsi);
2002 bb = gimple_bb (stmt);
2005 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
2006 && is_gimple_call (stmt)
2007 && !gimple_call_internal_p (stmt))
2009 instrument_nonnull_arg (&gsi);
2010 bb = gimple_bb (stmt);
2013 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2014 && gimple_code (stmt) == GIMPLE_RETURN)
2016 instrument_nonnull_return (&gsi);
2017 bb = gimple_bb (stmt);
2020 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2022 if (gimple_store_p (stmt))
2023 instrument_object_size (&gsi, true);
2024 if (gimple_assign_load_p (stmt))
2025 instrument_object_size (&gsi, false);
2028 gsi_next (&gsi);
2031 return 0;
2034 } // anon namespace
2036 gimple_opt_pass *
2037 make_pass_ubsan (gcc::context *ctxt)
2039 return new pass_ubsan (ctxt);
2042 #include "gt-ubsan.h"