gcc/
[official-gcc.git] / gcc / ubsan.c
blob7dae9670338d5577d996d9c9e99b933ad42b9185
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 "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. ARG is what to pass
1256 the libubsan call as value, often EXPR itself. */
1258 tree
1259 ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
1261 tree expr_type = TREE_TYPE (expr);
1262 tree t, tt, fn, min, max;
1263 machine_mode mode = TYPE_MODE (expr_type);
1264 int prec = TYPE_PRECISION (type);
1265 bool uns_p = TYPE_UNSIGNED (type);
1267 /* Float to integer conversion first truncates toward zero, so
1268 even signed char c = 127.875f; is not problematic.
1269 Therefore, we should complain only if EXPR is unordered or smaller
1270 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1271 TYPE_MAX_VALUE + 1.0. */
1272 if (REAL_MODE_FORMAT (mode)->b == 2)
1274 /* For maximum, TYPE_MAX_VALUE might not be representable
1275 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1276 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1277 either representable or infinity. */
1278 REAL_VALUE_TYPE maxval = dconst1;
1279 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1280 real_convert (&maxval, mode, &maxval);
1281 max = build_real (expr_type, maxval);
1283 /* For unsigned, assume -1.0 is always representable. */
1284 if (uns_p)
1285 min = build_minus_one_cst (expr_type);
1286 else
1288 /* TYPE_MIN_VALUE is generally representable (or -inf),
1289 but TYPE_MIN_VALUE - 1.0 might not be. */
1290 REAL_VALUE_TYPE minval = dconstm1, minval2;
1291 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1292 real_convert (&minval, mode, &minval);
1293 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1294 real_convert (&minval2, mode, &minval2);
1295 if (real_compare (EQ_EXPR, &minval, &minval2)
1296 && !real_isinf (&minval))
1298 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1299 rounds to TYPE_MIN_VALUE, we need to subtract
1300 more. As REAL_MODE_FORMAT (mode)->p is the number
1301 of base digits, we want to subtract a number that
1302 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1303 times smaller than minval. */
1304 minval2 = dconst1;
1305 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1306 SET_REAL_EXP (&minval2,
1307 REAL_EXP (&minval2) + prec - 1
1308 - REAL_MODE_FORMAT (mode)->p + 1);
1309 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1310 real_convert (&minval2, mode, &minval2);
1312 min = build_real (expr_type, minval2);
1315 else if (REAL_MODE_FORMAT (mode)->b == 10)
1317 /* For _Decimal128 up to 34 decimal digits, - sign,
1318 dot, e, exponent. */
1319 char buf[64];
1320 mpfr_t m;
1321 int p = REAL_MODE_FORMAT (mode)->p;
1322 REAL_VALUE_TYPE maxval, minval;
1324 /* Use mpfr_snprintf rounding to compute the smallest
1325 representable decimal number greater or equal than
1326 1 << (prec - !uns_p). */
1327 mpfr_init2 (m, prec + 2);
1328 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1329 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1330 decimal_real_from_string (&maxval, buf);
1331 max = build_real (expr_type, maxval);
1333 /* For unsigned, assume -1.0 is always representable. */
1334 if (uns_p)
1335 min = build_minus_one_cst (expr_type);
1336 else
1338 /* Use mpfr_snprintf rounding to compute the largest
1339 representable decimal number less or equal than
1340 (-1 << (prec - 1)) - 1. */
1341 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1342 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1343 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1344 decimal_real_from_string (&minval, buf);
1345 min = build_real (expr_type, minval);
1347 mpfr_clear (m);
1349 else
1350 return NULL_TREE;
1352 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1353 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1354 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1355 if (integer_zerop (t))
1356 return NULL_TREE;
1358 if (flag_sanitize_undefined_trap_on_error)
1359 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1360 else
1362 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1363 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1364 NULL, ubsan_type_descriptor (expr_type),
1365 ubsan_type_descriptor (type), NULL_TREE,
1366 NULL_TREE);
1367 enum built_in_function bcode
1368 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1369 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1370 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1371 fn = builtin_decl_explicit (bcode);
1372 fn = build_call_expr_loc (loc, fn, 2,
1373 build_fold_addr_expr_loc (loc, data),
1374 ubsan_encode_value (arg, false));
1377 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1380 /* Instrument values passed to function arguments with nonnull attribute. */
1382 static void
1383 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1385 gimple stmt = gsi_stmt (*gsi);
1386 location_t loc[2];
1387 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1388 while for nonnull sanitization it is clear. */
1389 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1390 flag_delete_null_pointer_checks = 1;
1391 loc[0] = gimple_location (stmt);
1392 loc[1] = UNKNOWN_LOCATION;
1393 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1395 tree arg = gimple_call_arg (stmt, i);
1396 if (POINTER_TYPE_P (TREE_TYPE (arg))
1397 && infer_nonnull_range (stmt, arg, false, true))
1399 gimple g;
1400 if (!is_gimple_val (arg))
1402 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1403 gimple_set_location (g, loc[0]);
1404 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1405 arg = gimple_assign_lhs (g);
1408 basic_block then_bb, fallthru_bb;
1409 *gsi = create_cond_insert_point (gsi, true, false, true,
1410 &then_bb, &fallthru_bb);
1411 g = gimple_build_cond (EQ_EXPR, arg,
1412 build_zero_cst (TREE_TYPE (arg)),
1413 NULL_TREE, NULL_TREE);
1414 gimple_set_location (g, loc[0]);
1415 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1417 *gsi = gsi_after_labels (then_bb);
1418 if (flag_sanitize_undefined_trap_on_error)
1419 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1420 else
1422 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1423 2, loc, NULL_TREE,
1424 build_int_cst (integer_type_node,
1425 i + 1),
1426 NULL_TREE);
1427 data = build_fold_addr_expr_loc (loc[0], data);
1428 enum built_in_function bcode
1429 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1430 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1431 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1432 tree fn = builtin_decl_explicit (bcode);
1434 g = gimple_build_call (fn, 1, data);
1436 gimple_set_location (g, loc[0]);
1437 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1439 *gsi = gsi_for_stmt (stmt);
1441 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1444 /* Instrument returns in functions with returns_nonnull attribute. */
1446 static void
1447 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1449 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1450 location_t loc[2];
1451 tree arg = gimple_return_retval (stmt);
1452 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1453 while for nonnull return sanitization it is clear. */
1454 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1455 flag_delete_null_pointer_checks = 1;
1456 loc[0] = gimple_location (stmt);
1457 loc[1] = UNKNOWN_LOCATION;
1458 if (arg
1459 && POINTER_TYPE_P (TREE_TYPE (arg))
1460 && is_gimple_val (arg)
1461 && infer_nonnull_range (stmt, arg, false, true))
1463 basic_block then_bb, fallthru_bb;
1464 *gsi = create_cond_insert_point (gsi, true, false, true,
1465 &then_bb, &fallthru_bb);
1466 gimple g = gimple_build_cond (EQ_EXPR, arg,
1467 build_zero_cst (TREE_TYPE (arg)),
1468 NULL_TREE, NULL_TREE);
1469 gimple_set_location (g, loc[0]);
1470 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1472 *gsi = gsi_after_labels (then_bb);
1473 if (flag_sanitize_undefined_trap_on_error)
1474 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1475 else
1477 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1478 2, loc, NULL_TREE, NULL_TREE);
1479 data = build_fold_addr_expr_loc (loc[0], data);
1480 enum built_in_function bcode
1481 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1482 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1483 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1484 tree fn = builtin_decl_explicit (bcode);
1486 g = gimple_build_call (fn, 1, data);
1488 gimple_set_location (g, loc[0]);
1489 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1490 *gsi = gsi_for_stmt (stmt);
1492 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1495 /* Instrument memory references. Here we check whether the pointer
1496 points to an out-of-bounds location. */
1498 static void
1499 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1501 gimple stmt = gsi_stmt (*gsi);
1502 location_t loc = gimple_location (stmt);
1503 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1504 tree type;
1505 tree index = NULL_TREE;
1506 HOST_WIDE_INT size_in_bytes;
1508 type = TREE_TYPE (t);
1509 if (VOID_TYPE_P (type))
1510 return;
1512 switch (TREE_CODE (t))
1514 case COMPONENT_REF:
1515 if (TREE_CODE (t) == COMPONENT_REF
1516 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1518 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1519 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1520 repr, NULL_TREE);
1522 break;
1523 case ARRAY_REF:
1524 index = TREE_OPERAND (t, 1);
1525 break;
1526 case INDIRECT_REF:
1527 case MEM_REF:
1528 case VAR_DECL:
1529 case PARM_DECL:
1530 case RESULT_DECL:
1531 break;
1532 default:
1533 return;
1536 size_in_bytes = int_size_in_bytes (type);
1537 if (size_in_bytes <= 0)
1538 return;
1540 HOST_WIDE_INT bitsize, bitpos;
1541 tree offset;
1542 machine_mode mode;
1543 int volatilep = 0, unsignedp = 0;
1544 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1545 &unsignedp, &volatilep, false);
1547 if (bitpos % BITS_PER_UNIT != 0
1548 || bitsize != size_in_bytes * BITS_PER_UNIT)
1549 return;
1551 bool decl_p = DECL_P (inner);
1552 tree base;
1553 if (decl_p)
1554 base = inner;
1555 else if (TREE_CODE (inner) == MEM_REF)
1556 base = TREE_OPERAND (inner, 0);
1557 else
1558 return;
1559 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1561 while (TREE_CODE (base) == SSA_NAME)
1563 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1564 if (gimple_assign_ssa_name_copy_p (def_stmt)
1565 || (gimple_assign_cast_p (def_stmt)
1566 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1567 || (is_gimple_assign (def_stmt)
1568 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1570 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1571 if (TREE_CODE (rhs1) == SSA_NAME
1572 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1573 break;
1574 else
1575 base = rhs1;
1577 else
1578 break;
1581 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1582 return;
1584 tree sizet;
1585 tree base_addr = base;
1586 if (decl_p)
1587 base_addr = build1 (ADDR_EXPR,
1588 build_pointer_type (TREE_TYPE (base)), base);
1589 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1590 if (size != (unsigned HOST_WIDE_INT) -1)
1591 sizet = build_int_cst (sizetype, size);
1592 else if (optimize)
1594 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1595 loc = input_location;
1596 /* Generate __builtin_object_size call. */
1597 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1598 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1599 integer_zero_node);
1600 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1601 GSI_SAME_STMT);
1603 else
1604 return;
1606 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1607 call. */
1608 /* ptr + sizeof (*ptr) - base */
1609 t = fold_build2 (MINUS_EXPR, sizetype,
1610 fold_convert (pointer_sized_int_node, ptr),
1611 fold_convert (pointer_sized_int_node, base_addr));
1612 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1614 /* Perhaps we can omit the check. */
1615 if (TREE_CODE (t) == INTEGER_CST
1616 && TREE_CODE (sizet) == INTEGER_CST
1617 && tree_int_cst_le (t, sizet))
1618 return;
1620 if (index != NULL_TREE
1621 && TREE_CODE (index) == SSA_NAME
1622 && TREE_CODE (sizet) == INTEGER_CST)
1624 gimple def = SSA_NAME_DEF_STMT (index);
1625 if (is_gimple_assign (def)
1626 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1627 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1629 tree cst = gimple_assign_rhs2 (def);
1630 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1631 TYPE_SIZE_UNIT (type));
1632 if (tree_int_cst_sgn (cst) >= 0
1633 && tree_int_cst_lt (cst, sz))
1634 return;
1638 /* Nope. Emit the check. */
1639 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1640 GSI_SAME_STMT);
1641 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1642 GSI_SAME_STMT);
1643 tree ckind = build_int_cst (unsigned_char_type_node,
1644 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1645 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1646 ptr, t, sizet, ckind);
1647 gimple_set_location (g, loc);
1648 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1651 /* True if we want to play UBSan games in the current function. */
1653 bool
1654 do_ubsan_in_current_function ()
1656 return (current_function_decl != NULL_TREE
1657 && !lookup_attribute ("no_sanitize_undefined",
1658 DECL_ATTRIBUTES (current_function_decl)));
1661 namespace {
1663 const pass_data pass_data_ubsan =
1665 GIMPLE_PASS, /* type */
1666 "ubsan", /* name */
1667 OPTGROUP_NONE, /* optinfo_flags */
1668 TV_TREE_UBSAN, /* tv_id */
1669 ( PROP_cfg | PROP_ssa ), /* properties_required */
1670 0, /* properties_provided */
1671 0, /* properties_destroyed */
1672 0, /* todo_flags_start */
1673 TODO_update_ssa, /* todo_flags_finish */
1676 class pass_ubsan : public gimple_opt_pass
1678 public:
1679 pass_ubsan (gcc::context *ctxt)
1680 : gimple_opt_pass (pass_data_ubsan, ctxt)
1683 /* opt_pass methods: */
1684 virtual bool gate (function *)
1686 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1687 | SANITIZE_BOOL | SANITIZE_ENUM
1688 | SANITIZE_ALIGNMENT
1689 | SANITIZE_NONNULL_ATTRIBUTE
1690 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1691 | SANITIZE_OBJECT_SIZE)
1692 && do_ubsan_in_current_function ();
1695 virtual unsigned int execute (function *);
1697 }; // class pass_ubsan
1699 unsigned int
1700 pass_ubsan::execute (function *fun)
1702 basic_block bb;
1703 gimple_stmt_iterator gsi;
1705 initialize_sanitizer_builtins ();
1707 FOR_EACH_BB_FN (bb, fun)
1709 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1711 gimple stmt = gsi_stmt (gsi);
1712 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1714 gsi_next (&gsi);
1715 continue;
1718 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1719 && is_gimple_assign (stmt))
1720 instrument_si_overflow (gsi);
1722 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1724 if (gimple_store_p (stmt))
1725 instrument_null (gsi, true);
1726 if (gimple_assign_load_p (stmt))
1727 instrument_null (gsi, false);
1730 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1731 && gimple_assign_load_p (stmt))
1733 instrument_bool_enum_load (&gsi);
1734 bb = gimple_bb (stmt);
1737 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1738 && is_gimple_call (stmt)
1739 && !gimple_call_internal_p (stmt))
1741 instrument_nonnull_arg (&gsi);
1742 bb = gimple_bb (stmt);
1745 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1746 && gimple_code (stmt) == GIMPLE_RETURN)
1748 instrument_nonnull_return (&gsi);
1749 bb = gimple_bb (stmt);
1752 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
1754 if (gimple_store_p (stmt))
1755 instrument_object_size (&gsi, true);
1756 if (gimple_assign_load_p (stmt))
1757 instrument_object_size (&gsi, false);
1760 gsi_next (&gsi);
1763 return 0;
1766 } // anon namespace
1768 gimple_opt_pass *
1769 make_pass_ubsan (gcc::context *ctxt)
1771 return new pass_ubsan (ctxt);
1774 #include "gt-ubsan.h"