PR libgomp/64635
[official-gcc.git] / gcc / ubsan.c
blob036e67e787971cedfe9527cc03a7e357d0c5e632
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 /* Expand the UBSAN_BOUNDS special builtin function. */
691 bool
692 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
694 gimple stmt = gsi_stmt (*gsi);
695 location_t loc = gimple_location (stmt);
696 gcc_assert (gimple_call_num_args (stmt) == 3);
698 /* Pick up the arguments of the UBSAN_BOUNDS call. */
699 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
700 tree index = gimple_call_arg (stmt, 1);
701 tree orig_index_type = TREE_TYPE (index);
702 tree bound = gimple_call_arg (stmt, 2);
704 gimple_stmt_iterator gsi_orig = *gsi;
706 /* Create condition "if (index > bound)". */
707 basic_block then_bb, fallthru_bb;
708 gimple_stmt_iterator cond_insert_point
709 = create_cond_insert_point (gsi, false, false, true,
710 &then_bb, &fallthru_bb);
711 index = fold_convert (TREE_TYPE (bound), index);
712 index = force_gimple_operand_gsi (&cond_insert_point, index,
713 true, NULL_TREE,
714 false, GSI_NEW_STMT);
715 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
716 gimple_set_location (g, loc);
717 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
719 /* Generate __ubsan_handle_out_of_bounds call. */
720 *gsi = gsi_after_labels (then_bb);
721 if (flag_sanitize_undefined_trap_on_error)
722 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
723 else
725 tree data
726 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
727 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
728 ubsan_type_descriptor (orig_index_type),
729 NULL_TREE, NULL_TREE);
730 data = build_fold_addr_expr_loc (loc, data);
731 enum built_in_function bcode
732 = (flag_sanitize_recover & SANITIZE_BOUNDS)
733 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
734 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
735 tree fn = builtin_decl_explicit (bcode);
736 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
737 true, NULL_TREE, true,
738 GSI_SAME_STMT);
739 g = gimple_build_call (fn, 2, data, val);
741 gimple_set_location (g, loc);
742 gsi_insert_before (gsi, g, GSI_SAME_STMT);
744 /* Get rid of the UBSAN_BOUNDS call from the IR. */
745 unlink_stmt_vdef (stmt);
746 gsi_remove (&gsi_orig, true);
748 /* Point GSI to next logical statement. */
749 *gsi = gsi_start_bb (fallthru_bb);
750 return true;
753 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
754 argument which is a constant, because the middle-end treats pointer
755 conversions as useless and therefore the type of the first argument
756 could be changed to any other pointer type. */
758 bool
759 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
761 gimple_stmt_iterator gsi = *gsip;
762 gimple stmt = gsi_stmt (gsi);
763 location_t loc = gimple_location (stmt);
764 gcc_assert (gimple_call_num_args (stmt) == 3);
765 tree ptr = gimple_call_arg (stmt, 0);
766 tree ckind = gimple_call_arg (stmt, 1);
767 tree align = gimple_call_arg (stmt, 2);
768 tree check_align = NULL_TREE;
769 bool check_null;
771 basic_block cur_bb = gsi_bb (gsi);
773 gimple g;
774 if (!integer_zerop (align))
776 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
777 if (compare_tree_int (align, ptralign) == 1)
779 check_align = make_ssa_name (pointer_sized_int_node);
780 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
781 gimple_set_location (g, loc);
782 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
785 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
787 if (check_align == NULL_TREE && !check_null)
789 gsi_remove (gsip, true);
790 /* Unlink the UBSAN_NULLs vops before replacing it. */
791 unlink_stmt_vdef (stmt);
792 return true;
795 /* Split the original block holding the pointer dereference. */
796 edge e = split_block (cur_bb, stmt);
798 /* Get a hold on the 'condition block', the 'then block' and the
799 'else block'. */
800 basic_block cond_bb = e->src;
801 basic_block fallthru_bb = e->dest;
802 basic_block then_bb = create_empty_bb (cond_bb);
803 add_bb_to_loop (then_bb, cond_bb->loop_father);
804 loops_state_set (LOOPS_NEED_FIXUP);
806 /* Make an edge coming from the 'cond block' into the 'then block';
807 this edge is unlikely taken, so set up the probability accordingly. */
808 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
809 e->probability = PROB_VERY_UNLIKELY;
811 /* Connect 'then block' with the 'else block'. This is needed
812 as the ubsan routines we call in the 'then block' are not noreturn.
813 The 'then block' only has one outcoming edge. */
814 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
816 /* Set up the fallthrough basic block. */
817 e = find_edge (cond_bb, fallthru_bb);
818 e->flags = EDGE_FALSE_VALUE;
819 e->count = cond_bb->count;
820 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
822 /* Update dominance info for the newly created then_bb; note that
823 fallthru_bb's dominance info has already been updated by
824 split_block. */
825 if (dom_info_available_p (CDI_DOMINATORS))
826 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
828 /* Put the ubsan builtin call into the newly created BB. */
829 if (flag_sanitize_undefined_trap_on_error)
830 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
831 else
833 enum built_in_function bcode
834 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
835 | (check_null ? SANITIZE_NULL : 0)))
836 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
837 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
838 tree fn = builtin_decl_implicit (bcode);
839 tree data
840 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
841 ubsan_type_descriptor (TREE_TYPE (ckind),
842 UBSAN_PRINT_POINTER),
843 NULL_TREE,
844 align,
845 fold_convert (unsigned_char_type_node, ckind),
846 NULL_TREE);
847 data = build_fold_addr_expr_loc (loc, data);
848 g = gimple_build_call (fn, 2, data,
849 check_align ? check_align
850 : build_zero_cst (pointer_sized_int_node));
852 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
853 gimple_set_location (g, loc);
854 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
856 /* Unlink the UBSAN_NULLs vops before replacing it. */
857 unlink_stmt_vdef (stmt);
859 if (check_null)
861 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
862 NULL_TREE, NULL_TREE);
863 gimple_set_location (g, loc);
865 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
866 gsi_replace (&gsi, g, false);
869 if (check_align)
871 if (check_null)
873 /* Split the block with the condition again. */
874 e = split_block (cond_bb, stmt);
875 basic_block cond1_bb = e->src;
876 basic_block cond2_bb = e->dest;
878 /* Make an edge coming from the 'cond1 block' into the 'then block';
879 this edge is unlikely taken, so set up the probability
880 accordingly. */
881 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
882 e->probability = PROB_VERY_UNLIKELY;
884 /* Set up the fallthrough basic block. */
885 e = find_edge (cond1_bb, cond2_bb);
886 e->flags = EDGE_FALSE_VALUE;
887 e->count = cond1_bb->count;
888 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
890 /* Update dominance info. */
891 if (dom_info_available_p (CDI_DOMINATORS))
893 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
894 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
897 gsi2 = gsi_start_bb (cond2_bb);
900 tree mask = build_int_cst (pointer_sized_int_node,
901 tree_to_uhwi (align) - 1);
902 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
903 BIT_AND_EXPR, check_align, mask);
904 gimple_set_location (g, loc);
905 if (check_null)
906 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
907 else
908 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
910 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
911 build_int_cst (pointer_sized_int_node, 0),
912 NULL_TREE, NULL_TREE);
913 gimple_set_location (g, loc);
914 if (check_null)
915 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
916 else
917 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
918 gsi_replace (&gsi, g, false);
920 return false;
923 /* Expand UBSAN_OBJECT_SIZE internal call. */
925 bool
926 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
928 gimple stmt = gsi_stmt (*gsi);
929 location_t loc = gimple_location (stmt);
930 gcc_assert (gimple_call_num_args (stmt) == 4);
932 tree ptr = gimple_call_arg (stmt, 0);
933 tree offset = gimple_call_arg (stmt, 1);
934 tree size = gimple_call_arg (stmt, 2);
935 tree ckind = gimple_call_arg (stmt, 3);
936 gimple_stmt_iterator gsi_orig = *gsi;
937 gimple g;
939 /* See if we can discard the check. */
940 if (TREE_CODE (size) != INTEGER_CST
941 || integer_all_onesp (size))
942 /* Yes, __builtin_object_size couldn't determine the
943 object size. */;
944 else
946 /* if (offset > objsize) */
947 basic_block then_bb, fallthru_bb;
948 gimple_stmt_iterator cond_insert_point
949 = create_cond_insert_point (gsi, false, false, true,
950 &then_bb, &fallthru_bb);
951 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
952 gimple_set_location (g, loc);
953 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
955 /* Generate __ubsan_handle_type_mismatch call. */
956 *gsi = gsi_after_labels (then_bb);
957 if (flag_sanitize_undefined_trap_on_error)
958 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
959 else
961 tree data
962 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
963 ubsan_type_descriptor (TREE_TYPE (ptr),
964 UBSAN_PRINT_POINTER),
965 NULL_TREE,
966 build_zero_cst (pointer_sized_int_node),
967 ckind,
968 NULL_TREE);
969 data = build_fold_addr_expr_loc (loc, data);
970 enum built_in_function bcode
971 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
972 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
973 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
974 tree p = make_ssa_name (pointer_sized_int_node);
975 g = gimple_build_assign (p, NOP_EXPR, ptr);
976 gimple_set_location (g, loc);
977 gsi_insert_before (gsi, g, GSI_SAME_STMT);
978 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
980 gimple_set_location (g, loc);
981 gsi_insert_before (gsi, g, GSI_SAME_STMT);
983 /* Point GSI to next logical statement. */
984 *gsi = gsi_start_bb (fallthru_bb);
987 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
988 unlink_stmt_vdef (stmt);
989 gsi_remove (&gsi_orig, true);
990 return gsi_end_p (*gsi);
993 /* Cached __ubsan_vptr_type_cache decl. */
994 static GTY(()) tree ubsan_vptr_type_cache_decl;
996 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
997 argument which is a constant, because the middle-end treats pointer
998 conversions as useless and therefore the type of the first argument
999 could be changed to any other pointer type. */
1001 bool
1002 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1004 gimple_stmt_iterator gsi = *gsip;
1005 gimple stmt = gsi_stmt (gsi);
1006 location_t loc = gimple_location (stmt);
1007 gcc_assert (gimple_call_num_args (stmt) == 5);
1008 tree op = gimple_call_arg (stmt, 0);
1009 tree vptr = gimple_call_arg (stmt, 1);
1010 tree str_hash = gimple_call_arg (stmt, 2);
1011 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1012 tree ckind_tree = gimple_call_arg (stmt, 4);
1013 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1014 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1015 gimple g;
1016 basic_block fallthru_bb = NULL;
1018 if (ckind == UBSAN_DOWNCAST_POINTER)
1020 /* Guard everything with if (op != NULL) { ... }. */
1021 basic_block then_bb;
1022 gimple_stmt_iterator cond_insert_point
1023 = create_cond_insert_point (gsip, false, false, true,
1024 &then_bb, &fallthru_bb);
1025 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1026 NULL_TREE, NULL_TREE);
1027 gimple_set_location (g, loc);
1028 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1029 *gsip = gsi_after_labels (then_bb);
1030 gsi_remove (&gsi, false);
1031 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1032 gsi = *gsip;
1035 tree htype = TREE_TYPE (str_hash);
1036 tree cst = wide_int_to_tree (htype,
1037 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1038 | 0xeb382d69, 64));
1039 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1040 vptr, str_hash);
1041 gimple_set_location (g, loc);
1042 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1043 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1044 gimple_assign_lhs (g), cst);
1045 gimple_set_location (g, loc);
1046 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1047 tree t1 = gimple_assign_lhs (g);
1048 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1049 t1, build_int_cst (integer_type_node, 47));
1050 gimple_set_location (g, loc);
1051 tree t2 = gimple_assign_lhs (g);
1052 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1053 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1054 vptr, t1);
1055 gimple_set_location (g, loc);
1056 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1057 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1058 t2, gimple_assign_lhs (g));
1059 gimple_set_location (g, loc);
1060 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1061 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1062 gimple_assign_lhs (g), cst);
1063 gimple_set_location (g, loc);
1064 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1065 tree t3 = gimple_assign_lhs (g);
1066 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1067 t3, build_int_cst (integer_type_node, 47));
1068 gimple_set_location (g, loc);
1069 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1070 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1071 t3, gimple_assign_lhs (g));
1072 gimple_set_location (g, loc);
1073 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1074 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1075 gimple_assign_lhs (g), cst);
1076 gimple_set_location (g, loc);
1077 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1078 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1080 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1081 NOP_EXPR, gimple_assign_lhs (g));
1082 gimple_set_location (g, loc);
1083 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1085 tree hash = gimple_assign_lhs (g);
1087 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1089 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1090 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1091 get_identifier ("__ubsan_vptr_type_cache"),
1092 atype);
1093 DECL_ARTIFICIAL (array) = 1;
1094 DECL_IGNORED_P (array) = 1;
1095 TREE_PUBLIC (array) = 1;
1096 TREE_STATIC (array) = 1;
1097 DECL_EXTERNAL (array) = 1;
1098 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1099 DECL_VISIBILITY_SPECIFIED (array) = 1;
1100 varpool_node::finalize_decl (array);
1101 ubsan_vptr_type_cache_decl = array;
1104 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1105 BIT_AND_EXPR, hash,
1106 build_int_cst (pointer_sized_int_node, 127));
1107 gimple_set_location (g, loc);
1108 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1110 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1111 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1112 NULL_TREE, NULL_TREE);
1113 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1114 ARRAY_REF, c);
1115 gimple_set_location (g, loc);
1116 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1118 basic_block then_bb, fallthru2_bb;
1119 gimple_stmt_iterator cond_insert_point
1120 = create_cond_insert_point (gsip, false, false, true,
1121 &then_bb, &fallthru2_bb);
1122 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1123 NULL_TREE, NULL_TREE);
1124 gimple_set_location (g, loc);
1125 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1126 *gsip = gsi_after_labels (then_bb);
1127 if (fallthru_bb == NULL)
1128 fallthru_bb = fallthru2_bb;
1130 tree data
1131 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1132 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1133 build_int_cst (unsigned_char_type_node, ckind),
1134 NULL_TREE);
1135 data = build_fold_addr_expr_loc (loc, data);
1136 enum built_in_function bcode
1137 = (flag_sanitize_recover & SANITIZE_VPTR)
1138 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1139 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1141 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1142 gimple_set_location (g, loc);
1143 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1145 /* Point GSI to next logical statement. */
1146 *gsip = gsi_start_bb (fallthru_bb);
1148 /* Get rid of the UBSAN_VPTR call from the IR. */
1149 unlink_stmt_vdef (stmt);
1150 gsi_remove (&gsi, true);
1151 return gsi_end_p (*gsip);
1154 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1155 whether the pointer is on the left hand side of the assignment. */
1157 static void
1158 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1159 bool is_lhs)
1161 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1162 unsigned int align = 0;
1163 if (flag_sanitize & SANITIZE_ALIGNMENT)
1165 align = min_align_of_type (TREE_TYPE (base));
1166 if (align <= 1)
1167 align = 0;
1169 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1170 return;
1171 tree t = TREE_OPERAND (base, 0);
1172 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1173 return;
1174 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && mem != base)
1175 ikind = UBSAN_MEMBER_ACCESS;
1176 tree kind = build_int_cst (TREE_TYPE (t), ikind);
1177 tree alignt = build_int_cst (pointer_sized_int_node, align);
1178 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1179 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1180 gsi_insert_before (iter, g, GSI_SAME_STMT);
1183 /* Perform the pointer instrumentation. */
1185 static void
1186 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1188 gimple stmt = gsi_stmt (gsi);
1189 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1190 tree base = get_base_address (t);
1191 const enum tree_code code = TREE_CODE (base);
1192 if (code == MEM_REF
1193 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1194 instrument_mem_ref (t, base, &gsi, is_lhs);
1197 /* Build an ubsan builtin call for the signed-integer-overflow
1198 sanitization. CODE says what kind of builtin are we building,
1199 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1200 are operands of the binary operation. */
1202 tree
1203 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1204 tree op0, tree op1)
1206 if (flag_sanitize_undefined_trap_on_error)
1207 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1209 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1210 ubsan_type_descriptor (lhstype), NULL_TREE,
1211 NULL_TREE);
1212 enum built_in_function fn_code;
1214 switch (code)
1216 case PLUS_EXPR:
1217 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1218 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1219 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1220 break;
1221 case MINUS_EXPR:
1222 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1223 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1224 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1225 break;
1226 case MULT_EXPR:
1227 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1228 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1229 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1230 break;
1231 case NEGATE_EXPR:
1232 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1233 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1234 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1235 break;
1236 default:
1237 gcc_unreachable ();
1239 tree fn = builtin_decl_explicit (fn_code);
1240 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1241 build_fold_addr_expr_loc (loc, data),
1242 ubsan_encode_value (op0, true),
1243 op1 ? ubsan_encode_value (op1, true)
1244 : NULL_TREE);
1247 /* Perform the signed integer instrumentation. GSI is the iterator
1248 pointing at statement we are trying to instrument. */
1250 static void
1251 instrument_si_overflow (gimple_stmt_iterator gsi)
1253 gimple stmt = gsi_stmt (gsi);
1254 tree_code code = gimple_assign_rhs_code (stmt);
1255 tree lhs = gimple_assign_lhs (stmt);
1256 tree lhstype = TREE_TYPE (lhs);
1257 tree a, b;
1258 gimple g;
1260 /* If this is not a signed operation, don't instrument anything here.
1261 Also punt on bit-fields. */
1262 if (!INTEGRAL_TYPE_P (lhstype)
1263 || TYPE_OVERFLOW_WRAPS (lhstype)
1264 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1265 return;
1267 switch (code)
1269 case MINUS_EXPR:
1270 case PLUS_EXPR:
1271 case MULT_EXPR:
1272 /* Transform
1273 i = u {+,-,*} 5;
1274 into
1275 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1276 a = gimple_assign_rhs1 (stmt);
1277 b = gimple_assign_rhs2 (stmt);
1278 g = gimple_build_call_internal (code == PLUS_EXPR
1279 ? IFN_UBSAN_CHECK_ADD
1280 : code == MINUS_EXPR
1281 ? IFN_UBSAN_CHECK_SUB
1282 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1283 gimple_call_set_lhs (g, lhs);
1284 gsi_replace (&gsi, g, false);
1285 break;
1286 case NEGATE_EXPR:
1287 /* Represent i = -u;
1289 i = UBSAN_CHECK_SUB (0, u); */
1290 a = build_int_cst (lhstype, 0);
1291 b = gimple_assign_rhs1 (stmt);
1292 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1293 gimple_call_set_lhs (g, lhs);
1294 gsi_replace (&gsi, g, false);
1295 break;
1296 case ABS_EXPR:
1297 /* Transform i = ABS_EXPR<u>;
1298 into
1299 _N = UBSAN_CHECK_SUB (0, u);
1300 i = ABS_EXPR<_N>; */
1301 a = build_int_cst (lhstype, 0);
1302 b = gimple_assign_rhs1 (stmt);
1303 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1304 a = make_ssa_name (lhstype);
1305 gimple_call_set_lhs (g, a);
1306 gimple_set_location (g, gimple_location (stmt));
1307 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1308 gimple_assign_set_rhs1 (stmt, a);
1309 update_stmt (stmt);
1310 break;
1311 default:
1312 break;
1316 /* Instrument loads from (non-bitfield) bool and C++ enum values
1317 to check if the memory value is outside of the range of the valid
1318 type values. */
1320 static void
1321 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1323 gimple stmt = gsi_stmt (*gsi);
1324 tree rhs = gimple_assign_rhs1 (stmt);
1325 tree type = TREE_TYPE (rhs);
1326 tree minv = NULL_TREE, maxv = NULL_TREE;
1328 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1330 minv = boolean_false_node;
1331 maxv = boolean_true_node;
1333 else if (TREE_CODE (type) == ENUMERAL_TYPE
1334 && (flag_sanitize & SANITIZE_ENUM)
1335 && TREE_TYPE (type) != NULL_TREE
1336 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1337 && (TYPE_PRECISION (TREE_TYPE (type))
1338 < GET_MODE_PRECISION (TYPE_MODE (type))))
1340 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1341 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1343 else
1344 return;
1346 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1347 HOST_WIDE_INT bitsize, bitpos;
1348 tree offset;
1349 machine_mode mode;
1350 int volatilep = 0, unsignedp = 0;
1351 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1352 &unsignedp, &volatilep, false);
1353 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1355 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1356 || (bitpos % modebitsize) != 0
1357 || bitsize != modebitsize
1358 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1359 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1360 return;
1362 bool can_throw = stmt_could_throw_p (stmt);
1363 location_t loc = gimple_location (stmt);
1364 tree lhs = gimple_assign_lhs (stmt);
1365 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1366 tree atype = reference_alias_ptr_type (rhs);
1367 gimple g = gimple_build_assign (make_ssa_name (ptype),
1368 build_fold_addr_expr (rhs));
1369 gimple_set_location (g, loc);
1370 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1371 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1372 build_int_cst (atype, 0));
1373 tree urhs = make_ssa_name (utype);
1374 if (can_throw)
1376 gimple_assign_set_lhs (stmt, urhs);
1377 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1378 gimple_set_location (g, loc);
1379 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1380 gsi_insert_on_edge_immediate (e, g);
1381 gimple_assign_set_rhs_from_tree (gsi, mem);
1382 update_stmt (stmt);
1383 *gsi = gsi_for_stmt (g);
1384 g = stmt;
1386 else
1388 g = gimple_build_assign (urhs, mem);
1389 gimple_set_location (g, loc);
1390 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1392 minv = fold_convert (utype, minv);
1393 maxv = fold_convert (utype, maxv);
1394 if (!integer_zerop (minv))
1396 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1397 gimple_set_location (g, loc);
1398 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1401 gimple_stmt_iterator gsi2 = *gsi;
1402 basic_block then_bb, fallthru_bb;
1403 *gsi = create_cond_insert_point (gsi, true, false, true,
1404 &then_bb, &fallthru_bb);
1405 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1406 int_const_binop (MINUS_EXPR, maxv, minv),
1407 NULL_TREE, NULL_TREE);
1408 gimple_set_location (g, loc);
1409 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1411 if (!can_throw)
1413 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1414 update_stmt (stmt);
1417 gsi2 = gsi_after_labels (then_bb);
1418 if (flag_sanitize_undefined_trap_on_error)
1419 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1420 else
1422 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1423 ubsan_type_descriptor (type), NULL_TREE,
1424 NULL_TREE);
1425 data = build_fold_addr_expr_loc (loc, data);
1426 enum built_in_function bcode
1427 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1428 ? SANITIZE_BOOL : SANITIZE_ENUM))
1429 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1430 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1431 tree fn = builtin_decl_explicit (bcode);
1433 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1434 true, NULL_TREE, true,
1435 GSI_SAME_STMT);
1436 g = gimple_build_call (fn, 2, data, val);
1438 gimple_set_location (g, loc);
1439 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1440 *gsi = gsi_for_stmt (stmt);
1443 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1444 destination, EXPR is floating-point expression. ARG is what to pass
1445 the libubsan call as value, often EXPR itself. */
1447 tree
1448 ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
1450 tree expr_type = TREE_TYPE (expr);
1451 tree t, tt, fn, min, max;
1452 machine_mode mode = TYPE_MODE (expr_type);
1453 int prec = TYPE_PRECISION (type);
1454 bool uns_p = TYPE_UNSIGNED (type);
1456 /* Float to integer conversion first truncates toward zero, so
1457 even signed char c = 127.875f; is not problematic.
1458 Therefore, we should complain only if EXPR is unordered or smaller
1459 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1460 TYPE_MAX_VALUE + 1.0. */
1461 if (REAL_MODE_FORMAT (mode)->b == 2)
1463 /* For maximum, TYPE_MAX_VALUE might not be representable
1464 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1465 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1466 either representable or infinity. */
1467 REAL_VALUE_TYPE maxval = dconst1;
1468 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1469 real_convert (&maxval, mode, &maxval);
1470 max = build_real (expr_type, maxval);
1472 /* For unsigned, assume -1.0 is always representable. */
1473 if (uns_p)
1474 min = build_minus_one_cst (expr_type);
1475 else
1477 /* TYPE_MIN_VALUE is generally representable (or -inf),
1478 but TYPE_MIN_VALUE - 1.0 might not be. */
1479 REAL_VALUE_TYPE minval = dconstm1, minval2;
1480 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1481 real_convert (&minval, mode, &minval);
1482 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1483 real_convert (&minval2, mode, &minval2);
1484 if (real_compare (EQ_EXPR, &minval, &minval2)
1485 && !real_isinf (&minval))
1487 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1488 rounds to TYPE_MIN_VALUE, we need to subtract
1489 more. As REAL_MODE_FORMAT (mode)->p is the number
1490 of base digits, we want to subtract a number that
1491 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1492 times smaller than minval. */
1493 minval2 = dconst1;
1494 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1495 SET_REAL_EXP (&minval2,
1496 REAL_EXP (&minval2) + prec - 1
1497 - REAL_MODE_FORMAT (mode)->p + 1);
1498 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1499 real_convert (&minval2, mode, &minval2);
1501 min = build_real (expr_type, minval2);
1504 else if (REAL_MODE_FORMAT (mode)->b == 10)
1506 /* For _Decimal128 up to 34 decimal digits, - sign,
1507 dot, e, exponent. */
1508 char buf[64];
1509 mpfr_t m;
1510 int p = REAL_MODE_FORMAT (mode)->p;
1511 REAL_VALUE_TYPE maxval, minval;
1513 /* Use mpfr_snprintf rounding to compute the smallest
1514 representable decimal number greater or equal than
1515 1 << (prec - !uns_p). */
1516 mpfr_init2 (m, prec + 2);
1517 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1518 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1519 decimal_real_from_string (&maxval, buf);
1520 max = build_real (expr_type, maxval);
1522 /* For unsigned, assume -1.0 is always representable. */
1523 if (uns_p)
1524 min = build_minus_one_cst (expr_type);
1525 else
1527 /* Use mpfr_snprintf rounding to compute the largest
1528 representable decimal number less or equal than
1529 (-1 << (prec - 1)) - 1. */
1530 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1531 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1532 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1533 decimal_real_from_string (&minval, buf);
1534 min = build_real (expr_type, minval);
1536 mpfr_clear (m);
1538 else
1539 return NULL_TREE;
1541 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1542 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1543 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1544 if (integer_zerop (t))
1545 return NULL_TREE;
1547 if (flag_sanitize_undefined_trap_on_error)
1548 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1549 else
1551 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1552 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1553 NULL, ubsan_type_descriptor (expr_type),
1554 ubsan_type_descriptor (type), NULL_TREE,
1555 NULL_TREE);
1556 enum built_in_function bcode
1557 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1558 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1559 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1560 fn = builtin_decl_explicit (bcode);
1561 fn = build_call_expr_loc (loc, fn, 2,
1562 build_fold_addr_expr_loc (loc, data),
1563 ubsan_encode_value (arg, false));
1566 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1569 /* Instrument values passed to function arguments with nonnull attribute. */
1571 static void
1572 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1574 gimple stmt = gsi_stmt (*gsi);
1575 location_t loc[2];
1576 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1577 while for nonnull sanitization it is clear. */
1578 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1579 flag_delete_null_pointer_checks = 1;
1580 loc[0] = gimple_location (stmt);
1581 loc[1] = UNKNOWN_LOCATION;
1582 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1584 tree arg = gimple_call_arg (stmt, i);
1585 if (POINTER_TYPE_P (TREE_TYPE (arg))
1586 && infer_nonnull_range (stmt, arg, false, true))
1588 gimple g;
1589 if (!is_gimple_val (arg))
1591 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1592 gimple_set_location (g, loc[0]);
1593 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1594 arg = gimple_assign_lhs (g);
1597 basic_block then_bb, fallthru_bb;
1598 *gsi = create_cond_insert_point (gsi, true, false, true,
1599 &then_bb, &fallthru_bb);
1600 g = gimple_build_cond (EQ_EXPR, arg,
1601 build_zero_cst (TREE_TYPE (arg)),
1602 NULL_TREE, NULL_TREE);
1603 gimple_set_location (g, loc[0]);
1604 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1606 *gsi = gsi_after_labels (then_bb);
1607 if (flag_sanitize_undefined_trap_on_error)
1608 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1609 else
1611 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1612 2, loc, NULL_TREE,
1613 build_int_cst (integer_type_node,
1614 i + 1),
1615 NULL_TREE);
1616 data = build_fold_addr_expr_loc (loc[0], data);
1617 enum built_in_function bcode
1618 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1619 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1620 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1621 tree fn = builtin_decl_explicit (bcode);
1623 g = gimple_build_call (fn, 1, data);
1625 gimple_set_location (g, loc[0]);
1626 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1628 *gsi = gsi_for_stmt (stmt);
1630 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1633 /* Instrument returns in functions with returns_nonnull attribute. */
1635 static void
1636 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1638 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1639 location_t loc[2];
1640 tree arg = gimple_return_retval (stmt);
1641 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1642 while for nonnull return sanitization it is clear. */
1643 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1644 flag_delete_null_pointer_checks = 1;
1645 loc[0] = gimple_location (stmt);
1646 loc[1] = UNKNOWN_LOCATION;
1647 if (arg
1648 && POINTER_TYPE_P (TREE_TYPE (arg))
1649 && is_gimple_val (arg)
1650 && infer_nonnull_range (stmt, arg, false, true))
1652 basic_block then_bb, fallthru_bb;
1653 *gsi = create_cond_insert_point (gsi, true, false, true,
1654 &then_bb, &fallthru_bb);
1655 gimple g = gimple_build_cond (EQ_EXPR, arg,
1656 build_zero_cst (TREE_TYPE (arg)),
1657 NULL_TREE, NULL_TREE);
1658 gimple_set_location (g, loc[0]);
1659 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1661 *gsi = gsi_after_labels (then_bb);
1662 if (flag_sanitize_undefined_trap_on_error)
1663 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1664 else
1666 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1667 2, loc, NULL_TREE, NULL_TREE);
1668 data = build_fold_addr_expr_loc (loc[0], data);
1669 enum built_in_function bcode
1670 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1671 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1672 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_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 *gsi = gsi_for_stmt (stmt);
1681 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1684 /* Instrument memory references. Here we check whether the pointer
1685 points to an out-of-bounds location. */
1687 static void
1688 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1690 gimple stmt = gsi_stmt (*gsi);
1691 location_t loc = gimple_location (stmt);
1692 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1693 tree type;
1694 tree index = NULL_TREE;
1695 HOST_WIDE_INT size_in_bytes;
1697 type = TREE_TYPE (t);
1698 if (VOID_TYPE_P (type))
1699 return;
1701 switch (TREE_CODE (t))
1703 case COMPONENT_REF:
1704 if (TREE_CODE (t) == COMPONENT_REF
1705 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1707 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1708 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1709 repr, NULL_TREE);
1711 break;
1712 case ARRAY_REF:
1713 index = TREE_OPERAND (t, 1);
1714 break;
1715 case INDIRECT_REF:
1716 case MEM_REF:
1717 case VAR_DECL:
1718 case PARM_DECL:
1719 case RESULT_DECL:
1720 break;
1721 default:
1722 return;
1725 size_in_bytes = int_size_in_bytes (type);
1726 if (size_in_bytes <= 0)
1727 return;
1729 HOST_WIDE_INT bitsize, bitpos;
1730 tree offset;
1731 machine_mode mode;
1732 int volatilep = 0, unsignedp = 0;
1733 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1734 &unsignedp, &volatilep, false);
1736 if (bitpos % BITS_PER_UNIT != 0
1737 || bitsize != size_in_bytes * BITS_PER_UNIT)
1738 return;
1740 bool decl_p = DECL_P (inner);
1741 tree base;
1742 if (decl_p)
1743 base = inner;
1744 else if (TREE_CODE (inner) == MEM_REF)
1745 base = TREE_OPERAND (inner, 0);
1746 else
1747 return;
1748 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1750 while (TREE_CODE (base) == SSA_NAME)
1752 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1753 if (gimple_assign_ssa_name_copy_p (def_stmt)
1754 || (gimple_assign_cast_p (def_stmt)
1755 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1756 || (is_gimple_assign (def_stmt)
1757 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1759 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1760 if (TREE_CODE (rhs1) == SSA_NAME
1761 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1762 break;
1763 else
1764 base = rhs1;
1766 else
1767 break;
1770 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1771 return;
1773 tree sizet;
1774 tree base_addr = base;
1775 if (decl_p)
1776 base_addr = build1 (ADDR_EXPR,
1777 build_pointer_type (TREE_TYPE (base)), base);
1778 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1779 if (size != (unsigned HOST_WIDE_INT) -1)
1780 sizet = build_int_cst (sizetype, size);
1781 else if (optimize)
1783 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1784 loc = input_location;
1785 /* Generate __builtin_object_size call. */
1786 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1787 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1788 integer_zero_node);
1789 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1790 GSI_SAME_STMT);
1792 else
1793 return;
1795 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1796 call. */
1797 /* ptr + sizeof (*ptr) - base */
1798 t = fold_build2 (MINUS_EXPR, sizetype,
1799 fold_convert (pointer_sized_int_node, ptr),
1800 fold_convert (pointer_sized_int_node, base_addr));
1801 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1803 /* Perhaps we can omit the check. */
1804 if (TREE_CODE (t) == INTEGER_CST
1805 && TREE_CODE (sizet) == INTEGER_CST
1806 && tree_int_cst_le (t, sizet))
1807 return;
1809 if (index != NULL_TREE
1810 && TREE_CODE (index) == SSA_NAME
1811 && TREE_CODE (sizet) == INTEGER_CST)
1813 gimple def = SSA_NAME_DEF_STMT (index);
1814 if (is_gimple_assign (def)
1815 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1816 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1818 tree cst = gimple_assign_rhs2 (def);
1819 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1820 TYPE_SIZE_UNIT (type));
1821 if (tree_int_cst_sgn (cst) >= 0
1822 && tree_int_cst_lt (cst, sz))
1823 return;
1827 /* Nope. Emit the check. */
1828 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1829 GSI_SAME_STMT);
1830 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1831 GSI_SAME_STMT);
1832 tree ckind = build_int_cst (unsigned_char_type_node,
1833 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1834 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1835 ptr, t, sizet, ckind);
1836 gimple_set_location (g, loc);
1837 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1840 /* True if we want to play UBSan games in the current function. */
1842 bool
1843 do_ubsan_in_current_function ()
1845 return (current_function_decl != NULL_TREE
1846 && !lookup_attribute ("no_sanitize_undefined",
1847 DECL_ATTRIBUTES (current_function_decl)));
1850 namespace {
1852 const pass_data pass_data_ubsan =
1854 GIMPLE_PASS, /* type */
1855 "ubsan", /* name */
1856 OPTGROUP_NONE, /* optinfo_flags */
1857 TV_TREE_UBSAN, /* tv_id */
1858 ( PROP_cfg | PROP_ssa ), /* properties_required */
1859 0, /* properties_provided */
1860 0, /* properties_destroyed */
1861 0, /* todo_flags_start */
1862 TODO_update_ssa, /* todo_flags_finish */
1865 class pass_ubsan : public gimple_opt_pass
1867 public:
1868 pass_ubsan (gcc::context *ctxt)
1869 : gimple_opt_pass (pass_data_ubsan, ctxt)
1872 /* opt_pass methods: */
1873 virtual bool gate (function *)
1875 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1876 | SANITIZE_BOOL | SANITIZE_ENUM
1877 | SANITIZE_ALIGNMENT
1878 | SANITIZE_NONNULL_ATTRIBUTE
1879 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1880 | SANITIZE_OBJECT_SIZE)
1881 && do_ubsan_in_current_function ();
1884 virtual unsigned int execute (function *);
1886 }; // class pass_ubsan
1888 unsigned int
1889 pass_ubsan::execute (function *fun)
1891 basic_block bb;
1892 gimple_stmt_iterator gsi;
1894 initialize_sanitizer_builtins ();
1896 FOR_EACH_BB_FN (bb, fun)
1898 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1900 gimple stmt = gsi_stmt (gsi);
1901 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1903 gsi_next (&gsi);
1904 continue;
1907 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1908 && is_gimple_assign (stmt))
1909 instrument_si_overflow (gsi);
1911 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1913 if (gimple_store_p (stmt))
1914 instrument_null (gsi, true);
1915 if (gimple_assign_load_p (stmt))
1916 instrument_null (gsi, false);
1919 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1920 && gimple_assign_load_p (stmt))
1922 instrument_bool_enum_load (&gsi);
1923 bb = gimple_bb (stmt);
1926 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1927 && is_gimple_call (stmt)
1928 && !gimple_call_internal_p (stmt))
1930 instrument_nonnull_arg (&gsi);
1931 bb = gimple_bb (stmt);
1934 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1935 && gimple_code (stmt) == GIMPLE_RETURN)
1937 instrument_nonnull_return (&gsi);
1938 bb = gimple_bb (stmt);
1941 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
1943 if (gimple_store_p (stmt))
1944 instrument_object_size (&gsi, true);
1945 if (gimple_assign_load_p (stmt))
1946 instrument_object_size (&gsi, false);
1949 gsi_next (&gsi);
1952 return 0;
1955 } // anon namespace
1957 gimple_opt_pass *
1958 make_pass_ubsan (gcc::context *ctxt)
1960 return new pass_ubsan (ctxt);
1963 #include "gt-ubsan.h"