2015-01-23 Bernd Edlinger <bernd.edlinger@hotmail.de>
[official-gcc.git] / gcc / ubsan.c
bloba9df290a7295df156749fc0765d044f894933862
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);
332 str = build_string (len + 1, xloc.file);
333 TREE_TYPE (str) = build_array_type (char_type_node,
334 build_index_type (size_int (len)));
335 TREE_READONLY (str) = 1;
336 TREE_STATIC (str) = 1;
337 str = build_fold_addr_expr (str);
339 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
340 build_int_cst (unsigned_type_node,
341 xloc.line), NULL_TREE,
342 build_int_cst (unsigned_type_node,
343 xloc.column));
344 TREE_CONSTANT (ctor) = 1;
345 TREE_STATIC (ctor) = 1;
347 return ctor;
350 /* This routine returns a magic number for TYPE. */
352 static unsigned short
353 get_ubsan_type_info_for_type (tree type)
355 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
356 if (TREE_CODE (type) == REAL_TYPE)
357 return tree_to_uhwi (TYPE_SIZE (type));
358 else if (INTEGRAL_TYPE_P (type))
360 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
361 gcc_assert (prec != -1);
362 return (prec << 1) | !TYPE_UNSIGNED (type);
364 else
365 return 0;
368 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
369 descriptor. It first looks into the hash table; if not found,
370 create the VAR_DECL, put it into the hash table and return the
371 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
372 an enum controlling how we want to print the type. */
374 tree
375 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
377 /* See through any typedefs. */
378 type = TYPE_MAIN_VARIANT (type);
380 tree decl = decl_for_type_lookup (type);
381 /* It is possible that some of the earlier created DECLs were found
382 unused, in that case they weren't emitted and varpool_node::get
383 returns NULL node on them. But now we really need them. Thus,
384 renew them here. */
385 if (decl != NULL_TREE && varpool_node::get (decl))
386 return build_fold_addr_expr (decl);
388 tree dtype = ubsan_get_type_descriptor_type ();
389 tree type2 = type;
390 const char *tname = NULL;
391 pretty_printer pretty_name;
392 unsigned char deref_depth = 0;
393 unsigned short tkind, tinfo;
395 /* Get the name of the type, or the name of the pointer type. */
396 if (pstyle == UBSAN_PRINT_POINTER)
398 gcc_assert (POINTER_TYPE_P (type));
399 type2 = TREE_TYPE (type);
401 /* Remove any '*' operators from TYPE. */
402 while (POINTER_TYPE_P (type2))
403 deref_depth++, type2 = TREE_TYPE (type2);
405 if (TREE_CODE (type2) == METHOD_TYPE)
406 type2 = TYPE_METHOD_BASETYPE (type2);
409 /* If an array, get its type. */
410 type2 = strip_array_types (type2);
412 if (pstyle == UBSAN_PRINT_ARRAY)
414 while (POINTER_TYPE_P (type2))
415 deref_depth++, type2 = TREE_TYPE (type2);
418 if (TYPE_NAME (type2) != NULL)
420 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
421 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
422 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
423 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
426 if (tname == NULL)
427 /* We weren't able to determine the type name. */
428 tname = "<unknown>";
430 if (pstyle == UBSAN_PRINT_POINTER)
432 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
433 TYPE_VOLATILE (type2) ? "volatile " : "",
434 TYPE_READONLY (type2) ? "const " : "",
435 TYPE_RESTRICT (type2) ? "restrict " : "",
436 TYPE_ATOMIC (type2) ? "_Atomic " : "",
437 TREE_CODE (type2) == RECORD_TYPE
438 ? "struct "
439 : TREE_CODE (type2) == UNION_TYPE
440 ? "union " : "", tname,
441 deref_depth == 0 ? "" : " ");
442 while (deref_depth-- > 0)
443 pp_star (&pretty_name);
444 pp_quote (&pretty_name);
446 else if (pstyle == UBSAN_PRINT_ARRAY)
448 /* Pretty print the array dimensions. */
449 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
450 tree t = type;
451 pp_printf (&pretty_name, "'%s ", tname);
452 while (deref_depth-- > 0)
453 pp_star (&pretty_name);
454 while (TREE_CODE (t) == ARRAY_TYPE)
456 pp_left_bracket (&pretty_name);
457 tree dom = TYPE_DOMAIN (t);
458 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
460 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
461 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
462 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
463 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
464 else
465 pp_wide_int (&pretty_name,
466 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
467 TYPE_SIGN (TREE_TYPE (dom)));
469 else
470 /* ??? We can't determine the variable name; print VLA unspec. */
471 pp_star (&pretty_name);
472 pp_right_bracket (&pretty_name);
473 t = TREE_TYPE (t);
475 pp_quote (&pretty_name);
477 /* Save the tree with stripped types. */
478 type = t;
480 else
481 pp_printf (&pretty_name, "'%s'", tname);
483 switch (TREE_CODE (type))
485 case BOOLEAN_TYPE:
486 case ENUMERAL_TYPE:
487 case INTEGER_TYPE:
488 tkind = 0x0000;
489 break;
490 case REAL_TYPE:
491 /* FIXME: libubsan right now only supports float, double and
492 long double type formats. */
493 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
494 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
495 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
496 tkind = 0x0001;
497 else
498 tkind = 0xffff;
499 break;
500 default:
501 tkind = 0xffff;
502 break;
504 tinfo = get_ubsan_type_info_for_type (type);
506 /* Create a new VAR_DECL of type descriptor. */
507 char tmp_name[32];
508 static unsigned int type_var_id_num;
509 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
510 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
511 dtype);
512 TREE_STATIC (decl) = 1;
513 TREE_PUBLIC (decl) = 0;
514 DECL_ARTIFICIAL (decl) = 1;
515 DECL_IGNORED_P (decl) = 1;
516 DECL_EXTERNAL (decl) = 0;
518 const char *tmp = pp_formatted_text (&pretty_name);
519 size_t len = strlen (tmp);
520 tree str = build_string (len + 1, tmp);
521 TREE_TYPE (str) = build_array_type (char_type_node,
522 build_index_type (size_int (len)));
523 TREE_READONLY (str) = 1;
524 TREE_STATIC (str) = 1;
525 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
526 build_int_cst (short_unsigned_type_node,
527 tkind), NULL_TREE,
528 build_int_cst (short_unsigned_type_node,
529 tinfo), NULL_TREE, str);
530 TREE_CONSTANT (ctor) = 1;
531 TREE_STATIC (ctor) = 1;
532 DECL_INITIAL (decl) = ctor;
533 varpool_node::finalize_decl (decl);
535 /* Save the VAR_DECL into the hash table. */
536 decl_for_type_insert (type, decl);
538 return build_fold_addr_expr (decl);
541 /* Create a structure for the ubsan library. NAME is a name of the new
542 structure. LOCCNT is number of locations, PLOC points to array of
543 locations. The arguments in ... are of __ubsan_type_descriptor type
544 and there are at most two of them, followed by NULL_TREE, followed
545 by optional extra arguments and another NULL_TREE. */
547 tree
548 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
550 va_list args;
551 tree ret, t;
552 tree fields[6];
553 vec<tree, va_gc> *saved_args = NULL;
554 size_t i = 0;
555 int j;
557 /* Firstly, create a pointer to type descriptor type. */
558 tree td_type = ubsan_get_type_descriptor_type ();
559 td_type = build_pointer_type (td_type);
561 /* Create the structure type. */
562 ret = make_node (RECORD_TYPE);
563 for (j = 0; j < loccnt; j++)
565 gcc_checking_assert (i < 2);
566 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
567 ubsan_get_source_location_type ());
568 DECL_CONTEXT (fields[i]) = ret;
569 if (i)
570 DECL_CHAIN (fields[i - 1]) = fields[i];
571 i++;
574 va_start (args, ploc);
575 for (t = va_arg (args, tree); t != NULL_TREE;
576 i++, t = va_arg (args, tree))
578 gcc_checking_assert (i < 4);
579 /* Save the tree arguments for later use. */
580 vec_safe_push (saved_args, t);
581 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
582 td_type);
583 DECL_CONTEXT (fields[i]) = ret;
584 if (i)
585 DECL_CHAIN (fields[i - 1]) = fields[i];
588 for (t = va_arg (args, tree); t != NULL_TREE;
589 i++, t = va_arg (args, tree))
591 gcc_checking_assert (i < 6);
592 /* Save the tree arguments for later use. */
593 vec_safe_push (saved_args, t);
594 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
595 TREE_TYPE (t));
596 DECL_CONTEXT (fields[i]) = ret;
597 if (i)
598 DECL_CHAIN (fields[i - 1]) = fields[i];
600 va_end (args);
602 tree type_decl = build_decl (input_location, TYPE_DECL,
603 get_identifier (name), ret);
604 DECL_IGNORED_P (type_decl) = 1;
605 DECL_ARTIFICIAL (type_decl) = 1;
606 TYPE_FIELDS (ret) = fields[0];
607 TYPE_NAME (ret) = type_decl;
608 TYPE_STUB_DECL (ret) = type_decl;
609 layout_type (ret);
611 /* Now, fill in the type. */
612 char tmp_name[32];
613 static unsigned int ubsan_var_id_num;
614 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
615 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
616 ret);
617 TREE_STATIC (var) = 1;
618 TREE_PUBLIC (var) = 0;
619 DECL_ARTIFICIAL (var) = 1;
620 DECL_IGNORED_P (var) = 1;
621 DECL_EXTERNAL (var) = 0;
623 vec<constructor_elt, va_gc> *v;
624 vec_alloc (v, i);
625 tree ctor = build_constructor (ret, v);
627 /* If desirable, set the __ubsan_source_location element. */
628 for (j = 0; j < loccnt; j++)
630 location_t loc = LOCATION_LOCUS (ploc[j]);
631 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
634 size_t nelts = vec_safe_length (saved_args);
635 for (i = 0; i < nelts; i++)
637 t = (*saved_args)[i];
638 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
641 TREE_CONSTANT (ctor) = 1;
642 TREE_STATIC (ctor) = 1;
643 DECL_INITIAL (var) = ctor;
644 varpool_node::finalize_decl (var);
646 return var;
649 /* Instrument the __builtin_unreachable call. We just call the libubsan
650 routine instead. */
652 bool
653 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
655 gimple g;
656 location_t loc = gimple_location (gsi_stmt (*gsi));
658 if (flag_sanitize_undefined_trap_on_error)
659 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
660 else
662 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
663 NULL_TREE, NULL_TREE);
664 data = build_fold_addr_expr_loc (loc, data);
665 tree fn
666 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
667 g = gimple_build_call (fn, 1, data);
669 gimple_set_location (g, loc);
670 gsi_replace (gsi, g, false);
671 return false;
674 /* Return true if T is a call to a libubsan routine. */
676 bool
677 is_ubsan_builtin_p (tree t)
679 return TREE_CODE (t) == FUNCTION_DECL
680 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
681 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
682 "__builtin___ubsan_", 18) == 0;
685 /* Expand the UBSAN_BOUNDS special builtin function. */
687 bool
688 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
690 gimple stmt = gsi_stmt (*gsi);
691 location_t loc = gimple_location (stmt);
692 gcc_assert (gimple_call_num_args (stmt) == 3);
694 /* Pick up the arguments of the UBSAN_BOUNDS call. */
695 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
696 tree index = gimple_call_arg (stmt, 1);
697 tree orig_index_type = TREE_TYPE (index);
698 tree bound = gimple_call_arg (stmt, 2);
700 gimple_stmt_iterator gsi_orig = *gsi;
702 /* Create condition "if (index > bound)". */
703 basic_block then_bb, fallthru_bb;
704 gimple_stmt_iterator cond_insert_point
705 = create_cond_insert_point (gsi, false, false, true,
706 &then_bb, &fallthru_bb);
707 index = fold_convert (TREE_TYPE (bound), index);
708 index = force_gimple_operand_gsi (&cond_insert_point, index,
709 true, NULL_TREE,
710 false, GSI_NEW_STMT);
711 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
712 gimple_set_location (g, loc);
713 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
715 /* Generate __ubsan_handle_out_of_bounds call. */
716 *gsi = gsi_after_labels (then_bb);
717 if (flag_sanitize_undefined_trap_on_error)
718 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
719 else
721 tree data
722 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
723 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
724 ubsan_type_descriptor (orig_index_type),
725 NULL_TREE, NULL_TREE);
726 data = build_fold_addr_expr_loc (loc, data);
727 enum built_in_function bcode
728 = (flag_sanitize_recover & SANITIZE_BOUNDS)
729 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
730 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
731 tree fn = builtin_decl_explicit (bcode);
732 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
733 true, NULL_TREE, true,
734 GSI_SAME_STMT);
735 g = gimple_build_call (fn, 2, data, val);
737 gimple_set_location (g, loc);
738 gsi_insert_before (gsi, g, GSI_SAME_STMT);
740 /* Get rid of the UBSAN_BOUNDS call from the IR. */
741 unlink_stmt_vdef (stmt);
742 gsi_remove (&gsi_orig, true);
744 /* Point GSI to next logical statement. */
745 *gsi = gsi_start_bb (fallthru_bb);
746 return true;
749 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
750 argument which is a constant, because the middle-end treats pointer
751 conversions as useless and therefore the type of the first argument
752 could be changed to any other pointer type. */
754 bool
755 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
757 gimple_stmt_iterator gsi = *gsip;
758 gimple stmt = gsi_stmt (gsi);
759 location_t loc = gimple_location (stmt);
760 gcc_assert (gimple_call_num_args (stmt) == 3);
761 tree ptr = gimple_call_arg (stmt, 0);
762 tree ckind = gimple_call_arg (stmt, 1);
763 tree align = gimple_call_arg (stmt, 2);
764 tree check_align = NULL_TREE;
765 bool check_null;
767 basic_block cur_bb = gsi_bb (gsi);
769 gimple g;
770 if (!integer_zerop (align))
772 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
773 if (compare_tree_int (align, ptralign) == 1)
775 check_align = make_ssa_name (pointer_sized_int_node);
776 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
777 gimple_set_location (g, loc);
778 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
781 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
783 if (check_align == NULL_TREE && !check_null)
785 gsi_remove (gsip, true);
786 /* Unlink the UBSAN_NULLs vops before replacing it. */
787 unlink_stmt_vdef (stmt);
788 return true;
791 /* Split the original block holding the pointer dereference. */
792 edge e = split_block (cur_bb, stmt);
794 /* Get a hold on the 'condition block', the 'then block' and the
795 'else block'. */
796 basic_block cond_bb = e->src;
797 basic_block fallthru_bb = e->dest;
798 basic_block then_bb = create_empty_bb (cond_bb);
799 add_bb_to_loop (then_bb, cond_bb->loop_father);
800 loops_state_set (LOOPS_NEED_FIXUP);
802 /* Make an edge coming from the 'cond block' into the 'then block';
803 this edge is unlikely taken, so set up the probability accordingly. */
804 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
805 e->probability = PROB_VERY_UNLIKELY;
807 /* Connect 'then block' with the 'else block'. This is needed
808 as the ubsan routines we call in the 'then block' are not noreturn.
809 The 'then block' only has one outcoming edge. */
810 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
812 /* Set up the fallthrough basic block. */
813 e = find_edge (cond_bb, fallthru_bb);
814 e->flags = EDGE_FALSE_VALUE;
815 e->count = cond_bb->count;
816 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
818 /* Update dominance info for the newly created then_bb; note that
819 fallthru_bb's dominance info has already been updated by
820 split_block. */
821 if (dom_info_available_p (CDI_DOMINATORS))
822 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
824 /* Put the ubsan builtin call into the newly created BB. */
825 if (flag_sanitize_undefined_trap_on_error)
826 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
827 else
829 enum built_in_function bcode
830 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
831 | (check_null ? SANITIZE_NULL : 0)))
832 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
833 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
834 tree fn = builtin_decl_implicit (bcode);
835 tree data
836 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
837 ubsan_type_descriptor (TREE_TYPE (ckind),
838 UBSAN_PRINT_POINTER),
839 NULL_TREE,
840 align,
841 fold_convert (unsigned_char_type_node, ckind),
842 NULL_TREE);
843 data = build_fold_addr_expr_loc (loc, data);
844 g = gimple_build_call (fn, 2, data,
845 check_align ? check_align
846 : build_zero_cst (pointer_sized_int_node));
848 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
849 gimple_set_location (g, loc);
850 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
852 /* Unlink the UBSAN_NULLs vops before replacing it. */
853 unlink_stmt_vdef (stmt);
855 if (check_null)
857 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
858 NULL_TREE, NULL_TREE);
859 gimple_set_location (g, loc);
861 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
862 gsi_replace (&gsi, g, false);
865 if (check_align)
867 if (check_null)
869 /* Split the block with the condition again. */
870 e = split_block (cond_bb, stmt);
871 basic_block cond1_bb = e->src;
872 basic_block cond2_bb = e->dest;
874 /* Make an edge coming from the 'cond1 block' into the 'then block';
875 this edge is unlikely taken, so set up the probability
876 accordingly. */
877 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
878 e->probability = PROB_VERY_UNLIKELY;
880 /* Set up the fallthrough basic block. */
881 e = find_edge (cond1_bb, cond2_bb);
882 e->flags = EDGE_FALSE_VALUE;
883 e->count = cond1_bb->count;
884 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
886 /* Update dominance info. */
887 if (dom_info_available_p (CDI_DOMINATORS))
889 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
890 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
893 gsi2 = gsi_start_bb (cond2_bb);
896 tree mask = build_int_cst (pointer_sized_int_node,
897 tree_to_uhwi (align) - 1);
898 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
899 BIT_AND_EXPR, check_align, mask);
900 gimple_set_location (g, loc);
901 if (check_null)
902 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
903 else
904 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
906 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
907 build_int_cst (pointer_sized_int_node, 0),
908 NULL_TREE, NULL_TREE);
909 gimple_set_location (g, loc);
910 if (check_null)
911 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
912 else
913 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
914 gsi_replace (&gsi, g, false);
916 return false;
919 /* Expand UBSAN_OBJECT_SIZE internal call. */
921 bool
922 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
924 gimple stmt = gsi_stmt (*gsi);
925 location_t loc = gimple_location (stmt);
926 gcc_assert (gimple_call_num_args (stmt) == 4);
928 tree ptr = gimple_call_arg (stmt, 0);
929 tree offset = gimple_call_arg (stmt, 1);
930 tree size = gimple_call_arg (stmt, 2);
931 tree ckind = gimple_call_arg (stmt, 3);
932 gimple_stmt_iterator gsi_orig = *gsi;
933 gimple g;
935 /* See if we can discard the check. */
936 if (TREE_CODE (size) != INTEGER_CST
937 || integer_all_onesp (size))
938 /* Yes, __builtin_object_size couldn't determine the
939 object size. */;
940 else
942 /* if (offset > objsize) */
943 basic_block then_bb, fallthru_bb;
944 gimple_stmt_iterator cond_insert_point
945 = create_cond_insert_point (gsi, false, false, true,
946 &then_bb, &fallthru_bb);
947 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
948 gimple_set_location (g, loc);
949 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
951 /* Generate __ubsan_handle_type_mismatch call. */
952 *gsi = gsi_after_labels (then_bb);
953 if (flag_sanitize_undefined_trap_on_error)
954 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
955 else
957 tree data
958 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
959 ubsan_type_descriptor (TREE_TYPE (ptr),
960 UBSAN_PRINT_POINTER),
961 NULL_TREE,
962 build_zero_cst (pointer_sized_int_node),
963 ckind,
964 NULL_TREE);
965 data = build_fold_addr_expr_loc (loc, data);
966 enum built_in_function bcode
967 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
968 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
969 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
970 tree p = make_ssa_name (pointer_sized_int_node);
971 g = gimple_build_assign (p, NOP_EXPR, ptr);
972 gimple_set_location (g, loc);
973 gsi_insert_before (gsi, g, GSI_SAME_STMT);
974 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
976 gimple_set_location (g, loc);
977 gsi_insert_before (gsi, g, GSI_SAME_STMT);
979 /* Point GSI to next logical statement. */
980 *gsi = gsi_start_bb (fallthru_bb);
983 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
984 unlink_stmt_vdef (stmt);
985 gsi_remove (&gsi_orig, true);
986 return gsi_end_p (*gsi);
989 /* Cached __ubsan_vptr_type_cache decl. */
990 static GTY(()) tree ubsan_vptr_type_cache_decl;
992 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
993 argument which is a constant, because the middle-end treats pointer
994 conversions as useless and therefore the type of the first argument
995 could be changed to any other pointer type. */
997 bool
998 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1000 gimple_stmt_iterator gsi = *gsip;
1001 gimple stmt = gsi_stmt (gsi);
1002 location_t loc = gimple_location (stmt);
1003 gcc_assert (gimple_call_num_args (stmt) == 5);
1004 tree op = gimple_call_arg (stmt, 0);
1005 tree vptr = gimple_call_arg (stmt, 1);
1006 tree str_hash = gimple_call_arg (stmt, 2);
1007 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1008 tree ckind_tree = gimple_call_arg (stmt, 4);
1009 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1010 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1011 gimple g;
1012 basic_block fallthru_bb = NULL;
1014 if (ckind == UBSAN_DOWNCAST_POINTER)
1016 /* Guard everything with if (op != NULL) { ... }. */
1017 basic_block then_bb;
1018 gimple_stmt_iterator cond_insert_point
1019 = create_cond_insert_point (gsip, false, false, true,
1020 &then_bb, &fallthru_bb);
1021 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1022 NULL_TREE, NULL_TREE);
1023 gimple_set_location (g, loc);
1024 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1025 *gsip = gsi_after_labels (then_bb);
1026 gsi_remove (&gsi, false);
1027 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1028 gsi = *gsip;
1031 tree htype = TREE_TYPE (str_hash);
1032 tree cst = wide_int_to_tree (htype,
1033 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1034 | 0xeb382d69, 64));
1035 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1036 vptr, str_hash);
1037 gimple_set_location (g, loc);
1038 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1039 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1040 gimple_assign_lhs (g), cst);
1041 gimple_set_location (g, loc);
1042 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1043 tree t1 = gimple_assign_lhs (g);
1044 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1045 t1, build_int_cst (integer_type_node, 47));
1046 gimple_set_location (g, loc);
1047 tree t2 = gimple_assign_lhs (g);
1048 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1049 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1050 vptr, t1);
1051 gimple_set_location (g, loc);
1052 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1053 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1054 t2, gimple_assign_lhs (g));
1055 gimple_set_location (g, loc);
1056 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1057 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1058 gimple_assign_lhs (g), cst);
1059 gimple_set_location (g, loc);
1060 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1061 tree t3 = gimple_assign_lhs (g);
1062 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1063 t3, build_int_cst (integer_type_node, 47));
1064 gimple_set_location (g, loc);
1065 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1066 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1067 t3, gimple_assign_lhs (g));
1068 gimple_set_location (g, loc);
1069 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1070 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1071 gimple_assign_lhs (g), cst);
1072 gimple_set_location (g, loc);
1073 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1074 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1076 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1077 NOP_EXPR, gimple_assign_lhs (g));
1078 gimple_set_location (g, loc);
1079 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1081 tree hash = gimple_assign_lhs (g);
1083 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1085 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1086 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1087 get_identifier ("__ubsan_vptr_type_cache"),
1088 atype);
1089 DECL_ARTIFICIAL (array) = 1;
1090 DECL_IGNORED_P (array) = 1;
1091 TREE_PUBLIC (array) = 1;
1092 TREE_STATIC (array) = 1;
1093 DECL_EXTERNAL (array) = 1;
1094 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1095 DECL_VISIBILITY_SPECIFIED (array) = 1;
1096 varpool_node::finalize_decl (array);
1097 ubsan_vptr_type_cache_decl = array;
1100 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1101 BIT_AND_EXPR, hash,
1102 build_int_cst (pointer_sized_int_node, 127));
1103 gimple_set_location (g, loc);
1104 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1106 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1107 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1108 NULL_TREE, NULL_TREE);
1109 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1110 ARRAY_REF, c);
1111 gimple_set_location (g, loc);
1112 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1114 basic_block then_bb, fallthru2_bb;
1115 gimple_stmt_iterator cond_insert_point
1116 = create_cond_insert_point (gsip, false, false, true,
1117 &then_bb, &fallthru2_bb);
1118 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1119 NULL_TREE, NULL_TREE);
1120 gimple_set_location (g, loc);
1121 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1122 *gsip = gsi_after_labels (then_bb);
1123 if (fallthru_bb == NULL)
1124 fallthru_bb = fallthru2_bb;
1126 tree data
1127 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1128 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1129 build_int_cst (unsigned_char_type_node, ckind),
1130 NULL_TREE);
1131 data = build_fold_addr_expr_loc (loc, data);
1132 enum built_in_function bcode
1133 = (flag_sanitize_recover & SANITIZE_VPTR)
1134 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1135 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1137 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1138 gimple_set_location (g, loc);
1139 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1141 /* Point GSI to next logical statement. */
1142 *gsip = gsi_start_bb (fallthru_bb);
1144 /* Get rid of the UBSAN_VPTR call from the IR. */
1145 unlink_stmt_vdef (stmt);
1146 gsi_remove (&gsi, true);
1147 return gsi_end_p (*gsip);
1150 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1151 whether the pointer is on the left hand side of the assignment. */
1153 static void
1154 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1155 bool is_lhs)
1157 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1158 unsigned int align = 0;
1159 if (flag_sanitize & SANITIZE_ALIGNMENT)
1161 align = min_align_of_type (TREE_TYPE (base));
1162 if (align <= 1)
1163 align = 0;
1165 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1166 return;
1167 tree t = TREE_OPERAND (base, 0);
1168 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1169 return;
1170 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && mem != base)
1171 ikind = UBSAN_MEMBER_ACCESS;
1172 tree kind = build_int_cst (TREE_TYPE (t), ikind);
1173 tree alignt = build_int_cst (pointer_sized_int_node, align);
1174 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1175 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1176 gsi_insert_before (iter, g, GSI_SAME_STMT);
1179 /* Perform the pointer instrumentation. */
1181 static void
1182 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1184 gimple stmt = gsi_stmt (gsi);
1185 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1186 tree base = get_base_address (t);
1187 const enum tree_code code = TREE_CODE (base);
1188 if (code == MEM_REF
1189 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1190 instrument_mem_ref (t, base, &gsi, is_lhs);
1193 /* Build an ubsan builtin call for the signed-integer-overflow
1194 sanitization. CODE says what kind of builtin are we building,
1195 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1196 are operands of the binary operation. */
1198 tree
1199 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1200 tree op0, tree op1)
1202 if (flag_sanitize_undefined_trap_on_error)
1203 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1205 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1206 ubsan_type_descriptor (lhstype), NULL_TREE,
1207 NULL_TREE);
1208 enum built_in_function fn_code;
1210 switch (code)
1212 case PLUS_EXPR:
1213 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1214 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1215 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1216 break;
1217 case MINUS_EXPR:
1218 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1219 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1220 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1221 break;
1222 case MULT_EXPR:
1223 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1224 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1225 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1226 break;
1227 case NEGATE_EXPR:
1228 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1229 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1230 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1231 break;
1232 default:
1233 gcc_unreachable ();
1235 tree fn = builtin_decl_explicit (fn_code);
1236 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1237 build_fold_addr_expr_loc (loc, data),
1238 ubsan_encode_value (op0, true),
1239 op1 ? ubsan_encode_value (op1, true)
1240 : NULL_TREE);
1243 /* Perform the signed integer instrumentation. GSI is the iterator
1244 pointing at statement we are trying to instrument. */
1246 static void
1247 instrument_si_overflow (gimple_stmt_iterator gsi)
1249 gimple stmt = gsi_stmt (gsi);
1250 tree_code code = gimple_assign_rhs_code (stmt);
1251 tree lhs = gimple_assign_lhs (stmt);
1252 tree lhstype = TREE_TYPE (lhs);
1253 tree a, b;
1254 gimple g;
1256 /* If this is not a signed operation, don't instrument anything here.
1257 Also punt on bit-fields. */
1258 if (!INTEGRAL_TYPE_P (lhstype)
1259 || TYPE_OVERFLOW_WRAPS (lhstype)
1260 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1261 return;
1263 switch (code)
1265 case MINUS_EXPR:
1266 case PLUS_EXPR:
1267 case MULT_EXPR:
1268 /* Transform
1269 i = u {+,-,*} 5;
1270 into
1271 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1272 a = gimple_assign_rhs1 (stmt);
1273 b = gimple_assign_rhs2 (stmt);
1274 g = gimple_build_call_internal (code == PLUS_EXPR
1275 ? IFN_UBSAN_CHECK_ADD
1276 : code == MINUS_EXPR
1277 ? IFN_UBSAN_CHECK_SUB
1278 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1279 gimple_call_set_lhs (g, lhs);
1280 gsi_replace (&gsi, g, false);
1281 break;
1282 case NEGATE_EXPR:
1283 /* Represent i = -u;
1285 i = UBSAN_CHECK_SUB (0, u); */
1286 a = build_int_cst (lhstype, 0);
1287 b = gimple_assign_rhs1 (stmt);
1288 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1289 gimple_call_set_lhs (g, lhs);
1290 gsi_replace (&gsi, g, false);
1291 break;
1292 case ABS_EXPR:
1293 /* Transform i = ABS_EXPR<u>;
1294 into
1295 _N = UBSAN_CHECK_SUB (0, u);
1296 i = ABS_EXPR<_N>; */
1297 a = build_int_cst (lhstype, 0);
1298 b = gimple_assign_rhs1 (stmt);
1299 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1300 a = make_ssa_name (lhstype);
1301 gimple_call_set_lhs (g, a);
1302 gimple_set_location (g, gimple_location (stmt));
1303 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1304 gimple_assign_set_rhs1 (stmt, a);
1305 update_stmt (stmt);
1306 break;
1307 default:
1308 break;
1312 /* Instrument loads from (non-bitfield) bool and C++ enum values
1313 to check if the memory value is outside of the range of the valid
1314 type values. */
1316 static void
1317 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1319 gimple stmt = gsi_stmt (*gsi);
1320 tree rhs = gimple_assign_rhs1 (stmt);
1321 tree type = TREE_TYPE (rhs);
1322 tree minv = NULL_TREE, maxv = NULL_TREE;
1324 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1326 minv = boolean_false_node;
1327 maxv = boolean_true_node;
1329 else if (TREE_CODE (type) == ENUMERAL_TYPE
1330 && (flag_sanitize & SANITIZE_ENUM)
1331 && TREE_TYPE (type) != NULL_TREE
1332 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1333 && (TYPE_PRECISION (TREE_TYPE (type))
1334 < GET_MODE_PRECISION (TYPE_MODE (type))))
1336 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1337 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1339 else
1340 return;
1342 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1343 HOST_WIDE_INT bitsize, bitpos;
1344 tree offset;
1345 machine_mode mode;
1346 int volatilep = 0, unsignedp = 0;
1347 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1348 &unsignedp, &volatilep, false);
1349 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1351 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1352 || (bitpos % modebitsize) != 0
1353 || bitsize != modebitsize
1354 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1355 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1356 return;
1358 bool can_throw = stmt_could_throw_p (stmt);
1359 location_t loc = gimple_location (stmt);
1360 tree lhs = gimple_assign_lhs (stmt);
1361 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1362 tree atype = reference_alias_ptr_type (rhs);
1363 gimple g = gimple_build_assign (make_ssa_name (ptype),
1364 build_fold_addr_expr (rhs));
1365 gimple_set_location (g, loc);
1366 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1367 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1368 build_int_cst (atype, 0));
1369 tree urhs = make_ssa_name (utype);
1370 if (can_throw)
1372 gimple_assign_set_lhs (stmt, urhs);
1373 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1374 gimple_set_location (g, loc);
1375 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1376 gsi_insert_on_edge_immediate (e, g);
1377 gimple_assign_set_rhs_from_tree (gsi, mem);
1378 update_stmt (stmt);
1379 *gsi = gsi_for_stmt (g);
1380 g = stmt;
1382 else
1384 g = gimple_build_assign (urhs, mem);
1385 gimple_set_location (g, loc);
1386 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1388 minv = fold_convert (utype, minv);
1389 maxv = fold_convert (utype, maxv);
1390 if (!integer_zerop (minv))
1392 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1393 gimple_set_location (g, loc);
1394 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1397 gimple_stmt_iterator gsi2 = *gsi;
1398 basic_block then_bb, fallthru_bb;
1399 *gsi = create_cond_insert_point (gsi, true, false, true,
1400 &then_bb, &fallthru_bb);
1401 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1402 int_const_binop (MINUS_EXPR, maxv, minv),
1403 NULL_TREE, NULL_TREE);
1404 gimple_set_location (g, loc);
1405 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1407 if (!can_throw)
1409 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1410 update_stmt (stmt);
1413 gsi2 = gsi_after_labels (then_bb);
1414 if (flag_sanitize_undefined_trap_on_error)
1415 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1416 else
1418 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1419 ubsan_type_descriptor (type), NULL_TREE,
1420 NULL_TREE);
1421 data = build_fold_addr_expr_loc (loc, data);
1422 enum built_in_function bcode
1423 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1424 ? SANITIZE_BOOL : SANITIZE_ENUM))
1425 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1426 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1427 tree fn = builtin_decl_explicit (bcode);
1429 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1430 true, NULL_TREE, true,
1431 GSI_SAME_STMT);
1432 g = gimple_build_call (fn, 2, data, val);
1434 gimple_set_location (g, loc);
1435 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1436 *gsi = gsi_for_stmt (stmt);
1439 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1440 destination, EXPR is floating-point expression. ARG is what to pass
1441 the libubsan call as value, often EXPR itself. */
1443 tree
1444 ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
1446 tree expr_type = TREE_TYPE (expr);
1447 tree t, tt, fn, min, max;
1448 machine_mode mode = TYPE_MODE (expr_type);
1449 int prec = TYPE_PRECISION (type);
1450 bool uns_p = TYPE_UNSIGNED (type);
1452 /* Float to integer conversion first truncates toward zero, so
1453 even signed char c = 127.875f; is not problematic.
1454 Therefore, we should complain only if EXPR is unordered or smaller
1455 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1456 TYPE_MAX_VALUE + 1.0. */
1457 if (REAL_MODE_FORMAT (mode)->b == 2)
1459 /* For maximum, TYPE_MAX_VALUE might not be representable
1460 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1461 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1462 either representable or infinity. */
1463 REAL_VALUE_TYPE maxval = dconst1;
1464 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1465 real_convert (&maxval, mode, &maxval);
1466 max = build_real (expr_type, maxval);
1468 /* For unsigned, assume -1.0 is always representable. */
1469 if (uns_p)
1470 min = build_minus_one_cst (expr_type);
1471 else
1473 /* TYPE_MIN_VALUE is generally representable (or -inf),
1474 but TYPE_MIN_VALUE - 1.0 might not be. */
1475 REAL_VALUE_TYPE minval = dconstm1, minval2;
1476 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1477 real_convert (&minval, mode, &minval);
1478 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1479 real_convert (&minval2, mode, &minval2);
1480 if (real_compare (EQ_EXPR, &minval, &minval2)
1481 && !real_isinf (&minval))
1483 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1484 rounds to TYPE_MIN_VALUE, we need to subtract
1485 more. As REAL_MODE_FORMAT (mode)->p is the number
1486 of base digits, we want to subtract a number that
1487 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1488 times smaller than minval. */
1489 minval2 = dconst1;
1490 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1491 SET_REAL_EXP (&minval2,
1492 REAL_EXP (&minval2) + prec - 1
1493 - REAL_MODE_FORMAT (mode)->p + 1);
1494 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1495 real_convert (&minval2, mode, &minval2);
1497 min = build_real (expr_type, minval2);
1500 else if (REAL_MODE_FORMAT (mode)->b == 10)
1502 /* For _Decimal128 up to 34 decimal digits, - sign,
1503 dot, e, exponent. */
1504 char buf[64];
1505 mpfr_t m;
1506 int p = REAL_MODE_FORMAT (mode)->p;
1507 REAL_VALUE_TYPE maxval, minval;
1509 /* Use mpfr_snprintf rounding to compute the smallest
1510 representable decimal number greater or equal than
1511 1 << (prec - !uns_p). */
1512 mpfr_init2 (m, prec + 2);
1513 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1514 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1515 decimal_real_from_string (&maxval, buf);
1516 max = build_real (expr_type, maxval);
1518 /* For unsigned, assume -1.0 is always representable. */
1519 if (uns_p)
1520 min = build_minus_one_cst (expr_type);
1521 else
1523 /* Use mpfr_snprintf rounding to compute the largest
1524 representable decimal number less or equal than
1525 (-1 << (prec - 1)) - 1. */
1526 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1527 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1528 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1529 decimal_real_from_string (&minval, buf);
1530 min = build_real (expr_type, minval);
1532 mpfr_clear (m);
1534 else
1535 return NULL_TREE;
1537 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1538 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1539 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1540 if (integer_zerop (t))
1541 return NULL_TREE;
1543 if (flag_sanitize_undefined_trap_on_error)
1544 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1545 else
1547 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1548 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1549 NULL, ubsan_type_descriptor (expr_type),
1550 ubsan_type_descriptor (type), NULL_TREE,
1551 NULL_TREE);
1552 enum built_in_function bcode
1553 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1554 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1555 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1556 fn = builtin_decl_explicit (bcode);
1557 fn = build_call_expr_loc (loc, fn, 2,
1558 build_fold_addr_expr_loc (loc, data),
1559 ubsan_encode_value (arg, false));
1562 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1565 /* Instrument values passed to function arguments with nonnull attribute. */
1567 static void
1568 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1570 gimple stmt = gsi_stmt (*gsi);
1571 location_t loc[2];
1572 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1573 while for nonnull sanitization it is clear. */
1574 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1575 flag_delete_null_pointer_checks = 1;
1576 loc[0] = gimple_location (stmt);
1577 loc[1] = UNKNOWN_LOCATION;
1578 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1580 tree arg = gimple_call_arg (stmt, i);
1581 if (POINTER_TYPE_P (TREE_TYPE (arg))
1582 && infer_nonnull_range (stmt, arg, false, true))
1584 gimple g;
1585 if (!is_gimple_val (arg))
1587 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1588 gimple_set_location (g, loc[0]);
1589 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1590 arg = gimple_assign_lhs (g);
1593 basic_block then_bb, fallthru_bb;
1594 *gsi = create_cond_insert_point (gsi, true, false, true,
1595 &then_bb, &fallthru_bb);
1596 g = gimple_build_cond (EQ_EXPR, arg,
1597 build_zero_cst (TREE_TYPE (arg)),
1598 NULL_TREE, NULL_TREE);
1599 gimple_set_location (g, loc[0]);
1600 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1602 *gsi = gsi_after_labels (then_bb);
1603 if (flag_sanitize_undefined_trap_on_error)
1604 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1605 else
1607 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1608 2, loc, NULL_TREE,
1609 build_int_cst (integer_type_node,
1610 i + 1),
1611 NULL_TREE);
1612 data = build_fold_addr_expr_loc (loc[0], data);
1613 enum built_in_function bcode
1614 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1615 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1616 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1617 tree fn = builtin_decl_explicit (bcode);
1619 g = gimple_build_call (fn, 1, data);
1621 gimple_set_location (g, loc[0]);
1622 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1624 *gsi = gsi_for_stmt (stmt);
1626 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1629 /* Instrument returns in functions with returns_nonnull attribute. */
1631 static void
1632 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1634 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1635 location_t loc[2];
1636 tree arg = gimple_return_retval (stmt);
1637 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1638 while for nonnull return sanitization it is clear. */
1639 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1640 flag_delete_null_pointer_checks = 1;
1641 loc[0] = gimple_location (stmt);
1642 loc[1] = UNKNOWN_LOCATION;
1643 if (arg
1644 && POINTER_TYPE_P (TREE_TYPE (arg))
1645 && is_gimple_val (arg)
1646 && infer_nonnull_range (stmt, arg, false, true))
1648 basic_block then_bb, fallthru_bb;
1649 *gsi = create_cond_insert_point (gsi, true, false, true,
1650 &then_bb, &fallthru_bb);
1651 gimple g = gimple_build_cond (EQ_EXPR, arg,
1652 build_zero_cst (TREE_TYPE (arg)),
1653 NULL_TREE, NULL_TREE);
1654 gimple_set_location (g, loc[0]);
1655 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1657 *gsi = gsi_after_labels (then_bb);
1658 if (flag_sanitize_undefined_trap_on_error)
1659 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1660 else
1662 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1663 2, loc, NULL_TREE, NULL_TREE);
1664 data = build_fold_addr_expr_loc (loc[0], data);
1665 enum built_in_function bcode
1666 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1667 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1668 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1669 tree fn = builtin_decl_explicit (bcode);
1671 g = gimple_build_call (fn, 1, data);
1673 gimple_set_location (g, loc[0]);
1674 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1675 *gsi = gsi_for_stmt (stmt);
1677 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1680 /* Instrument memory references. Here we check whether the pointer
1681 points to an out-of-bounds location. */
1683 static void
1684 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1686 gimple stmt = gsi_stmt (*gsi);
1687 location_t loc = gimple_location (stmt);
1688 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1689 tree type;
1690 tree index = NULL_TREE;
1691 HOST_WIDE_INT size_in_bytes;
1693 type = TREE_TYPE (t);
1694 if (VOID_TYPE_P (type))
1695 return;
1697 switch (TREE_CODE (t))
1699 case COMPONENT_REF:
1700 if (TREE_CODE (t) == COMPONENT_REF
1701 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1703 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1704 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1705 repr, NULL_TREE);
1707 break;
1708 case ARRAY_REF:
1709 index = TREE_OPERAND (t, 1);
1710 break;
1711 case INDIRECT_REF:
1712 case MEM_REF:
1713 case VAR_DECL:
1714 case PARM_DECL:
1715 case RESULT_DECL:
1716 break;
1717 default:
1718 return;
1721 size_in_bytes = int_size_in_bytes (type);
1722 if (size_in_bytes <= 0)
1723 return;
1725 HOST_WIDE_INT bitsize, bitpos;
1726 tree offset;
1727 machine_mode mode;
1728 int volatilep = 0, unsignedp = 0;
1729 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1730 &unsignedp, &volatilep, false);
1732 if (bitpos % BITS_PER_UNIT != 0
1733 || bitsize != size_in_bytes * BITS_PER_UNIT)
1734 return;
1736 bool decl_p = DECL_P (inner);
1737 tree base;
1738 if (decl_p)
1739 base = inner;
1740 else if (TREE_CODE (inner) == MEM_REF)
1741 base = TREE_OPERAND (inner, 0);
1742 else
1743 return;
1744 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1746 while (TREE_CODE (base) == SSA_NAME)
1748 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1749 if (gimple_assign_ssa_name_copy_p (def_stmt)
1750 || (gimple_assign_cast_p (def_stmt)
1751 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1752 || (is_gimple_assign (def_stmt)
1753 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1755 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1756 if (TREE_CODE (rhs1) == SSA_NAME
1757 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1758 break;
1759 else
1760 base = rhs1;
1762 else
1763 break;
1766 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1767 return;
1769 tree sizet;
1770 tree base_addr = base;
1771 if (decl_p)
1772 base_addr = build1 (ADDR_EXPR,
1773 build_pointer_type (TREE_TYPE (base)), base);
1774 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1775 if (size != (unsigned HOST_WIDE_INT) -1)
1776 sizet = build_int_cst (sizetype, size);
1777 else if (optimize)
1779 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1780 loc = input_location;
1781 /* Generate __builtin_object_size call. */
1782 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1783 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1784 integer_zero_node);
1785 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1786 GSI_SAME_STMT);
1788 else
1789 return;
1791 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1792 call. */
1793 /* ptr + sizeof (*ptr) - base */
1794 t = fold_build2 (MINUS_EXPR, sizetype,
1795 fold_convert (pointer_sized_int_node, ptr),
1796 fold_convert (pointer_sized_int_node, base_addr));
1797 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1799 /* Perhaps we can omit the check. */
1800 if (TREE_CODE (t) == INTEGER_CST
1801 && TREE_CODE (sizet) == INTEGER_CST
1802 && tree_int_cst_le (t, sizet))
1803 return;
1805 if (index != NULL_TREE
1806 && TREE_CODE (index) == SSA_NAME
1807 && TREE_CODE (sizet) == INTEGER_CST)
1809 gimple def = SSA_NAME_DEF_STMT (index);
1810 if (is_gimple_assign (def)
1811 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1812 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1814 tree cst = gimple_assign_rhs2 (def);
1815 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1816 TYPE_SIZE_UNIT (type));
1817 if (tree_int_cst_sgn (cst) >= 0
1818 && tree_int_cst_lt (cst, sz))
1819 return;
1823 /* Nope. Emit the check. */
1824 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1825 GSI_SAME_STMT);
1826 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1827 GSI_SAME_STMT);
1828 tree ckind = build_int_cst (unsigned_char_type_node,
1829 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1830 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1831 ptr, t, sizet, ckind);
1832 gimple_set_location (g, loc);
1833 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1836 /* True if we want to play UBSan games in the current function. */
1838 bool
1839 do_ubsan_in_current_function ()
1841 return (current_function_decl != NULL_TREE
1842 && !lookup_attribute ("no_sanitize_undefined",
1843 DECL_ATTRIBUTES (current_function_decl)));
1846 namespace {
1848 const pass_data pass_data_ubsan =
1850 GIMPLE_PASS, /* type */
1851 "ubsan", /* name */
1852 OPTGROUP_NONE, /* optinfo_flags */
1853 TV_TREE_UBSAN, /* tv_id */
1854 ( PROP_cfg | PROP_ssa ), /* properties_required */
1855 0, /* properties_provided */
1856 0, /* properties_destroyed */
1857 0, /* todo_flags_start */
1858 TODO_update_ssa, /* todo_flags_finish */
1861 class pass_ubsan : public gimple_opt_pass
1863 public:
1864 pass_ubsan (gcc::context *ctxt)
1865 : gimple_opt_pass (pass_data_ubsan, ctxt)
1868 /* opt_pass methods: */
1869 virtual bool gate (function *)
1871 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1872 | SANITIZE_BOOL | SANITIZE_ENUM
1873 | SANITIZE_ALIGNMENT
1874 | SANITIZE_NONNULL_ATTRIBUTE
1875 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1876 | SANITIZE_OBJECT_SIZE)
1877 && do_ubsan_in_current_function ();
1880 virtual unsigned int execute (function *);
1882 }; // class pass_ubsan
1884 unsigned int
1885 pass_ubsan::execute (function *fun)
1887 basic_block bb;
1888 gimple_stmt_iterator gsi;
1890 initialize_sanitizer_builtins ();
1892 FOR_EACH_BB_FN (bb, fun)
1894 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1896 gimple stmt = gsi_stmt (gsi);
1897 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1899 gsi_next (&gsi);
1900 continue;
1903 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1904 && is_gimple_assign (stmt))
1905 instrument_si_overflow (gsi);
1907 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1909 if (gimple_store_p (stmt))
1910 instrument_null (gsi, true);
1911 if (gimple_assign_load_p (stmt))
1912 instrument_null (gsi, false);
1915 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1916 && gimple_assign_load_p (stmt))
1918 instrument_bool_enum_load (&gsi);
1919 bb = gimple_bb (stmt);
1922 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1923 && is_gimple_call (stmt)
1924 && !gimple_call_internal_p (stmt))
1926 instrument_nonnull_arg (&gsi);
1927 bb = gimple_bb (stmt);
1930 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1931 && gimple_code (stmt) == GIMPLE_RETURN)
1933 instrument_nonnull_return (&gsi);
1934 bb = gimple_bb (stmt);
1937 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
1939 if (gimple_store_p (stmt))
1940 instrument_object_size (&gsi, true);
1941 if (gimple_assign_load_p (stmt))
1942 instrument_object_size (&gsi, false);
1945 gsi_next (&gsi);
1948 return 0;
1951 } // anon namespace
1953 gimple_opt_pass *
1954 make_pass_ubsan (gcc::context *ctxt)
1956 return new pass_ubsan (ctxt);
1959 #include "gt-ubsan.h"