PR sanitizer/64121
[official-gcc.git] / gcc / ubsan.c
blobfb5f104d7019a7f1d930036888aa294d037e4936
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2014 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 "tree.h"
25 #include "stor-layout.h"
26 #include "stringpool.h"
27 #include "predict.h"
28 #include "dominance.h"
29 #include "cfg.h"
30 #include "cfganal.h"
31 #include "basic-block.h"
32 #include "hash-map.h"
33 #include "is-a.h"
34 #include "plugin-api.h"
35 #include "vec.h"
36 #include "hashtab.h"
37 #include "hash-set.h"
38 #include "machmode.h"
39 #include "tm.h"
40 #include "hard-reg-set.h"
41 #include "input.h"
42 #include "function.h"
43 #include "ipa-ref.h"
44 #include "cgraph.h"
45 #include "tree-pass.h"
46 #include "tree-ssa-alias.h"
47 #include "tree-pretty-print.h"
48 #include "internal-fn.h"
49 #include "gimple-expr.h"
50 #include "gimple.h"
51 #include "gimple-iterator.h"
52 #include "gimple-ssa.h"
53 #include "gimple-walk.h"
54 #include "output.h"
55 #include "tm_p.h"
56 #include "toplev.h"
57 #include "cfgloop.h"
58 #include "ubsan.h"
59 #include "c-family/c-common.h"
60 #include "rtl.h"
61 #include "expr.h"
62 #include "tree-ssanames.h"
63 #include "asan.h"
64 #include "gimplify-me.h"
65 #include "intl.h"
66 #include "realmpfr.h"
67 #include "dfp.h"
68 #include "builtins.h"
69 #include "tree-object-size.h"
70 #include "tree-eh.h"
72 /* Map from a tree to a VAR_DECL tree. */
74 struct GTY((for_user)) tree_type_map {
75 struct tree_map_base type;
76 tree decl;
79 struct tree_type_map_cache_hasher : ggc_cache_hasher<tree_type_map *>
81 static inline hashval_t
82 hash (tree_type_map *t)
84 return TYPE_UID (t->type.from);
87 static inline bool
88 equal (tree_type_map *a, tree_type_map *b)
90 return a->type.from == b->type.from;
93 static void
94 handle_cache_entry (tree_type_map *&m)
96 extern void gt_ggc_mx (tree_type_map *&);
97 if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
98 return;
99 else if (ggc_marked_p (m->type.from))
100 gt_ggc_mx (m);
101 else
102 m = static_cast<tree_type_map *> (HTAB_DELETED_ENTRY);
106 static GTY ((cache))
107 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
109 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
111 static tree
112 decl_for_type_lookup (tree type)
114 /* If the hash table is not initialized yet, create it now. */
115 if (decl_tree_for_type == NULL)
117 decl_tree_for_type
118 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
119 /* That also means we don't have to bother with the lookup. */
120 return NULL_TREE;
123 struct tree_type_map *h, in;
124 in.type.from = type;
126 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
127 return h ? h->decl : NULL_TREE;
130 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
132 static void
133 decl_for_type_insert (tree type, tree decl)
135 struct tree_type_map *h;
137 h = ggc_alloc<tree_type_map> ();
138 h->type.from = type;
139 h->decl = decl;
140 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
143 /* Helper routine, which encodes a value in the pointer_sized_int_node.
144 Arguments with precision <= POINTER_SIZE are passed directly,
145 the rest is passed by reference. T is a value we are to encode.
146 IN_EXPAND_P is true if this function is called during expansion. */
148 tree
149 ubsan_encode_value (tree t, bool in_expand_p)
151 tree type = TREE_TYPE (t);
152 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
153 if (bitsize <= POINTER_SIZE)
154 switch (TREE_CODE (type))
156 case BOOLEAN_TYPE:
157 case ENUMERAL_TYPE:
158 case INTEGER_TYPE:
159 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
160 case REAL_TYPE:
162 tree itype = build_nonstandard_integer_type (bitsize, true);
163 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
164 return fold_convert (pointer_sized_int_node, t);
166 default:
167 gcc_unreachable ();
169 else
171 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
173 /* The reason for this is that we don't want to pessimize
174 code by making vars unnecessarily addressable. */
175 tree var = create_tmp_var (type);
176 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
177 if (in_expand_p)
179 rtx mem
180 = assign_stack_temp_for_type (TYPE_MODE (type),
181 GET_MODE_SIZE (TYPE_MODE (type)),
182 type);
183 SET_DECL_RTL (var, mem);
184 expand_assignment (var, t, false);
185 return build_fold_addr_expr (var);
187 t = build_fold_addr_expr (var);
188 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
190 else
191 return build_fold_addr_expr (t);
195 /* Cached ubsan_get_type_descriptor_type () return value. */
196 static GTY(()) tree ubsan_type_descriptor_type;
198 /* Build
199 struct __ubsan_type_descriptor
201 unsigned short __typekind;
202 unsigned short __typeinfo;
203 char __typename[];
205 type. */
207 static tree
208 ubsan_get_type_descriptor_type (void)
210 static const char *field_names[3]
211 = { "__typekind", "__typeinfo", "__typename" };
212 tree fields[3], ret;
214 if (ubsan_type_descriptor_type)
215 return ubsan_type_descriptor_type;
217 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
218 tree flex_arr_type = build_array_type (char_type_node, itype);
220 ret = make_node (RECORD_TYPE);
221 for (int i = 0; i < 3; i++)
223 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
224 get_identifier (field_names[i]),
225 (i == 2) ? flex_arr_type
226 : short_unsigned_type_node);
227 DECL_CONTEXT (fields[i]) = ret;
228 if (i)
229 DECL_CHAIN (fields[i - 1]) = fields[i];
231 tree type_decl = build_decl (input_location, TYPE_DECL,
232 get_identifier ("__ubsan_type_descriptor"),
233 ret);
234 DECL_IGNORED_P (type_decl) = 1;
235 DECL_ARTIFICIAL (type_decl) = 1;
236 TYPE_FIELDS (ret) = fields[0];
237 TYPE_NAME (ret) = type_decl;
238 TYPE_STUB_DECL (ret) = type_decl;
239 layout_type (ret);
240 ubsan_type_descriptor_type = ret;
241 return ret;
244 /* Cached ubsan_get_source_location_type () return value. */
245 static GTY(()) tree ubsan_source_location_type;
247 /* Build
248 struct __ubsan_source_location
250 const char *__filename;
251 unsigned int __line;
252 unsigned int __column;
254 type. */
256 tree
257 ubsan_get_source_location_type (void)
259 static const char *field_names[3]
260 = { "__filename", "__line", "__column" };
261 tree fields[3], ret;
262 if (ubsan_source_location_type)
263 return ubsan_source_location_type;
265 tree const_char_type = build_qualified_type (char_type_node,
266 TYPE_QUAL_CONST);
268 ret = make_node (RECORD_TYPE);
269 for (int i = 0; i < 3; i++)
271 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
272 get_identifier (field_names[i]),
273 (i == 0) ? build_pointer_type (const_char_type)
274 : unsigned_type_node);
275 DECL_CONTEXT (fields[i]) = ret;
276 if (i)
277 DECL_CHAIN (fields[i - 1]) = fields[i];
279 tree type_decl = build_decl (input_location, TYPE_DECL,
280 get_identifier ("__ubsan_source_location"),
281 ret);
282 DECL_IGNORED_P (type_decl) = 1;
283 DECL_ARTIFICIAL (type_decl) = 1;
284 TYPE_FIELDS (ret) = fields[0];
285 TYPE_NAME (ret) = type_decl;
286 TYPE_STUB_DECL (ret) = type_decl;
287 layout_type (ret);
288 ubsan_source_location_type = ret;
289 return ret;
292 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
293 type with its fields filled from a location_t LOC. */
295 static tree
296 ubsan_source_location (location_t loc)
298 expanded_location xloc;
299 tree type = ubsan_get_source_location_type ();
301 xloc = expand_location (loc);
302 tree str;
303 if (xloc.file == NULL)
305 str = build_int_cst (ptr_type_node, 0);
306 xloc.line = 0;
307 xloc.column = 0;
309 else
311 /* Fill in the values from LOC. */
312 size_t len = strlen (xloc.file);
313 str = build_string (len + 1, xloc.file);
314 TREE_TYPE (str) = build_array_type (char_type_node,
315 build_index_type (size_int (len)));
316 TREE_READONLY (str) = 1;
317 TREE_STATIC (str) = 1;
318 str = build_fold_addr_expr (str);
320 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
321 build_int_cst (unsigned_type_node,
322 xloc.line), NULL_TREE,
323 build_int_cst (unsigned_type_node,
324 xloc.column));
325 TREE_CONSTANT (ctor) = 1;
326 TREE_STATIC (ctor) = 1;
328 return ctor;
331 /* This routine returns a magic number for TYPE. */
333 static unsigned short
334 get_ubsan_type_info_for_type (tree type)
336 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
337 if (TREE_CODE (type) == REAL_TYPE)
338 return tree_to_uhwi (TYPE_SIZE (type));
339 else if (INTEGRAL_TYPE_P (type))
341 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
342 gcc_assert (prec != -1);
343 return (prec << 1) | !TYPE_UNSIGNED (type);
345 else
346 return 0;
349 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
350 descriptor. It first looks into the hash table; if not found,
351 create the VAR_DECL, put it into the hash table and return the
352 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
353 an enum controlling how we want to print the type. */
355 tree
356 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
358 /* See through any typedefs. */
359 type = TYPE_MAIN_VARIANT (type);
361 tree decl = decl_for_type_lookup (type);
362 /* It is possible that some of the earlier created DECLs were found
363 unused, in that case they weren't emitted and varpool_node::get
364 returns NULL node on them. But now we really need them. Thus,
365 renew them here. */
366 if (decl != NULL_TREE && varpool_node::get (decl))
367 return build_fold_addr_expr (decl);
369 tree dtype = ubsan_get_type_descriptor_type ();
370 tree type2 = type;
371 const char *tname = NULL;
372 char *pretty_name;
373 unsigned char deref_depth = 0;
374 unsigned short tkind, tinfo;
376 /* Get the name of the type, or the name of the pointer type. */
377 if (pstyle == UBSAN_PRINT_POINTER)
379 gcc_assert (POINTER_TYPE_P (type));
380 type2 = TREE_TYPE (type);
382 /* Remove any '*' operators from TYPE. */
383 while (POINTER_TYPE_P (type2))
384 deref_depth++, type2 = TREE_TYPE (type2);
386 if (TREE_CODE (type2) == METHOD_TYPE)
387 type2 = TYPE_METHOD_BASETYPE (type2);
390 /* If an array, get its type. */
391 type2 = strip_array_types (type2);
393 if (pstyle == UBSAN_PRINT_ARRAY)
395 while (POINTER_TYPE_P (type2))
396 deref_depth++, type2 = TREE_TYPE (type2);
399 if (TYPE_NAME (type2) != NULL)
401 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
402 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
403 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
404 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
407 if (tname == NULL)
408 /* We weren't able to determine the type name. */
409 tname = "<unknown>";
411 /* Decorate the type name with '', '*', "struct", or "union". */
412 pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
413 if (pstyle == UBSAN_PRINT_POINTER)
415 int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
416 TYPE_VOLATILE (type2) ? "volatile " : "",
417 TYPE_READONLY (type2) ? "const " : "",
418 TYPE_RESTRICT (type2) ? "restrict " : "",
419 TYPE_ATOMIC (type2) ? "_Atomic " : "",
420 TREE_CODE (type2) == RECORD_TYPE
421 ? "struct "
422 : TREE_CODE (type2) == UNION_TYPE
423 ? "union " : "", tname,
424 deref_depth == 0 ? "" : " ");
425 while (deref_depth-- > 0)
426 pretty_name[pos++] = '*';
427 pretty_name[pos++] = '\'';
428 pretty_name[pos] = '\0';
430 else if (pstyle == UBSAN_PRINT_ARRAY)
432 /* Pretty print the array dimensions. */
433 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
434 tree t = type;
435 int pos = sprintf (pretty_name, "'%s ", tname);
436 while (deref_depth-- > 0)
437 pretty_name[pos++] = '*';
438 while (TREE_CODE (t) == ARRAY_TYPE)
440 pretty_name[pos++] = '[';
441 tree dom = TYPE_DOMAIN (t);
442 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
443 pos += sprintf (&pretty_name[pos], HOST_WIDE_INT_PRINT_DEC,
444 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
445 else
446 /* ??? We can't determine the variable name; print VLA unspec. */
447 pretty_name[pos++] = '*';
448 pretty_name[pos++] = ']';
449 t = TREE_TYPE (t);
451 pretty_name[pos++] = '\'';
452 pretty_name[pos] = '\0';
454 /* Save the tree with stripped types. */
455 type = t;
457 else
458 sprintf (pretty_name, "'%s'", tname);
460 switch (TREE_CODE (type))
462 case BOOLEAN_TYPE:
463 case ENUMERAL_TYPE:
464 case INTEGER_TYPE:
465 tkind = 0x0000;
466 break;
467 case REAL_TYPE:
468 /* FIXME: libubsan right now only supports float, double and
469 long double type formats. */
470 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
471 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
472 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
473 tkind = 0x0001;
474 else
475 tkind = 0xffff;
476 break;
477 default:
478 tkind = 0xffff;
479 break;
481 tinfo = get_ubsan_type_info_for_type (type);
483 /* Create a new VAR_DECL of type descriptor. */
484 char tmp_name[32];
485 static unsigned int type_var_id_num;
486 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
487 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
488 dtype);
489 TREE_STATIC (decl) = 1;
490 TREE_PUBLIC (decl) = 0;
491 DECL_ARTIFICIAL (decl) = 1;
492 DECL_IGNORED_P (decl) = 1;
493 DECL_EXTERNAL (decl) = 0;
495 size_t len = strlen (pretty_name);
496 tree str = build_string (len + 1, pretty_name);
497 TREE_TYPE (str) = build_array_type (char_type_node,
498 build_index_type (size_int (len)));
499 TREE_READONLY (str) = 1;
500 TREE_STATIC (str) = 1;
501 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
502 build_int_cst (short_unsigned_type_node,
503 tkind), NULL_TREE,
504 build_int_cst (short_unsigned_type_node,
505 tinfo), NULL_TREE, str);
506 TREE_CONSTANT (ctor) = 1;
507 TREE_STATIC (ctor) = 1;
508 DECL_INITIAL (decl) = ctor;
509 varpool_node::finalize_decl (decl);
511 /* Save the VAR_DECL into the hash table. */
512 decl_for_type_insert (type, decl);
514 return build_fold_addr_expr (decl);
517 /* Create a structure for the ubsan library. NAME is a name of the new
518 structure. LOCCNT is number of locations, PLOC points to array of
519 locations. The arguments in ... are of __ubsan_type_descriptor type
520 and there are at most two of them, followed by NULL_TREE, followed
521 by optional extra arguments and another NULL_TREE. */
523 tree
524 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
526 va_list args;
527 tree ret, t;
528 tree fields[6];
529 vec<tree, va_gc> *saved_args = NULL;
530 size_t i = 0;
531 int j;
533 /* Firstly, create a pointer to type descriptor type. */
534 tree td_type = ubsan_get_type_descriptor_type ();
535 td_type = build_pointer_type (td_type);
537 /* Create the structure type. */
538 ret = make_node (RECORD_TYPE);
539 for (j = 0; j < loccnt; j++)
541 gcc_checking_assert (i < 2);
542 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
543 ubsan_get_source_location_type ());
544 DECL_CONTEXT (fields[i]) = ret;
545 if (i)
546 DECL_CHAIN (fields[i - 1]) = fields[i];
547 i++;
550 va_start (args, ploc);
551 for (t = va_arg (args, tree); t != NULL_TREE;
552 i++, t = va_arg (args, tree))
554 gcc_checking_assert (i < 4);
555 /* Save the tree arguments for later use. */
556 vec_safe_push (saved_args, t);
557 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
558 td_type);
559 DECL_CONTEXT (fields[i]) = ret;
560 if (i)
561 DECL_CHAIN (fields[i - 1]) = fields[i];
564 for (t = va_arg (args, tree); t != NULL_TREE;
565 i++, t = va_arg (args, tree))
567 gcc_checking_assert (i < 6);
568 /* Save the tree arguments for later use. */
569 vec_safe_push (saved_args, t);
570 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
571 TREE_TYPE (t));
572 DECL_CONTEXT (fields[i]) = ret;
573 if (i)
574 DECL_CHAIN (fields[i - 1]) = fields[i];
576 va_end (args);
578 tree type_decl = build_decl (input_location, TYPE_DECL,
579 get_identifier (name), ret);
580 DECL_IGNORED_P (type_decl) = 1;
581 DECL_ARTIFICIAL (type_decl) = 1;
582 TYPE_FIELDS (ret) = fields[0];
583 TYPE_NAME (ret) = type_decl;
584 TYPE_STUB_DECL (ret) = type_decl;
585 layout_type (ret);
587 /* Now, fill in the type. */
588 char tmp_name[32];
589 static unsigned int ubsan_var_id_num;
590 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
591 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
592 ret);
593 TREE_STATIC (var) = 1;
594 TREE_PUBLIC (var) = 0;
595 DECL_ARTIFICIAL (var) = 1;
596 DECL_IGNORED_P (var) = 1;
597 DECL_EXTERNAL (var) = 0;
599 vec<constructor_elt, va_gc> *v;
600 vec_alloc (v, i);
601 tree ctor = build_constructor (ret, v);
603 /* If desirable, set the __ubsan_source_location element. */
604 for (j = 0; j < loccnt; j++)
606 location_t loc = LOCATION_LOCUS (ploc[j]);
607 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
610 size_t nelts = vec_safe_length (saved_args);
611 for (i = 0; i < nelts; i++)
613 t = (*saved_args)[i];
614 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
617 TREE_CONSTANT (ctor) = 1;
618 TREE_STATIC (ctor) = 1;
619 DECL_INITIAL (var) = ctor;
620 varpool_node::finalize_decl (var);
622 return var;
625 /* Instrument the __builtin_unreachable call. We just call the libubsan
626 routine instead. */
628 bool
629 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
631 gimple g;
632 location_t loc = gimple_location (gsi_stmt (*gsi));
634 if (flag_sanitize_undefined_trap_on_error)
635 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
636 else
638 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
639 NULL_TREE, NULL_TREE);
640 data = build_fold_addr_expr_loc (loc, data);
641 tree fn
642 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
643 g = gimple_build_call (fn, 1, data);
645 gimple_set_location (g, loc);
646 gsi_replace (gsi, g, false);
647 return false;
650 /* Return true if T is a call to a libubsan routine. */
652 bool
653 is_ubsan_builtin_p (tree t)
655 return TREE_CODE (t) == FUNCTION_DECL
656 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
657 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
658 "__builtin___ubsan_", 18) == 0;
661 /* Expand the UBSAN_BOUNDS special builtin function. */
663 bool
664 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
666 gimple stmt = gsi_stmt (*gsi);
667 location_t loc = gimple_location (stmt);
668 gcc_assert (gimple_call_num_args (stmt) == 3);
670 /* Pick up the arguments of the UBSAN_BOUNDS call. */
671 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
672 tree index = gimple_call_arg (stmt, 1);
673 tree orig_index_type = TREE_TYPE (index);
674 tree bound = gimple_call_arg (stmt, 2);
676 gimple_stmt_iterator gsi_orig = *gsi;
678 /* Create condition "if (index > bound)". */
679 basic_block then_bb, fallthru_bb;
680 gimple_stmt_iterator cond_insert_point
681 = create_cond_insert_point (gsi, false, false, true,
682 &then_bb, &fallthru_bb);
683 index = fold_convert (TREE_TYPE (bound), index);
684 index = force_gimple_operand_gsi (&cond_insert_point, index,
685 true, NULL_TREE,
686 false, GSI_NEW_STMT);
687 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
688 gimple_set_location (g, loc);
689 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
691 /* Generate __ubsan_handle_out_of_bounds call. */
692 *gsi = gsi_after_labels (then_bb);
693 if (flag_sanitize_undefined_trap_on_error)
694 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
695 else
697 tree data
698 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
699 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
700 ubsan_type_descriptor (orig_index_type),
701 NULL_TREE, NULL_TREE);
702 data = build_fold_addr_expr_loc (loc, data);
703 enum built_in_function bcode
704 = (flag_sanitize_recover & SANITIZE_BOUNDS)
705 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
706 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
707 tree fn = builtin_decl_explicit (bcode);
708 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
709 true, NULL_TREE, true,
710 GSI_SAME_STMT);
711 g = gimple_build_call (fn, 2, data, val);
713 gimple_set_location (g, loc);
714 gsi_insert_before (gsi, g, GSI_SAME_STMT);
716 /* Get rid of the UBSAN_BOUNDS call from the IR. */
717 unlink_stmt_vdef (stmt);
718 gsi_remove (&gsi_orig, true);
720 /* Point GSI to next logical statement. */
721 *gsi = gsi_start_bb (fallthru_bb);
722 return true;
725 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
726 argument which is a constant, because the middle-end treats pointer
727 conversions as useless and therefore the type of the first argument
728 could be changed to any other pointer type. */
730 bool
731 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
733 gimple_stmt_iterator gsi = *gsip;
734 gimple stmt = gsi_stmt (gsi);
735 location_t loc = gimple_location (stmt);
736 gcc_assert (gimple_call_num_args (stmt) == 3);
737 tree ptr = gimple_call_arg (stmt, 0);
738 tree ckind = gimple_call_arg (stmt, 1);
739 tree align = gimple_call_arg (stmt, 2);
740 tree check_align = NULL_TREE;
741 bool check_null;
743 basic_block cur_bb = gsi_bb (gsi);
745 gimple g;
746 if (!integer_zerop (align))
748 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
749 if (compare_tree_int (align, ptralign) == 1)
751 check_align = make_ssa_name (pointer_sized_int_node);
752 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
753 gimple_set_location (g, loc);
754 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
757 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
759 if (check_align == NULL_TREE && !check_null)
761 gsi_remove (gsip, true);
762 /* Unlink the UBSAN_NULLs vops before replacing it. */
763 unlink_stmt_vdef (stmt);
764 return true;
767 /* Split the original block holding the pointer dereference. */
768 edge e = split_block (cur_bb, stmt);
770 /* Get a hold on the 'condition block', the 'then block' and the
771 'else block'. */
772 basic_block cond_bb = e->src;
773 basic_block fallthru_bb = e->dest;
774 basic_block then_bb = create_empty_bb (cond_bb);
775 add_bb_to_loop (then_bb, cond_bb->loop_father);
776 loops_state_set (LOOPS_NEED_FIXUP);
778 /* Make an edge coming from the 'cond block' into the 'then block';
779 this edge is unlikely taken, so set up the probability accordingly. */
780 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
781 e->probability = PROB_VERY_UNLIKELY;
783 /* Connect 'then block' with the 'else block'. This is needed
784 as the ubsan routines we call in the 'then block' are not noreturn.
785 The 'then block' only has one outcoming edge. */
786 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
788 /* Set up the fallthrough basic block. */
789 e = find_edge (cond_bb, fallthru_bb);
790 e->flags = EDGE_FALSE_VALUE;
791 e->count = cond_bb->count;
792 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
794 /* Update dominance info for the newly created then_bb; note that
795 fallthru_bb's dominance info has already been updated by
796 split_block. */
797 if (dom_info_available_p (CDI_DOMINATORS))
798 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
800 /* Put the ubsan builtin call into the newly created BB. */
801 if (flag_sanitize_undefined_trap_on_error)
802 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
803 else
805 enum built_in_function bcode
806 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
807 | (check_null ? SANITIZE_NULL : 0)))
808 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
809 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
810 tree fn = builtin_decl_implicit (bcode);
811 tree data
812 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
813 ubsan_type_descriptor (TREE_TYPE (ckind),
814 UBSAN_PRINT_POINTER),
815 NULL_TREE,
816 align,
817 fold_convert (unsigned_char_type_node, ckind),
818 NULL_TREE);
819 data = build_fold_addr_expr_loc (loc, data);
820 g = gimple_build_call (fn, 2, data,
821 check_align ? check_align
822 : build_zero_cst (pointer_sized_int_node));
824 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
825 gimple_set_location (g, loc);
826 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
828 /* Unlink the UBSAN_NULLs vops before replacing it. */
829 unlink_stmt_vdef (stmt);
831 if (check_null)
833 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
834 NULL_TREE, NULL_TREE);
835 gimple_set_location (g, loc);
837 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
838 gsi_replace (&gsi, g, false);
841 if (check_align)
843 if (check_null)
845 /* Split the block with the condition again. */
846 e = split_block (cond_bb, stmt);
847 basic_block cond1_bb = e->src;
848 basic_block cond2_bb = e->dest;
850 /* Make an edge coming from the 'cond1 block' into the 'then block';
851 this edge is unlikely taken, so set up the probability
852 accordingly. */
853 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
854 e->probability = PROB_VERY_UNLIKELY;
856 /* Set up the fallthrough basic block. */
857 e = find_edge (cond1_bb, cond2_bb);
858 e->flags = EDGE_FALSE_VALUE;
859 e->count = cond1_bb->count;
860 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
862 /* Update dominance info. */
863 if (dom_info_available_p (CDI_DOMINATORS))
865 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
866 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
869 gsi2 = gsi_start_bb (cond2_bb);
872 tree mask = build_int_cst (pointer_sized_int_node,
873 tree_to_uhwi (align) - 1);
874 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
875 BIT_AND_EXPR, check_align, mask);
876 gimple_set_location (g, loc);
877 if (check_null)
878 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
879 else
880 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
882 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
883 build_int_cst (pointer_sized_int_node, 0),
884 NULL_TREE, NULL_TREE);
885 gimple_set_location (g, loc);
886 if (check_null)
887 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
888 else
889 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
890 gsi_replace (&gsi, g, false);
892 return false;
895 /* Expand UBSAN_OBJECT_SIZE internal call. */
897 bool
898 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
900 gimple stmt = gsi_stmt (*gsi);
901 location_t loc = gimple_location (stmt);
902 gcc_assert (gimple_call_num_args (stmt) == 4);
904 tree ptr = gimple_call_arg (stmt, 0);
905 tree offset = gimple_call_arg (stmt, 1);
906 tree size = gimple_call_arg (stmt, 2);
907 tree ckind = gimple_call_arg (stmt, 3);
908 gimple_stmt_iterator gsi_orig = *gsi;
909 gimple g;
911 /* See if we can discard the check. */
912 if (TREE_CODE (size) != INTEGER_CST
913 || integer_all_onesp (size))
914 /* Yes, __builtin_object_size couldn't determine the
915 object size. */;
916 else
918 /* if (offset > objsize) */
919 basic_block then_bb, fallthru_bb;
920 gimple_stmt_iterator cond_insert_point
921 = create_cond_insert_point (gsi, false, false, true,
922 &then_bb, &fallthru_bb);
923 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
924 gimple_set_location (g, loc);
925 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
927 /* Generate __ubsan_handle_type_mismatch call. */
928 *gsi = gsi_after_labels (then_bb);
929 if (flag_sanitize_undefined_trap_on_error)
930 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
931 else
933 tree data
934 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
935 ubsan_type_descriptor (TREE_TYPE (ptr),
936 UBSAN_PRINT_POINTER),
937 NULL_TREE,
938 build_zero_cst (pointer_sized_int_node),
939 ckind,
940 NULL_TREE);
941 data = build_fold_addr_expr_loc (loc, data);
942 enum built_in_function bcode
943 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
944 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
945 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
946 tree p = make_ssa_name (pointer_sized_int_node);
947 g = gimple_build_assign (p, NOP_EXPR, ptr);
948 gimple_set_location (g, loc);
949 gsi_insert_before (gsi, g, GSI_SAME_STMT);
950 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
952 gimple_set_location (g, loc);
953 gsi_insert_before (gsi, g, GSI_SAME_STMT);
955 /* Point GSI to next logical statement. */
956 *gsi = gsi_start_bb (fallthru_bb);
959 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
960 unlink_stmt_vdef (stmt);
961 gsi_remove (&gsi_orig, true);
962 return gsi_end_p (*gsi);
965 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
966 whether the pointer is on the left hand side of the assignment. */
968 static void
969 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
970 bool is_lhs)
972 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
973 unsigned int align = 0;
974 if (flag_sanitize & SANITIZE_ALIGNMENT)
976 align = min_align_of_type (TREE_TYPE (base));
977 if (align <= 1)
978 align = 0;
980 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
981 return;
982 tree t = TREE_OPERAND (base, 0);
983 if (!POINTER_TYPE_P (TREE_TYPE (t)))
984 return;
985 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && mem != base)
986 ikind = UBSAN_MEMBER_ACCESS;
987 tree kind = build_int_cst (TREE_TYPE (t), ikind);
988 tree alignt = build_int_cst (pointer_sized_int_node, align);
989 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
990 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
991 gsi_insert_before (iter, g, GSI_SAME_STMT);
994 /* Perform the pointer instrumentation. */
996 static void
997 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
999 gimple stmt = gsi_stmt (gsi);
1000 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1001 tree base = get_base_address (t);
1002 const enum tree_code code = TREE_CODE (base);
1003 if (code == MEM_REF
1004 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1005 instrument_mem_ref (t, base, &gsi, is_lhs);
1008 /* Build an ubsan builtin call for the signed-integer-overflow
1009 sanitization. CODE says what kind of builtin are we building,
1010 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1011 are operands of the binary operation. */
1013 tree
1014 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1015 tree op0, tree op1)
1017 if (flag_sanitize_undefined_trap_on_error)
1018 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1020 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1021 ubsan_type_descriptor (lhstype), NULL_TREE,
1022 NULL_TREE);
1023 enum built_in_function fn_code;
1025 switch (code)
1027 case PLUS_EXPR:
1028 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1029 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1030 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1031 break;
1032 case MINUS_EXPR:
1033 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1034 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1035 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1036 break;
1037 case MULT_EXPR:
1038 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1039 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1040 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1041 break;
1042 case NEGATE_EXPR:
1043 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1044 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1045 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1046 break;
1047 default:
1048 gcc_unreachable ();
1050 tree fn = builtin_decl_explicit (fn_code);
1051 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1052 build_fold_addr_expr_loc (loc, data),
1053 ubsan_encode_value (op0, true),
1054 op1 ? ubsan_encode_value (op1, true)
1055 : NULL_TREE);
1058 /* Perform the signed integer instrumentation. GSI is the iterator
1059 pointing at statement we are trying to instrument. */
1061 static void
1062 instrument_si_overflow (gimple_stmt_iterator gsi)
1064 gimple stmt = gsi_stmt (gsi);
1065 tree_code code = gimple_assign_rhs_code (stmt);
1066 tree lhs = gimple_assign_lhs (stmt);
1067 tree lhstype = TREE_TYPE (lhs);
1068 tree a, b;
1069 gimple g;
1071 /* If this is not a signed operation, don't instrument anything here.
1072 Also punt on bit-fields. */
1073 if (!INTEGRAL_TYPE_P (lhstype)
1074 || TYPE_OVERFLOW_WRAPS (lhstype)
1075 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1076 return;
1078 switch (code)
1080 case MINUS_EXPR:
1081 case PLUS_EXPR:
1082 case MULT_EXPR:
1083 /* Transform
1084 i = u {+,-,*} 5;
1085 into
1086 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1087 a = gimple_assign_rhs1 (stmt);
1088 b = gimple_assign_rhs2 (stmt);
1089 g = gimple_build_call_internal (code == PLUS_EXPR
1090 ? IFN_UBSAN_CHECK_ADD
1091 : code == MINUS_EXPR
1092 ? IFN_UBSAN_CHECK_SUB
1093 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1094 gimple_call_set_lhs (g, lhs);
1095 gsi_replace (&gsi, g, false);
1096 break;
1097 case NEGATE_EXPR:
1098 /* Represent i = -u;
1100 i = UBSAN_CHECK_SUB (0, u); */
1101 a = build_int_cst (lhstype, 0);
1102 b = gimple_assign_rhs1 (stmt);
1103 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1104 gimple_call_set_lhs (g, lhs);
1105 gsi_replace (&gsi, g, false);
1106 break;
1107 case ABS_EXPR:
1108 /* Transform i = ABS_EXPR<u>;
1109 into
1110 _N = UBSAN_CHECK_SUB (0, u);
1111 i = ABS_EXPR<_N>; */
1112 a = build_int_cst (lhstype, 0);
1113 b = gimple_assign_rhs1 (stmt);
1114 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1115 a = make_ssa_name (lhstype);
1116 gimple_call_set_lhs (g, a);
1117 gimple_set_location (g, gimple_location (stmt));
1118 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1119 gimple_assign_set_rhs1 (stmt, a);
1120 update_stmt (stmt);
1121 break;
1122 default:
1123 break;
1127 /* Instrument loads from (non-bitfield) bool and C++ enum values
1128 to check if the memory value is outside of the range of the valid
1129 type values. */
1131 static void
1132 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1134 gimple stmt = gsi_stmt (*gsi);
1135 tree rhs = gimple_assign_rhs1 (stmt);
1136 tree type = TREE_TYPE (rhs);
1137 tree minv = NULL_TREE, maxv = NULL_TREE;
1139 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1141 minv = boolean_false_node;
1142 maxv = boolean_true_node;
1144 else if (TREE_CODE (type) == ENUMERAL_TYPE
1145 && (flag_sanitize & SANITIZE_ENUM)
1146 && TREE_TYPE (type) != NULL_TREE
1147 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1148 && (TYPE_PRECISION (TREE_TYPE (type))
1149 < GET_MODE_PRECISION (TYPE_MODE (type))))
1151 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1152 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1154 else
1155 return;
1157 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1158 HOST_WIDE_INT bitsize, bitpos;
1159 tree offset;
1160 machine_mode mode;
1161 int volatilep = 0, unsignedp = 0;
1162 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1163 &unsignedp, &volatilep, false);
1164 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1166 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1167 || (bitpos % modebitsize) != 0
1168 || bitsize != modebitsize
1169 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1170 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1171 return;
1173 bool can_throw = stmt_could_throw_p (stmt);
1174 location_t loc = gimple_location (stmt);
1175 tree lhs = gimple_assign_lhs (stmt);
1176 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1177 tree atype = reference_alias_ptr_type (rhs);
1178 gimple g = gimple_build_assign (make_ssa_name (ptype),
1179 build_fold_addr_expr (rhs));
1180 gimple_set_location (g, loc);
1181 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1182 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1183 build_int_cst (atype, 0));
1184 tree urhs = make_ssa_name (utype);
1185 if (can_throw)
1187 gimple_assign_set_lhs (stmt, urhs);
1188 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1189 gimple_set_location (g, loc);
1190 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1191 gsi_insert_on_edge_immediate (e, g);
1192 gimple_assign_set_rhs_from_tree (gsi, mem);
1193 update_stmt (stmt);
1194 *gsi = gsi_for_stmt (g);
1195 g = stmt;
1197 else
1199 g = gimple_build_assign (urhs, mem);
1200 gimple_set_location (g, loc);
1201 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1203 minv = fold_convert (utype, minv);
1204 maxv = fold_convert (utype, maxv);
1205 if (!integer_zerop (minv))
1207 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1208 gimple_set_location (g, loc);
1209 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1212 gimple_stmt_iterator gsi2 = *gsi;
1213 basic_block then_bb, fallthru_bb;
1214 *gsi = create_cond_insert_point (gsi, true, false, true,
1215 &then_bb, &fallthru_bb);
1216 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1217 int_const_binop (MINUS_EXPR, maxv, minv),
1218 NULL_TREE, NULL_TREE);
1219 gimple_set_location (g, loc);
1220 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1222 if (!can_throw)
1224 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1225 update_stmt (stmt);
1228 gsi2 = gsi_after_labels (then_bb);
1229 if (flag_sanitize_undefined_trap_on_error)
1230 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1231 else
1233 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1234 ubsan_type_descriptor (type), NULL_TREE,
1235 NULL_TREE);
1236 data = build_fold_addr_expr_loc (loc, data);
1237 enum built_in_function bcode
1238 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1239 ? SANITIZE_BOOL : SANITIZE_ENUM))
1240 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1241 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1242 tree fn = builtin_decl_explicit (bcode);
1244 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1245 true, NULL_TREE, true,
1246 GSI_SAME_STMT);
1247 g = gimple_build_call (fn, 2, data, val);
1249 gimple_set_location (g, loc);
1250 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1251 *gsi = gsi_for_stmt (stmt);
1254 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1255 destination, EXPR is floating-point expression. */
1257 tree
1258 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1260 tree expr_type = TREE_TYPE (expr);
1261 tree t, tt, fn, min, max;
1262 machine_mode mode = TYPE_MODE (expr_type);
1263 int prec = TYPE_PRECISION (type);
1264 bool uns_p = TYPE_UNSIGNED (type);
1266 /* Float to integer conversion first truncates toward zero, so
1267 even signed char c = 127.875f; is not problematic.
1268 Therefore, we should complain only if EXPR is unordered or smaller
1269 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1270 TYPE_MAX_VALUE + 1.0. */
1271 if (REAL_MODE_FORMAT (mode)->b == 2)
1273 /* For maximum, TYPE_MAX_VALUE might not be representable
1274 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1275 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1276 either representable or infinity. */
1277 REAL_VALUE_TYPE maxval = dconst1;
1278 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1279 real_convert (&maxval, mode, &maxval);
1280 max = build_real (expr_type, maxval);
1282 /* For unsigned, assume -1.0 is always representable. */
1283 if (uns_p)
1284 min = build_minus_one_cst (expr_type);
1285 else
1287 /* TYPE_MIN_VALUE is generally representable (or -inf),
1288 but TYPE_MIN_VALUE - 1.0 might not be. */
1289 REAL_VALUE_TYPE minval = dconstm1, minval2;
1290 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1291 real_convert (&minval, mode, &minval);
1292 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1293 real_convert (&minval2, mode, &minval2);
1294 if (real_compare (EQ_EXPR, &minval, &minval2)
1295 && !real_isinf (&minval))
1297 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1298 rounds to TYPE_MIN_VALUE, we need to subtract
1299 more. As REAL_MODE_FORMAT (mode)->p is the number
1300 of base digits, we want to subtract a number that
1301 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1302 times smaller than minval. */
1303 minval2 = dconst1;
1304 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1305 SET_REAL_EXP (&minval2,
1306 REAL_EXP (&minval2) + prec - 1
1307 - REAL_MODE_FORMAT (mode)->p + 1);
1308 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1309 real_convert (&minval2, mode, &minval2);
1311 min = build_real (expr_type, minval2);
1314 else if (REAL_MODE_FORMAT (mode)->b == 10)
1316 /* For _Decimal128 up to 34 decimal digits, - sign,
1317 dot, e, exponent. */
1318 char buf[64];
1319 mpfr_t m;
1320 int p = REAL_MODE_FORMAT (mode)->p;
1321 REAL_VALUE_TYPE maxval, minval;
1323 /* Use mpfr_snprintf rounding to compute the smallest
1324 representable decimal number greater or equal than
1325 1 << (prec - !uns_p). */
1326 mpfr_init2 (m, prec + 2);
1327 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1328 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1329 decimal_real_from_string (&maxval, buf);
1330 max = build_real (expr_type, maxval);
1332 /* For unsigned, assume -1.0 is always representable. */
1333 if (uns_p)
1334 min = build_minus_one_cst (expr_type);
1335 else
1337 /* Use mpfr_snprintf rounding to compute the largest
1338 representable decimal number less or equal than
1339 (-1 << (prec - 1)) - 1. */
1340 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1341 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1342 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1343 decimal_real_from_string (&minval, buf);
1344 min = build_real (expr_type, minval);
1346 mpfr_clear (m);
1348 else
1349 return NULL_TREE;
1351 if (flag_sanitize_undefined_trap_on_error)
1352 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1353 else
1355 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1356 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1357 NULL, ubsan_type_descriptor (expr_type),
1358 ubsan_type_descriptor (type), NULL_TREE,
1359 NULL_TREE);
1360 enum built_in_function bcode
1361 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1362 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1363 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1364 fn = builtin_decl_explicit (bcode);
1365 fn = build_call_expr_loc (loc, fn, 2,
1366 build_fold_addr_expr_loc (loc, data),
1367 ubsan_encode_value (expr, false));
1370 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1371 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1372 return fold_build3 (COND_EXPR, void_type_node,
1373 fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt),
1374 fn, integer_zero_node);
1377 /* Instrument values passed to function arguments with nonnull attribute. */
1379 static void
1380 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1382 gimple stmt = gsi_stmt (*gsi);
1383 location_t loc[2];
1384 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1385 while for nonnull sanitization it is clear. */
1386 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1387 flag_delete_null_pointer_checks = 1;
1388 loc[0] = gimple_location (stmt);
1389 loc[1] = UNKNOWN_LOCATION;
1390 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1392 tree arg = gimple_call_arg (stmt, i);
1393 if (POINTER_TYPE_P (TREE_TYPE (arg))
1394 && infer_nonnull_range (stmt, arg, false, true))
1396 gimple g;
1397 if (!is_gimple_val (arg))
1399 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1400 gimple_set_location (g, loc[0]);
1401 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1402 arg = gimple_assign_lhs (g);
1405 basic_block then_bb, fallthru_bb;
1406 *gsi = create_cond_insert_point (gsi, true, false, true,
1407 &then_bb, &fallthru_bb);
1408 g = gimple_build_cond (EQ_EXPR, arg,
1409 build_zero_cst (TREE_TYPE (arg)),
1410 NULL_TREE, NULL_TREE);
1411 gimple_set_location (g, loc[0]);
1412 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1414 *gsi = gsi_after_labels (then_bb);
1415 if (flag_sanitize_undefined_trap_on_error)
1416 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1417 else
1419 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1420 2, loc, NULL_TREE,
1421 build_int_cst (integer_type_node,
1422 i + 1),
1423 NULL_TREE);
1424 data = build_fold_addr_expr_loc (loc[0], data);
1425 enum built_in_function bcode
1426 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1427 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1428 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1429 tree fn = builtin_decl_explicit (bcode);
1431 g = gimple_build_call (fn, 1, data);
1433 gimple_set_location (g, loc[0]);
1434 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1436 *gsi = gsi_for_stmt (stmt);
1438 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1441 /* Instrument returns in functions with returns_nonnull attribute. */
1443 static void
1444 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1446 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1447 location_t loc[2];
1448 tree arg = gimple_return_retval (stmt);
1449 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1450 while for nonnull return sanitization it is clear. */
1451 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1452 flag_delete_null_pointer_checks = 1;
1453 loc[0] = gimple_location (stmt);
1454 loc[1] = UNKNOWN_LOCATION;
1455 if (arg
1456 && POINTER_TYPE_P (TREE_TYPE (arg))
1457 && is_gimple_val (arg)
1458 && infer_nonnull_range (stmt, arg, false, true))
1460 basic_block then_bb, fallthru_bb;
1461 *gsi = create_cond_insert_point (gsi, true, false, true,
1462 &then_bb, &fallthru_bb);
1463 gimple g = gimple_build_cond (EQ_EXPR, arg,
1464 build_zero_cst (TREE_TYPE (arg)),
1465 NULL_TREE, NULL_TREE);
1466 gimple_set_location (g, loc[0]);
1467 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1469 *gsi = gsi_after_labels (then_bb);
1470 if (flag_sanitize_undefined_trap_on_error)
1471 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1472 else
1474 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1475 2, loc, NULL_TREE, NULL_TREE);
1476 data = build_fold_addr_expr_loc (loc[0], data);
1477 enum built_in_function bcode
1478 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1479 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1480 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1481 tree fn = builtin_decl_explicit (bcode);
1483 g = gimple_build_call (fn, 1, data);
1485 gimple_set_location (g, loc[0]);
1486 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1487 *gsi = gsi_for_stmt (stmt);
1489 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1492 /* Instrument memory references. Here we check whether the pointer
1493 points to an out-of-bounds location. */
1495 static void
1496 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1498 gimple stmt = gsi_stmt (*gsi);
1499 location_t loc = gimple_location (stmt);
1500 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1501 tree type;
1502 tree index = NULL_TREE;
1503 HOST_WIDE_INT size_in_bytes;
1505 type = TREE_TYPE (t);
1506 if (VOID_TYPE_P (type))
1507 return;
1509 switch (TREE_CODE (t))
1511 case COMPONENT_REF:
1512 if (TREE_CODE (t) == COMPONENT_REF
1513 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1515 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1516 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1517 repr, NULL_TREE);
1519 break;
1520 case ARRAY_REF:
1521 index = TREE_OPERAND (t, 1);
1522 break;
1523 case INDIRECT_REF:
1524 case MEM_REF:
1525 case VAR_DECL:
1526 case PARM_DECL:
1527 case RESULT_DECL:
1528 break;
1529 default:
1530 return;
1533 size_in_bytes = int_size_in_bytes (type);
1534 if (size_in_bytes <= 0)
1535 return;
1537 HOST_WIDE_INT bitsize, bitpos;
1538 tree offset;
1539 machine_mode mode;
1540 int volatilep = 0, unsignedp = 0;
1541 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1542 &unsignedp, &volatilep, false);
1544 if (bitpos % BITS_PER_UNIT != 0
1545 || bitsize != size_in_bytes * BITS_PER_UNIT)
1546 return;
1548 bool decl_p = DECL_P (inner);
1549 tree base;
1550 if (decl_p)
1551 base = inner;
1552 else if (TREE_CODE (inner) == MEM_REF)
1553 base = TREE_OPERAND (inner, 0);
1554 else
1555 return;
1556 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1558 while (TREE_CODE (base) == SSA_NAME)
1560 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1561 if (gimple_assign_ssa_name_copy_p (def_stmt)
1562 || (gimple_assign_cast_p (def_stmt)
1563 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1564 || (is_gimple_assign (def_stmt)
1565 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1567 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1568 if (TREE_CODE (rhs1) == SSA_NAME
1569 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1570 break;
1571 else
1572 base = rhs1;
1574 else
1575 break;
1578 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1579 return;
1581 tree sizet;
1582 tree base_addr = base;
1583 if (decl_p)
1584 base_addr = build1 (ADDR_EXPR,
1585 build_pointer_type (TREE_TYPE (base)), base);
1586 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1587 if (size != (unsigned HOST_WIDE_INT) -1)
1588 sizet = build_int_cst (sizetype, size);
1589 else if (optimize)
1591 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1592 loc = input_location;
1593 /* Generate __builtin_object_size call. */
1594 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1595 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1596 integer_zero_node);
1597 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1598 GSI_SAME_STMT);
1600 else
1601 return;
1603 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1604 call. */
1605 /* ptr + sizeof (*ptr) - base */
1606 t = fold_build2 (MINUS_EXPR, sizetype,
1607 fold_convert (pointer_sized_int_node, ptr),
1608 fold_convert (pointer_sized_int_node, base_addr));
1609 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1611 /* Perhaps we can omit the check. */
1612 if (TREE_CODE (t) == INTEGER_CST
1613 && TREE_CODE (sizet) == INTEGER_CST
1614 && tree_int_cst_le (t, sizet))
1615 return;
1617 if (index != NULL_TREE
1618 && TREE_CODE (index) == SSA_NAME
1619 && TREE_CODE (sizet) == INTEGER_CST)
1621 gimple def = SSA_NAME_DEF_STMT (index);
1622 if (is_gimple_assign (def)
1623 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1624 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1626 tree cst = gimple_assign_rhs2 (def);
1627 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1628 TYPE_SIZE_UNIT (type));
1629 if (tree_int_cst_sgn (cst) >= 0
1630 && tree_int_cst_lt (cst, sz))
1631 return;
1635 /* Nope. Emit the check. */
1636 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1637 GSI_SAME_STMT);
1638 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1639 GSI_SAME_STMT);
1640 tree ckind = build_int_cst (unsigned_char_type_node,
1641 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1642 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1643 ptr, t, sizet, ckind);
1644 gimple_set_location (g, loc);
1645 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1648 namespace {
1650 const pass_data pass_data_ubsan =
1652 GIMPLE_PASS, /* type */
1653 "ubsan", /* name */
1654 OPTGROUP_NONE, /* optinfo_flags */
1655 TV_TREE_UBSAN, /* tv_id */
1656 ( PROP_cfg | PROP_ssa ), /* properties_required */
1657 0, /* properties_provided */
1658 0, /* properties_destroyed */
1659 0, /* todo_flags_start */
1660 TODO_update_ssa, /* todo_flags_finish */
1663 class pass_ubsan : public gimple_opt_pass
1665 public:
1666 pass_ubsan (gcc::context *ctxt)
1667 : gimple_opt_pass (pass_data_ubsan, ctxt)
1670 /* opt_pass methods: */
1671 virtual bool gate (function *)
1673 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1674 | SANITIZE_BOOL | SANITIZE_ENUM
1675 | SANITIZE_ALIGNMENT
1676 | SANITIZE_NONNULL_ATTRIBUTE
1677 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1678 | SANITIZE_OBJECT_SIZE)
1679 && current_function_decl != NULL_TREE
1680 && !lookup_attribute ("no_sanitize_undefined",
1681 DECL_ATTRIBUTES (current_function_decl));
1684 virtual unsigned int execute (function *);
1686 }; // class pass_ubsan
1688 unsigned int
1689 pass_ubsan::execute (function *fun)
1691 basic_block bb;
1692 gimple_stmt_iterator gsi;
1694 initialize_sanitizer_builtins ();
1696 FOR_EACH_BB_FN (bb, fun)
1698 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1700 gimple stmt = gsi_stmt (gsi);
1701 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1703 gsi_next (&gsi);
1704 continue;
1707 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1708 && is_gimple_assign (stmt))
1709 instrument_si_overflow (gsi);
1711 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1713 if (gimple_store_p (stmt))
1714 instrument_null (gsi, true);
1715 if (gimple_assign_load_p (stmt))
1716 instrument_null (gsi, false);
1719 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1720 && gimple_assign_load_p (stmt))
1722 instrument_bool_enum_load (&gsi);
1723 bb = gimple_bb (stmt);
1726 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1727 && is_gimple_call (stmt)
1728 && !gimple_call_internal_p (stmt))
1730 instrument_nonnull_arg (&gsi);
1731 bb = gimple_bb (stmt);
1734 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1735 && gimple_code (stmt) == GIMPLE_RETURN)
1737 instrument_nonnull_return (&gsi);
1738 bb = gimple_bb (stmt);
1741 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
1743 if (gimple_store_p (stmt))
1744 instrument_object_size (&gsi, true);
1745 if (gimple_assign_load_p (stmt))
1746 instrument_object_size (&gsi, false);
1749 gsi_next (&gsi);
1752 return 0;
1755 } // anon namespace
1757 gimple_opt_pass *
1758 make_pass_ubsan (gcc::context *ctxt)
1760 return new pass_ubsan (ctxt);
1763 #include "gt-ubsan.h"