* gcc.dg/store-motion-fgcse-sm.c (dg-final): Cleanup
[official-gcc.git] / gcc / ubsan.c
blobb3d5343605e0276c4adef61f42c59a79e69c355c
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, NULL);
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 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
657 "__builtin___ubsan_", 18) == 0;
660 /* Expand the UBSAN_BOUNDS special builtin function. */
662 bool
663 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
665 gimple stmt = gsi_stmt (*gsi);
666 location_t loc = gimple_location (stmt);
667 gcc_assert (gimple_call_num_args (stmt) == 3);
669 /* Pick up the arguments of the UBSAN_BOUNDS call. */
670 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
671 tree index = gimple_call_arg (stmt, 1);
672 tree orig_index_type = TREE_TYPE (index);
673 tree bound = gimple_call_arg (stmt, 2);
675 gimple_stmt_iterator gsi_orig = *gsi;
677 /* Create condition "if (index > bound)". */
678 basic_block then_bb, fallthru_bb;
679 gimple_stmt_iterator cond_insert_point
680 = create_cond_insert_point (gsi, false, false, true,
681 &then_bb, &fallthru_bb);
682 index = fold_convert (TREE_TYPE (bound), index);
683 index = force_gimple_operand_gsi (&cond_insert_point, index,
684 true, NULL_TREE,
685 false, GSI_NEW_STMT);
686 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
687 gimple_set_location (g, loc);
688 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
690 /* Generate __ubsan_handle_out_of_bounds call. */
691 *gsi = gsi_after_labels (then_bb);
692 if (flag_sanitize_undefined_trap_on_error)
693 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
694 else
696 tree data
697 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
698 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
699 ubsan_type_descriptor (orig_index_type),
700 NULL_TREE, NULL_TREE);
701 data = build_fold_addr_expr_loc (loc, data);
702 enum built_in_function bcode
703 = (flag_sanitize_recover & SANITIZE_BOUNDS)
704 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
705 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
706 tree fn = builtin_decl_explicit (bcode);
707 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
708 true, NULL_TREE, true,
709 GSI_SAME_STMT);
710 g = gimple_build_call (fn, 2, data, val);
712 gimple_set_location (g, loc);
713 gsi_insert_before (gsi, g, GSI_SAME_STMT);
715 /* Get rid of the UBSAN_BOUNDS call from the IR. */
716 unlink_stmt_vdef (stmt);
717 gsi_remove (&gsi_orig, true);
719 /* Point GSI to next logical statement. */
720 *gsi = gsi_start_bb (fallthru_bb);
721 return true;
724 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
725 argument which is a constant, because the middle-end treats pointer
726 conversions as useless and therefore the type of the first argument
727 could be changed to any other pointer type. */
729 bool
730 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
732 gimple_stmt_iterator gsi = *gsip;
733 gimple stmt = gsi_stmt (gsi);
734 location_t loc = gimple_location (stmt);
735 gcc_assert (gimple_call_num_args (stmt) == 3);
736 tree ptr = gimple_call_arg (stmt, 0);
737 tree ckind = gimple_call_arg (stmt, 1);
738 tree align = gimple_call_arg (stmt, 2);
739 tree check_align = NULL_TREE;
740 bool check_null;
742 basic_block cur_bb = gsi_bb (gsi);
744 gimple g;
745 if (!integer_zerop (align))
747 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
748 if (compare_tree_int (align, ptralign) == 1)
750 check_align = make_ssa_name (pointer_sized_int_node, NULL);
751 g = gimple_build_assign_with_ops (NOP_EXPR, check_align, ptr);
752 gimple_set_location (g, loc);
753 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
756 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
758 if (check_align == NULL_TREE && !check_null)
760 gsi_remove (gsip, true);
761 /* Unlink the UBSAN_NULLs vops before replacing it. */
762 unlink_stmt_vdef (stmt);
763 return true;
766 /* Split the original block holding the pointer dereference. */
767 edge e = split_block (cur_bb, stmt);
769 /* Get a hold on the 'condition block', the 'then block' and the
770 'else block'. */
771 basic_block cond_bb = e->src;
772 basic_block fallthru_bb = e->dest;
773 basic_block then_bb = create_empty_bb (cond_bb);
774 add_bb_to_loop (then_bb, cond_bb->loop_father);
775 loops_state_set (LOOPS_NEED_FIXUP);
777 /* Make an edge coming from the 'cond block' into the 'then block';
778 this edge is unlikely taken, so set up the probability accordingly. */
779 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
780 e->probability = PROB_VERY_UNLIKELY;
782 /* Connect 'then block' with the 'else block'. This is needed
783 as the ubsan routines we call in the 'then block' are not noreturn.
784 The 'then block' only has one outcoming edge. */
785 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
787 /* Set up the fallthrough basic block. */
788 e = find_edge (cond_bb, fallthru_bb);
789 e->flags = EDGE_FALSE_VALUE;
790 e->count = cond_bb->count;
791 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
793 /* Update dominance info for the newly created then_bb; note that
794 fallthru_bb's dominance info has already been updated by
795 split_block. */
796 if (dom_info_available_p (CDI_DOMINATORS))
797 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
799 /* Put the ubsan builtin call into the newly created BB. */
800 if (flag_sanitize_undefined_trap_on_error)
801 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
802 else
804 enum built_in_function bcode
805 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
806 | (check_null ? SANITIZE_NULL : 0)))
807 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
808 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
809 tree fn = builtin_decl_implicit (bcode);
810 tree data
811 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
812 ubsan_type_descriptor (TREE_TYPE (ckind),
813 UBSAN_PRINT_POINTER),
814 NULL_TREE,
815 align,
816 fold_convert (unsigned_char_type_node, ckind),
817 NULL_TREE);
818 data = build_fold_addr_expr_loc (loc, data);
819 g = gimple_build_call (fn, 2, data,
820 check_align ? check_align
821 : build_zero_cst (pointer_sized_int_node));
823 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
824 gimple_set_location (g, loc);
825 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
827 /* Unlink the UBSAN_NULLs vops before replacing it. */
828 unlink_stmt_vdef (stmt);
830 if (check_null)
832 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
833 NULL_TREE, NULL_TREE);
834 gimple_set_location (g, loc);
836 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
837 gsi_replace (&gsi, g, false);
840 if (check_align)
842 if (check_null)
844 /* Split the block with the condition again. */
845 e = split_block (cond_bb, stmt);
846 basic_block cond1_bb = e->src;
847 basic_block cond2_bb = e->dest;
849 /* Make an edge coming from the 'cond1 block' into the 'then block';
850 this edge is unlikely taken, so set up the probability
851 accordingly. */
852 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
853 e->probability = PROB_VERY_UNLIKELY;
855 /* Set up the fallthrough basic block. */
856 e = find_edge (cond1_bb, cond2_bb);
857 e->flags = EDGE_FALSE_VALUE;
858 e->count = cond1_bb->count;
859 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
861 /* Update dominance info. */
862 if (dom_info_available_p (CDI_DOMINATORS))
864 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
865 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
868 gsi2 = gsi_start_bb (cond2_bb);
871 tree mask = build_int_cst (pointer_sized_int_node,
872 tree_to_uhwi (align) - 1);
873 g = gimple_build_assign_with_ops (BIT_AND_EXPR,
874 make_ssa_name (pointer_sized_int_node,
875 NULL),
876 check_align, mask);
877 gimple_set_location (g, loc);
878 if (check_null)
879 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
880 else
881 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
883 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
884 build_int_cst (pointer_sized_int_node, 0),
885 NULL_TREE, NULL_TREE);
886 gimple_set_location (g, loc);
887 if (check_null)
888 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
889 else
890 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
891 gsi_replace (&gsi, g, false);
893 return false;
896 /* Expand UBSAN_OBJECT_SIZE internal call. */
898 bool
899 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
901 gimple stmt = gsi_stmt (*gsi);
902 location_t loc = gimple_location (stmt);
903 gcc_assert (gimple_call_num_args (stmt) == 4);
905 tree ptr = gimple_call_arg (stmt, 0);
906 tree offset = gimple_call_arg (stmt, 1);
907 tree size = gimple_call_arg (stmt, 2);
908 tree ckind = gimple_call_arg (stmt, 3);
909 gimple_stmt_iterator gsi_orig = *gsi;
910 gimple g;
912 /* See if we can discard the check. */
913 if (TREE_CODE (size) != INTEGER_CST
914 || integer_all_onesp (size))
915 /* Yes, __builtin_object_size couldn't determine the
916 object size. */;
917 else
919 /* if (offset > objsize) */
920 basic_block then_bb, fallthru_bb;
921 gimple_stmt_iterator cond_insert_point
922 = create_cond_insert_point (gsi, false, false, true,
923 &then_bb, &fallthru_bb);
924 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
925 gimple_set_location (g, loc);
926 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
928 /* Generate __ubsan_handle_type_mismatch call. */
929 *gsi = gsi_after_labels (then_bb);
930 if (flag_sanitize_undefined_trap_on_error)
931 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
932 else
934 tree data
935 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
936 ubsan_type_descriptor (TREE_TYPE (ptr),
937 UBSAN_PRINT_POINTER),
938 NULL_TREE,
939 build_zero_cst (pointer_sized_int_node),
940 ckind,
941 NULL_TREE);
942 data = build_fold_addr_expr_loc (loc, data);
943 enum built_in_function bcode
944 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
945 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
946 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
947 tree p = make_ssa_name (pointer_sized_int_node, NULL);
948 g = gimple_build_assign_with_ops (NOP_EXPR, p, ptr);
949 gimple_set_location (g, loc);
950 gsi_insert_before (gsi, g, GSI_SAME_STMT);
951 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
953 gimple_set_location (g, loc);
954 gsi_insert_before (gsi, g, GSI_SAME_STMT);
956 /* Point GSI to next logical statement. */
957 *gsi = gsi_start_bb (fallthru_bb);
960 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
961 unlink_stmt_vdef (stmt);
962 gsi_remove (&gsi_orig, true);
963 return gsi_end_p (*gsi);
966 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
967 whether the pointer is on the left hand side of the assignment. */
969 static void
970 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
971 bool is_lhs)
973 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
974 unsigned int align = 0;
975 if (flag_sanitize & SANITIZE_ALIGNMENT)
977 align = min_align_of_type (TREE_TYPE (base));
978 if (align <= 1)
979 align = 0;
981 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
982 return;
983 tree t = TREE_OPERAND (base, 0);
984 if (!POINTER_TYPE_P (TREE_TYPE (t)))
985 return;
986 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && mem != base)
987 ikind = UBSAN_MEMBER_ACCESS;
988 tree kind = build_int_cst (TREE_TYPE (t), ikind);
989 tree alignt = build_int_cst (pointer_sized_int_node, align);
990 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
991 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
992 gsi_insert_before (iter, g, GSI_SAME_STMT);
995 /* Perform the pointer instrumentation. */
997 static void
998 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1000 gimple stmt = gsi_stmt (gsi);
1001 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1002 tree base = get_base_address (t);
1003 const enum tree_code code = TREE_CODE (base);
1004 if (code == MEM_REF
1005 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1006 instrument_mem_ref (t, base, &gsi, is_lhs);
1009 /* Build an ubsan builtin call for the signed-integer-overflow
1010 sanitization. CODE says what kind of builtin are we building,
1011 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1012 are operands of the binary operation. */
1014 tree
1015 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1016 tree op0, tree op1)
1018 if (flag_sanitize_undefined_trap_on_error)
1019 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1021 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1022 ubsan_type_descriptor (lhstype), NULL_TREE,
1023 NULL_TREE);
1024 enum built_in_function fn_code;
1026 switch (code)
1028 case PLUS_EXPR:
1029 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1030 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1031 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1032 break;
1033 case MINUS_EXPR:
1034 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1035 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1036 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1037 break;
1038 case MULT_EXPR:
1039 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1040 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1041 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1042 break;
1043 case NEGATE_EXPR:
1044 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1045 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1046 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1047 break;
1048 default:
1049 gcc_unreachable ();
1051 tree fn = builtin_decl_explicit (fn_code);
1052 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1053 build_fold_addr_expr_loc (loc, data),
1054 ubsan_encode_value (op0, true),
1055 op1 ? ubsan_encode_value (op1, true)
1056 : NULL_TREE);
1059 /* Perform the signed integer instrumentation. GSI is the iterator
1060 pointing at statement we are trying to instrument. */
1062 static void
1063 instrument_si_overflow (gimple_stmt_iterator gsi)
1065 gimple stmt = gsi_stmt (gsi);
1066 tree_code code = gimple_assign_rhs_code (stmt);
1067 tree lhs = gimple_assign_lhs (stmt);
1068 tree lhstype = TREE_TYPE (lhs);
1069 tree a, b;
1070 gimple g;
1072 /* If this is not a signed operation, don't instrument anything here.
1073 Also punt on bit-fields. */
1074 if (!INTEGRAL_TYPE_P (lhstype)
1075 || TYPE_OVERFLOW_WRAPS (lhstype)
1076 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1077 return;
1079 switch (code)
1081 case MINUS_EXPR:
1082 case PLUS_EXPR:
1083 case MULT_EXPR:
1084 /* Transform
1085 i = u {+,-,*} 5;
1086 into
1087 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1088 a = gimple_assign_rhs1 (stmt);
1089 b = gimple_assign_rhs2 (stmt);
1090 g = gimple_build_call_internal (code == PLUS_EXPR
1091 ? IFN_UBSAN_CHECK_ADD
1092 : code == MINUS_EXPR
1093 ? IFN_UBSAN_CHECK_SUB
1094 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1095 gimple_call_set_lhs (g, lhs);
1096 gsi_replace (&gsi, g, false);
1097 break;
1098 case NEGATE_EXPR:
1099 /* Represent i = -u;
1101 i = UBSAN_CHECK_SUB (0, u); */
1102 a = build_int_cst (lhstype, 0);
1103 b = gimple_assign_rhs1 (stmt);
1104 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1105 gimple_call_set_lhs (g, lhs);
1106 gsi_replace (&gsi, g, false);
1107 break;
1108 case ABS_EXPR:
1109 /* Transform i = ABS_EXPR<u>;
1110 into
1111 _N = UBSAN_CHECK_SUB (0, u);
1112 i = ABS_EXPR<_N>; */
1113 a = build_int_cst (lhstype, 0);
1114 b = gimple_assign_rhs1 (stmt);
1115 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1116 a = make_ssa_name (lhstype, NULL);
1117 gimple_call_set_lhs (g, a);
1118 gimple_set_location (g, gimple_location (stmt));
1119 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1120 gimple_assign_set_rhs1 (stmt, a);
1121 update_stmt (stmt);
1122 break;
1123 default:
1124 break;
1128 /* Instrument loads from (non-bitfield) bool and C++ enum values
1129 to check if the memory value is outside of the range of the valid
1130 type values. */
1132 static void
1133 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1135 gimple stmt = gsi_stmt (*gsi);
1136 tree rhs = gimple_assign_rhs1 (stmt);
1137 tree type = TREE_TYPE (rhs);
1138 tree minv = NULL_TREE, maxv = NULL_TREE;
1140 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1142 minv = boolean_false_node;
1143 maxv = boolean_true_node;
1145 else if (TREE_CODE (type) == ENUMERAL_TYPE
1146 && (flag_sanitize & SANITIZE_ENUM)
1147 && TREE_TYPE (type) != NULL_TREE
1148 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1149 && (TYPE_PRECISION (TREE_TYPE (type))
1150 < GET_MODE_PRECISION (TYPE_MODE (type))))
1152 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1153 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1155 else
1156 return;
1158 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1159 HOST_WIDE_INT bitsize, bitpos;
1160 tree offset;
1161 machine_mode mode;
1162 int volatilep = 0, unsignedp = 0;
1163 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1164 &unsignedp, &volatilep, false);
1165 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1167 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1168 || (bitpos % modebitsize) != 0
1169 || bitsize != modebitsize
1170 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1171 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1172 return;
1174 bool can_throw = stmt_could_throw_p (stmt);
1175 location_t loc = gimple_location (stmt);
1176 tree lhs = gimple_assign_lhs (stmt);
1177 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1178 tree atype = reference_alias_ptr_type (rhs);
1179 gimple g = gimple_build_assign (make_ssa_name (ptype, NULL),
1180 build_fold_addr_expr (rhs));
1181 gimple_set_location (g, loc);
1182 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1183 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1184 build_int_cst (atype, 0));
1185 tree urhs = make_ssa_name (utype, NULL);
1186 if (can_throw)
1188 gimple_assign_set_lhs (stmt, urhs);
1189 g = gimple_build_assign_with_ops (NOP_EXPR, lhs, urhs);
1190 gimple_set_location (g, loc);
1191 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1192 gsi_insert_on_edge_immediate (e, g);
1193 gimple_assign_set_rhs_from_tree (gsi, mem);
1194 update_stmt (stmt);
1195 *gsi = gsi_for_stmt (g);
1196 g = stmt;
1198 else
1200 g = gimple_build_assign (urhs, mem);
1201 gimple_set_location (g, loc);
1202 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1204 minv = fold_convert (utype, minv);
1205 maxv = fold_convert (utype, maxv);
1206 if (!integer_zerop (minv))
1208 g = gimple_build_assign_with_ops (MINUS_EXPR,
1209 make_ssa_name (utype, NULL),
1210 urhs, minv);
1211 gimple_set_location (g, loc);
1212 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1215 gimple_stmt_iterator gsi2 = *gsi;
1216 basic_block then_bb, fallthru_bb;
1217 *gsi = create_cond_insert_point (gsi, true, false, true,
1218 &then_bb, &fallthru_bb);
1219 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1220 int_const_binop (MINUS_EXPR, maxv, minv),
1221 NULL_TREE, NULL_TREE);
1222 gimple_set_location (g, loc);
1223 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1225 if (!can_throw)
1227 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1228 update_stmt (stmt);
1231 gsi2 = gsi_after_labels (then_bb);
1232 if (flag_sanitize_undefined_trap_on_error)
1233 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1234 else
1236 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1237 ubsan_type_descriptor (type), NULL_TREE,
1238 NULL_TREE);
1239 data = build_fold_addr_expr_loc (loc, data);
1240 enum built_in_function bcode
1241 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1242 ? SANITIZE_BOOL : SANITIZE_ENUM))
1243 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1244 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1245 tree fn = builtin_decl_explicit (bcode);
1247 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1248 true, NULL_TREE, true,
1249 GSI_SAME_STMT);
1250 g = gimple_build_call (fn, 2, data, val);
1252 gimple_set_location (g, loc);
1253 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1254 *gsi = gsi_for_stmt (stmt);
1257 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1258 destination, EXPR is floating-point expression. */
1260 tree
1261 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1263 tree expr_type = TREE_TYPE (expr);
1264 tree t, tt, fn, min, max;
1265 machine_mode mode = TYPE_MODE (expr_type);
1266 int prec = TYPE_PRECISION (type);
1267 bool uns_p = TYPE_UNSIGNED (type);
1269 /* Float to integer conversion first truncates toward zero, so
1270 even signed char c = 127.875f; is not problematic.
1271 Therefore, we should complain only if EXPR is unordered or smaller
1272 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1273 TYPE_MAX_VALUE + 1.0. */
1274 if (REAL_MODE_FORMAT (mode)->b == 2)
1276 /* For maximum, TYPE_MAX_VALUE might not be representable
1277 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1278 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1279 either representable or infinity. */
1280 REAL_VALUE_TYPE maxval = dconst1;
1281 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1282 real_convert (&maxval, mode, &maxval);
1283 max = build_real (expr_type, maxval);
1285 /* For unsigned, assume -1.0 is always representable. */
1286 if (uns_p)
1287 min = build_minus_one_cst (expr_type);
1288 else
1290 /* TYPE_MIN_VALUE is generally representable (or -inf),
1291 but TYPE_MIN_VALUE - 1.0 might not be. */
1292 REAL_VALUE_TYPE minval = dconstm1, minval2;
1293 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1294 real_convert (&minval, mode, &minval);
1295 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1296 real_convert (&minval2, mode, &minval2);
1297 if (real_compare (EQ_EXPR, &minval, &minval2)
1298 && !real_isinf (&minval))
1300 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1301 rounds to TYPE_MIN_VALUE, we need to subtract
1302 more. As REAL_MODE_FORMAT (mode)->p is the number
1303 of base digits, we want to subtract a number that
1304 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1305 times smaller than minval. */
1306 minval2 = dconst1;
1307 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1308 SET_REAL_EXP (&minval2,
1309 REAL_EXP (&minval2) + prec - 1
1310 - REAL_MODE_FORMAT (mode)->p + 1);
1311 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1312 real_convert (&minval2, mode, &minval2);
1314 min = build_real (expr_type, minval2);
1317 else if (REAL_MODE_FORMAT (mode)->b == 10)
1319 /* For _Decimal128 up to 34 decimal digits, - sign,
1320 dot, e, exponent. */
1321 char buf[64];
1322 mpfr_t m;
1323 int p = REAL_MODE_FORMAT (mode)->p;
1324 REAL_VALUE_TYPE maxval, minval;
1326 /* Use mpfr_snprintf rounding to compute the smallest
1327 representable decimal number greater or equal than
1328 1 << (prec - !uns_p). */
1329 mpfr_init2 (m, prec + 2);
1330 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1331 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1332 decimal_real_from_string (&maxval, buf);
1333 max = build_real (expr_type, maxval);
1335 /* For unsigned, assume -1.0 is always representable. */
1336 if (uns_p)
1337 min = build_minus_one_cst (expr_type);
1338 else
1340 /* Use mpfr_snprintf rounding to compute the largest
1341 representable decimal number less or equal than
1342 (-1 << (prec - 1)) - 1. */
1343 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1344 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1345 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1346 decimal_real_from_string (&minval, buf);
1347 min = build_real (expr_type, minval);
1349 mpfr_clear (m);
1351 else
1352 return NULL_TREE;
1354 if (flag_sanitize_undefined_trap_on_error)
1355 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1356 else
1358 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1359 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1360 NULL, ubsan_type_descriptor (expr_type),
1361 ubsan_type_descriptor (type), NULL_TREE,
1362 NULL_TREE);
1363 enum built_in_function bcode
1364 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1365 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1366 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1367 fn = builtin_decl_explicit (bcode);
1368 fn = build_call_expr_loc (loc, fn, 2,
1369 build_fold_addr_expr_loc (loc, data),
1370 ubsan_encode_value (expr, false));
1373 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1374 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1375 return fold_build3 (COND_EXPR, void_type_node,
1376 fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt),
1377 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), NULL),
1403 arg);
1404 gimple_set_location (g, loc[0]);
1405 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1406 arg = gimple_assign_lhs (g);
1409 basic_block then_bb, fallthru_bb;
1410 *gsi = create_cond_insert_point (gsi, true, false, true,
1411 &then_bb, &fallthru_bb);
1412 g = gimple_build_cond (EQ_EXPR, arg,
1413 build_zero_cst (TREE_TYPE (arg)),
1414 NULL_TREE, NULL_TREE);
1415 gimple_set_location (g, loc[0]);
1416 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1418 *gsi = gsi_after_labels (then_bb);
1419 if (flag_sanitize_undefined_trap_on_error)
1420 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1421 else
1423 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1424 2, loc, NULL_TREE,
1425 build_int_cst (integer_type_node,
1426 i + 1),
1427 NULL_TREE);
1428 data = build_fold_addr_expr_loc (loc[0], data);
1429 enum built_in_function bcode
1430 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1431 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1432 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1433 tree fn = builtin_decl_explicit (bcode);
1435 g = gimple_build_call (fn, 1, data);
1437 gimple_set_location (g, loc[0]);
1438 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1440 *gsi = gsi_for_stmt (stmt);
1442 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1445 /* Instrument returns in functions with returns_nonnull attribute. */
1447 static void
1448 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1450 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1451 location_t loc[2];
1452 tree arg = gimple_return_retval (stmt);
1453 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1454 while for nonnull return sanitization it is clear. */
1455 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1456 flag_delete_null_pointer_checks = 1;
1457 loc[0] = gimple_location (stmt);
1458 loc[1] = UNKNOWN_LOCATION;
1459 if (arg
1460 && POINTER_TYPE_P (TREE_TYPE (arg))
1461 && is_gimple_val (arg)
1462 && infer_nonnull_range (stmt, arg, false, true))
1464 basic_block then_bb, fallthru_bb;
1465 *gsi = create_cond_insert_point (gsi, true, false, true,
1466 &then_bb, &fallthru_bb);
1467 gimple g = gimple_build_cond (EQ_EXPR, arg,
1468 build_zero_cst (TREE_TYPE (arg)),
1469 NULL_TREE, NULL_TREE);
1470 gimple_set_location (g, loc[0]);
1471 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1473 *gsi = gsi_after_labels (then_bb);
1474 if (flag_sanitize_undefined_trap_on_error)
1475 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1476 else
1478 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1479 2, loc, NULL_TREE, NULL_TREE);
1480 data = build_fold_addr_expr_loc (loc[0], data);
1481 enum built_in_function bcode
1482 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1483 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1484 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1485 tree fn = builtin_decl_explicit (bcode);
1487 g = gimple_build_call (fn, 1, data);
1489 gimple_set_location (g, loc[0]);
1490 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1491 *gsi = gsi_for_stmt (stmt);
1493 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1496 /* Instrument memory references. Here we check whether the pointer
1497 points to an out-of-bounds location. */
1499 static void
1500 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1502 gimple stmt = gsi_stmt (*gsi);
1503 location_t loc = gimple_location (stmt);
1504 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1505 tree type;
1506 tree index = NULL_TREE;
1507 HOST_WIDE_INT size_in_bytes;
1509 type = TREE_TYPE (t);
1510 if (VOID_TYPE_P (type))
1511 return;
1513 switch (TREE_CODE (t))
1515 case COMPONENT_REF:
1516 if (TREE_CODE (t) == COMPONENT_REF
1517 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1519 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1520 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1521 repr, NULL_TREE);
1523 break;
1524 case ARRAY_REF:
1525 index = TREE_OPERAND (t, 1);
1526 break;
1527 case INDIRECT_REF:
1528 case MEM_REF:
1529 case VAR_DECL:
1530 case PARM_DECL:
1531 case RESULT_DECL:
1532 break;
1533 default:
1534 return;
1537 size_in_bytes = int_size_in_bytes (type);
1538 if (size_in_bytes <= 0)
1539 return;
1541 HOST_WIDE_INT bitsize, bitpos;
1542 tree offset;
1543 machine_mode mode;
1544 int volatilep = 0, unsignedp = 0;
1545 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1546 &unsignedp, &volatilep, false);
1548 if (bitpos % BITS_PER_UNIT != 0
1549 || bitsize != size_in_bytes * BITS_PER_UNIT)
1550 return;
1552 bool decl_p = DECL_P (inner);
1553 tree base;
1554 if (decl_p)
1555 base = inner;
1556 else if (TREE_CODE (inner) == MEM_REF)
1557 base = TREE_OPERAND (inner, 0);
1558 else
1559 return;
1560 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1562 while (TREE_CODE (base) == SSA_NAME)
1564 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1565 if (gimple_assign_ssa_name_copy_p (def_stmt)
1566 || (gimple_assign_cast_p (def_stmt)
1567 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1568 || (is_gimple_assign (def_stmt)
1569 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1570 base = gimple_assign_rhs1 (def_stmt);
1571 else
1572 break;
1575 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1576 return;
1578 tree sizet;
1579 tree base_addr = base;
1580 if (decl_p)
1581 base_addr = build1 (ADDR_EXPR,
1582 build_pointer_type (TREE_TYPE (base)), base);
1583 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1584 if (size != (unsigned HOST_WIDE_INT) -1)
1585 sizet = build_int_cst (sizetype, size);
1586 else if (optimize)
1588 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1589 loc = input_location;
1590 /* Generate __builtin_object_size call. */
1591 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1592 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1593 integer_zero_node);
1594 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1595 GSI_SAME_STMT);
1597 else
1598 return;
1600 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1601 call. */
1602 /* ptr + sizeof (*ptr) - base */
1603 t = fold_build2 (MINUS_EXPR, sizetype,
1604 fold_convert (pointer_sized_int_node, ptr),
1605 fold_convert (pointer_sized_int_node, base_addr));
1606 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1608 /* Perhaps we can omit the check. */
1609 if (TREE_CODE (t) == INTEGER_CST
1610 && TREE_CODE (sizet) == INTEGER_CST
1611 && tree_int_cst_le (t, sizet))
1612 return;
1614 if (index != NULL_TREE
1615 && TREE_CODE (index) == SSA_NAME
1616 && TREE_CODE (sizet) == INTEGER_CST)
1618 gimple def = SSA_NAME_DEF_STMT (index);
1619 if (is_gimple_assign (def)
1620 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1621 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1623 tree cst = gimple_assign_rhs2 (def);
1624 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1625 TYPE_SIZE_UNIT (type));
1626 if (tree_int_cst_sgn (cst) >= 0
1627 && tree_int_cst_lt (cst, sz))
1628 return;
1632 /* Nope. Emit the check. */
1633 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1634 GSI_SAME_STMT);
1635 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1636 GSI_SAME_STMT);
1637 tree ckind = build_int_cst (unsigned_char_type_node,
1638 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1639 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1640 ptr, t, sizet, ckind);
1641 gimple_set_location (g, loc);
1642 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1645 namespace {
1647 const pass_data pass_data_ubsan =
1649 GIMPLE_PASS, /* type */
1650 "ubsan", /* name */
1651 OPTGROUP_NONE, /* optinfo_flags */
1652 TV_TREE_UBSAN, /* tv_id */
1653 ( PROP_cfg | PROP_ssa ), /* properties_required */
1654 0, /* properties_provided */
1655 0, /* properties_destroyed */
1656 0, /* todo_flags_start */
1657 TODO_update_ssa, /* todo_flags_finish */
1660 class pass_ubsan : public gimple_opt_pass
1662 public:
1663 pass_ubsan (gcc::context *ctxt)
1664 : gimple_opt_pass (pass_data_ubsan, ctxt)
1667 /* opt_pass methods: */
1668 virtual bool gate (function *)
1670 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1671 | SANITIZE_BOOL | SANITIZE_ENUM
1672 | SANITIZE_ALIGNMENT
1673 | SANITIZE_NONNULL_ATTRIBUTE
1674 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1675 | SANITIZE_OBJECT_SIZE)
1676 && current_function_decl != NULL_TREE
1677 && !lookup_attribute ("no_sanitize_undefined",
1678 DECL_ATTRIBUTES (current_function_decl));
1681 virtual unsigned int execute (function *);
1683 }; // class pass_ubsan
1685 unsigned int
1686 pass_ubsan::execute (function *fun)
1688 basic_block bb;
1689 gimple_stmt_iterator gsi;
1691 initialize_sanitizer_builtins ();
1693 FOR_EACH_BB_FN (bb, fun)
1695 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1697 gimple stmt = gsi_stmt (gsi);
1698 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1700 gsi_next (&gsi);
1701 continue;
1704 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1705 && is_gimple_assign (stmt))
1706 instrument_si_overflow (gsi);
1708 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1710 if (gimple_store_p (stmt))
1711 instrument_null (gsi, true);
1712 if (gimple_assign_load_p (stmt))
1713 instrument_null (gsi, false);
1716 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1717 && gimple_assign_load_p (stmt))
1719 instrument_bool_enum_load (&gsi);
1720 bb = gimple_bb (stmt);
1723 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1724 && is_gimple_call (stmt)
1725 && !gimple_call_internal_p (stmt))
1727 instrument_nonnull_arg (&gsi);
1728 bb = gimple_bb (stmt);
1731 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1732 && gimple_code (stmt) == GIMPLE_RETURN)
1734 instrument_nonnull_return (&gsi);
1735 bb = gimple_bb (stmt);
1738 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
1740 if (gimple_store_p (stmt))
1741 instrument_object_size (&gsi, true);
1742 if (gimple_assign_load_p (stmt))
1743 instrument_object_size (&gsi, false);
1746 gsi_next (&gsi);
1749 return 0;
1752 } // anon namespace
1754 gimple_opt_pass *
1755 make_pass_ubsan (gcc::context *ctxt)
1757 return new pass_ubsan (ctxt);
1760 #include "gt-ubsan.h"