gcc/
[official-gcc.git] / gcc / ubsan.c
blob568f3c95ea087a15795fdea086b891f2492f000a
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"
71 /* Map from a tree to a VAR_DECL tree. */
73 struct GTY(()) tree_type_map {
74 struct tree_map_base type;
75 tree decl;
78 #define tree_type_map_eq tree_map_base_eq
79 #define tree_type_map_marked_p tree_map_base_marked_p
81 /* Hash from a tree in a tree_type_map. */
83 unsigned int
84 tree_type_map_hash (const void *item)
86 return TYPE_UID (((const struct tree_type_map *)item)->type.from);
89 static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map)))
90 htab_t decl_tree_for_type;
92 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
94 static tree
95 decl_for_type_lookup (tree type)
97 /* If the hash table is not initialized yet, create it now. */
98 if (decl_tree_for_type == NULL)
100 decl_tree_for_type = htab_create_ggc (10, tree_type_map_hash,
101 tree_type_map_eq, 0);
102 /* That also means we don't have to bother with the lookup. */
103 return NULL_TREE;
106 struct tree_type_map *h, in;
107 in.type.from = type;
109 h = (struct tree_type_map *)
110 htab_find_with_hash (decl_tree_for_type, &in, TYPE_UID (type));
111 return h ? h->decl : NULL_TREE;
114 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
116 static void
117 decl_for_type_insert (tree type, tree decl)
119 struct tree_type_map *h;
120 void **slot;
122 h = ggc_alloc<tree_type_map> ();
123 h->type.from = type;
124 h->decl = decl;
125 slot = htab_find_slot_with_hash (decl_tree_for_type, h, TYPE_UID (type),
126 INSERT);
127 *(struct tree_type_map **) slot = h;
130 /* Helper routine, which encodes a value in the pointer_sized_int_node.
131 Arguments with precision <= POINTER_SIZE are passed directly,
132 the rest is passed by reference. T is a value we are to encode.
133 IN_EXPAND_P is true if this function is called during expansion. */
135 tree
136 ubsan_encode_value (tree t, bool in_expand_p)
138 tree type = TREE_TYPE (t);
139 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
140 if (bitsize <= POINTER_SIZE)
141 switch (TREE_CODE (type))
143 case BOOLEAN_TYPE:
144 case ENUMERAL_TYPE:
145 case INTEGER_TYPE:
146 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
147 case REAL_TYPE:
149 tree itype = build_nonstandard_integer_type (bitsize, true);
150 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
151 return fold_convert (pointer_sized_int_node, t);
153 default:
154 gcc_unreachable ();
156 else
158 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
160 /* The reason for this is that we don't want to pessimize
161 code by making vars unnecessarily addressable. */
162 tree var = create_tmp_var (type, NULL);
163 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
164 if (in_expand_p)
166 rtx mem
167 = assign_stack_temp_for_type (TYPE_MODE (type),
168 GET_MODE_SIZE (TYPE_MODE (type)),
169 type);
170 SET_DECL_RTL (var, mem);
171 expand_assignment (var, t, false);
172 return build_fold_addr_expr (var);
174 t = build_fold_addr_expr (var);
175 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
177 else
178 return build_fold_addr_expr (t);
182 /* Build
183 struct __ubsan_type_descriptor
185 unsigned short __typekind;
186 unsigned short __typeinfo;
187 char __typename[];
189 type. */
191 static tree
192 ubsan_type_descriptor_type (void)
194 static const char *field_names[3]
195 = { "__typekind", "__typeinfo", "__typename" };
196 tree fields[3], ret;
197 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
198 tree flex_arr_type = build_array_type (char_type_node, itype);
200 ret = make_node (RECORD_TYPE);
201 for (int i = 0; i < 3; i++)
203 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
204 get_identifier (field_names[i]),
205 (i == 2) ? flex_arr_type
206 : short_unsigned_type_node);
207 DECL_CONTEXT (fields[i]) = ret;
208 if (i)
209 DECL_CHAIN (fields[i - 1]) = fields[i];
211 TYPE_FIELDS (ret) = fields[0];
212 TYPE_NAME (ret) = get_identifier ("__ubsan_type_descriptor");
213 layout_type (ret);
214 return ret;
217 /* Cached ubsan_get_source_location_type () return value. */
218 static GTY(()) tree ubsan_source_location_type;
220 /* Build
221 struct __ubsan_source_location
223 const char *__filename;
224 unsigned int __line;
225 unsigned int __column;
227 type. */
229 tree
230 ubsan_get_source_location_type (void)
232 static const char *field_names[3]
233 = { "__filename", "__line", "__column" };
234 tree fields[3], ret;
235 if (ubsan_source_location_type)
236 return ubsan_source_location_type;
238 tree const_char_type = build_qualified_type (char_type_node,
239 TYPE_QUAL_CONST);
241 ret = make_node (RECORD_TYPE);
242 for (int i = 0; i < 3; i++)
244 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
245 get_identifier (field_names[i]),
246 (i == 0) ? build_pointer_type (const_char_type)
247 : unsigned_type_node);
248 DECL_CONTEXT (fields[i]) = ret;
249 if (i)
250 DECL_CHAIN (fields[i - 1]) = fields[i];
252 TYPE_FIELDS (ret) = fields[0];
253 TYPE_NAME (ret) = get_identifier ("__ubsan_source_location");
254 layout_type (ret);
255 ubsan_source_location_type = ret;
256 return ret;
259 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
260 type with its fields filled from a location_t LOC. */
262 static tree
263 ubsan_source_location (location_t loc)
265 expanded_location xloc;
266 tree type = ubsan_get_source_location_type ();
268 xloc = expand_location (loc);
269 tree str;
270 if (xloc.file == NULL)
272 str = build_int_cst (ptr_type_node, 0);
273 xloc.line = 0;
274 xloc.column = 0;
276 else
278 /* Fill in the values from LOC. */
279 size_t len = strlen (xloc.file);
280 str = build_string (len + 1, xloc.file);
281 TREE_TYPE (str) = build_array_type (char_type_node,
282 build_index_type (size_int (len)));
283 TREE_READONLY (str) = 1;
284 TREE_STATIC (str) = 1;
285 str = build_fold_addr_expr (str);
287 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
288 build_int_cst (unsigned_type_node,
289 xloc.line), NULL_TREE,
290 build_int_cst (unsigned_type_node,
291 xloc.column));
292 TREE_CONSTANT (ctor) = 1;
293 TREE_STATIC (ctor) = 1;
295 return ctor;
298 /* This routine returns a magic number for TYPE. */
300 static unsigned short
301 get_ubsan_type_info_for_type (tree type)
303 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
304 if (TREE_CODE (type) == REAL_TYPE)
305 return tree_to_uhwi (TYPE_SIZE (type));
306 else if (INTEGRAL_TYPE_P (type))
308 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
309 gcc_assert (prec != -1);
310 return (prec << 1) | !TYPE_UNSIGNED (type);
312 else
313 return 0;
316 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
317 descriptor. It first looks into the hash table; if not found,
318 create the VAR_DECL, put it into the hash table and return the
319 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
320 an enum controlling how we want to print the type. */
322 tree
323 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
325 /* See through any typedefs. */
326 type = TYPE_MAIN_VARIANT (type);
328 tree decl = decl_for_type_lookup (type);
329 /* It is possible that some of the earlier created DECLs were found
330 unused, in that case they weren't emitted and varpool_node::get
331 returns NULL node on them. But now we really need them. Thus,
332 renew them here. */
333 if (decl != NULL_TREE && varpool_node::get (decl))
334 return build_fold_addr_expr (decl);
336 tree dtype = ubsan_type_descriptor_type ();
337 tree type2 = type;
338 const char *tname = NULL;
339 char *pretty_name;
340 unsigned char deref_depth = 0;
341 unsigned short tkind, tinfo;
343 /* Get the name of the type, or the name of the pointer type. */
344 if (pstyle == UBSAN_PRINT_POINTER)
346 gcc_assert (POINTER_TYPE_P (type));
347 type2 = TREE_TYPE (type);
349 /* Remove any '*' operators from TYPE. */
350 while (POINTER_TYPE_P (type2))
351 deref_depth++, type2 = TREE_TYPE (type2);
353 if (TREE_CODE (type2) == METHOD_TYPE)
354 type2 = TYPE_METHOD_BASETYPE (type2);
357 /* If an array, get its type. */
358 type2 = strip_array_types (type2);
360 if (pstyle == UBSAN_PRINT_ARRAY)
362 while (POINTER_TYPE_P (type2))
363 deref_depth++, type2 = TREE_TYPE (type2);
366 if (TYPE_NAME (type2) != NULL)
368 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
369 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
370 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
371 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
374 if (tname == NULL)
375 /* We weren't able to determine the type name. */
376 tname = "<unknown>";
378 /* Decorate the type name with '', '*', "struct", or "union". */
379 pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
380 if (pstyle == UBSAN_PRINT_POINTER)
382 int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
383 TYPE_VOLATILE (type2) ? "volatile " : "",
384 TYPE_READONLY (type2) ? "const " : "",
385 TYPE_RESTRICT (type2) ? "restrict " : "",
386 TYPE_ATOMIC (type2) ? "_Atomic " : "",
387 TREE_CODE (type2) == RECORD_TYPE
388 ? "struct "
389 : TREE_CODE (type2) == UNION_TYPE
390 ? "union " : "", tname,
391 deref_depth == 0 ? "" : " ");
392 while (deref_depth-- > 0)
393 pretty_name[pos++] = '*';
394 pretty_name[pos++] = '\'';
395 pretty_name[pos] = '\0';
397 else if (pstyle == UBSAN_PRINT_ARRAY)
399 /* Pretty print the array dimensions. */
400 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
401 tree t = type;
402 int pos = sprintf (pretty_name, "'%s ", tname);
403 while (deref_depth-- > 0)
404 pretty_name[pos++] = '*';
405 while (TREE_CODE (t) == ARRAY_TYPE)
407 pretty_name[pos++] = '[';
408 tree dom = TYPE_DOMAIN (t);
409 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
410 pos += sprintf (&pretty_name[pos], HOST_WIDE_INT_PRINT_DEC,
411 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
412 else
413 /* ??? We can't determine the variable name; print VLA unspec. */
414 pretty_name[pos++] = '*';
415 pretty_name[pos++] = ']';
416 t = TREE_TYPE (t);
418 pretty_name[pos++] = '\'';
419 pretty_name[pos] = '\0';
421 /* Save the tree with stripped types. */
422 type = t;
424 else
425 sprintf (pretty_name, "'%s'", tname);
427 switch (TREE_CODE (type))
429 case BOOLEAN_TYPE:
430 case ENUMERAL_TYPE:
431 case INTEGER_TYPE:
432 tkind = 0x0000;
433 break;
434 case REAL_TYPE:
435 /* FIXME: libubsan right now only supports float, double and
436 long double type formats. */
437 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
438 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
439 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
440 tkind = 0x0001;
441 else
442 tkind = 0xffff;
443 break;
444 default:
445 tkind = 0xffff;
446 break;
448 tinfo = get_ubsan_type_info_for_type (type);
450 /* Create a new VAR_DECL of type descriptor. */
451 char tmp_name[32];
452 static unsigned int type_var_id_num;
453 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
454 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
455 dtype);
456 TREE_STATIC (decl) = 1;
457 TREE_PUBLIC (decl) = 0;
458 DECL_ARTIFICIAL (decl) = 1;
459 DECL_IGNORED_P (decl) = 1;
460 DECL_EXTERNAL (decl) = 0;
462 size_t len = strlen (pretty_name);
463 tree str = build_string (len + 1, pretty_name);
464 TREE_TYPE (str) = build_array_type (char_type_node,
465 build_index_type (size_int (len)));
466 TREE_READONLY (str) = 1;
467 TREE_STATIC (str) = 1;
468 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
469 build_int_cst (short_unsigned_type_node,
470 tkind), NULL_TREE,
471 build_int_cst (short_unsigned_type_node,
472 tinfo), NULL_TREE, str);
473 TREE_CONSTANT (ctor) = 1;
474 TREE_STATIC (ctor) = 1;
475 DECL_INITIAL (decl) = ctor;
476 varpool_node::finalize_decl (decl);
478 /* Save the VAR_DECL into the hash table. */
479 decl_for_type_insert (type, decl);
481 return build_fold_addr_expr (decl);
484 /* Create a structure for the ubsan library. NAME is a name of the new
485 structure. LOCCNT is number of locations, PLOC points to array of
486 locations. The arguments in ... are of __ubsan_type_descriptor type
487 and there are at most two of them, followed by NULL_TREE, followed
488 by optional extra arguments and another NULL_TREE. */
490 tree
491 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
493 va_list args;
494 tree ret, t;
495 tree fields[6];
496 vec<tree, va_gc> *saved_args = NULL;
497 size_t i = 0;
498 int j;
500 /* Firstly, create a pointer to type descriptor type. */
501 tree td_type = ubsan_type_descriptor_type ();
502 TYPE_READONLY (td_type) = 1;
503 td_type = build_pointer_type (td_type);
505 /* Create the structure type. */
506 ret = make_node (RECORD_TYPE);
507 for (j = 0; j < loccnt; j++)
509 gcc_checking_assert (i < 2);
510 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
511 ubsan_get_source_location_type ());
512 DECL_CONTEXT (fields[i]) = ret;
513 if (i)
514 DECL_CHAIN (fields[i - 1]) = fields[i];
515 i++;
518 va_start (args, ploc);
519 for (t = va_arg (args, tree); t != NULL_TREE;
520 i++, t = va_arg (args, tree))
522 gcc_checking_assert (i < 4);
523 /* Save the tree arguments for later use. */
524 vec_safe_push (saved_args, t);
525 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
526 td_type);
527 DECL_CONTEXT (fields[i]) = ret;
528 if (i)
529 DECL_CHAIN (fields[i - 1]) = fields[i];
532 for (t = va_arg (args, tree); t != NULL_TREE;
533 i++, t = va_arg (args, tree))
535 gcc_checking_assert (i < 6);
536 /* Save the tree arguments for later use. */
537 vec_safe_push (saved_args, t);
538 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
539 TREE_TYPE (t));
540 DECL_CONTEXT (fields[i]) = ret;
541 if (i)
542 DECL_CHAIN (fields[i - 1]) = fields[i];
544 va_end (args);
546 TYPE_FIELDS (ret) = fields[0];
547 TYPE_NAME (ret) = get_identifier (name);
548 layout_type (ret);
550 /* Now, fill in the type. */
551 char tmp_name[32];
552 static unsigned int ubsan_var_id_num;
553 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
554 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
555 ret);
556 TREE_STATIC (var) = 1;
557 TREE_PUBLIC (var) = 0;
558 DECL_ARTIFICIAL (var) = 1;
559 DECL_IGNORED_P (var) = 1;
560 DECL_EXTERNAL (var) = 0;
562 vec<constructor_elt, va_gc> *v;
563 vec_alloc (v, i);
564 tree ctor = build_constructor (ret, v);
566 /* If desirable, set the __ubsan_source_location element. */
567 for (j = 0; j < loccnt; j++)
569 location_t loc = LOCATION_LOCUS (ploc[j]);
570 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
573 size_t nelts = vec_safe_length (saved_args);
574 for (i = 0; i < nelts; i++)
576 t = (*saved_args)[i];
577 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
580 TREE_CONSTANT (ctor) = 1;
581 TREE_STATIC (ctor) = 1;
582 DECL_INITIAL (var) = ctor;
583 varpool_node::finalize_decl (var);
585 return var;
588 /* Instrument the __builtin_unreachable call. We just call the libubsan
589 routine instead. */
591 tree
592 ubsan_instrument_unreachable (location_t loc)
594 if (flag_sanitize_undefined_trap_on_error)
595 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
597 initialize_sanitizer_builtins ();
598 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc, NULL_TREE,
599 NULL_TREE);
600 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
601 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
604 /* Return true if T is a call to a libubsan routine. */
606 bool
607 is_ubsan_builtin_p (tree t)
609 return TREE_CODE (t) == FUNCTION_DECL
610 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
611 "__builtin___ubsan_", 18) == 0;
614 /* Expand the UBSAN_BOUNDS special builtin function. */
616 bool
617 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
619 gimple stmt = gsi_stmt (*gsi);
620 location_t loc = gimple_location (stmt);
621 gcc_assert (gimple_call_num_args (stmt) == 3);
623 /* Pick up the arguments of the UBSAN_BOUNDS call. */
624 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
625 tree index = gimple_call_arg (stmt, 1);
626 tree orig_index_type = TREE_TYPE (index);
627 tree bound = gimple_call_arg (stmt, 2);
629 gimple_stmt_iterator gsi_orig = *gsi;
631 /* Create condition "if (index > bound)". */
632 basic_block then_bb, fallthru_bb;
633 gimple_stmt_iterator cond_insert_point
634 = create_cond_insert_point (gsi, false, false, true,
635 &then_bb, &fallthru_bb);
636 index = fold_convert (TREE_TYPE (bound), index);
637 index = force_gimple_operand_gsi (&cond_insert_point, index,
638 true, NULL_TREE,
639 false, GSI_NEW_STMT);
640 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
641 gimple_set_location (g, loc);
642 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
644 /* Generate __ubsan_handle_out_of_bounds call. */
645 *gsi = gsi_after_labels (then_bb);
646 if (flag_sanitize_undefined_trap_on_error)
647 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
648 else
650 tree data
651 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
652 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
653 ubsan_type_descriptor (orig_index_type),
654 NULL_TREE, NULL_TREE);
655 data = build_fold_addr_expr_loc (loc, data);
656 enum built_in_function bcode
657 = (flag_sanitize_recover & SANITIZE_BOUNDS)
658 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
659 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
660 tree fn = builtin_decl_explicit (bcode);
661 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
662 true, NULL_TREE, true,
663 GSI_SAME_STMT);
664 g = gimple_build_call (fn, 2, data, val);
666 gimple_set_location (g, loc);
667 gsi_insert_before (gsi, g, GSI_SAME_STMT);
669 /* Get rid of the UBSAN_BOUNDS call from the IR. */
670 unlink_stmt_vdef (stmt);
671 gsi_remove (&gsi_orig, true);
673 /* Point GSI to next logical statement. */
674 *gsi = gsi_start_bb (fallthru_bb);
675 return true;
678 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
679 argument which is a constant, because the middle-end treats pointer
680 conversions as useless and therefore the type of the first argument
681 could be changed to any other pointer type. */
683 bool
684 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
686 gimple_stmt_iterator gsi = *gsip;
687 gimple stmt = gsi_stmt (gsi);
688 location_t loc = gimple_location (stmt);
689 gcc_assert (gimple_call_num_args (stmt) == 3);
690 tree ptr = gimple_call_arg (stmt, 0);
691 tree ckind = gimple_call_arg (stmt, 1);
692 tree align = gimple_call_arg (stmt, 2);
693 tree check_align = NULL_TREE;
694 bool check_null;
696 basic_block cur_bb = gsi_bb (gsi);
698 gimple g;
699 if (!integer_zerop (align))
701 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
702 if (compare_tree_int (align, ptralign) == 1)
704 check_align = make_ssa_name (pointer_sized_int_node, NULL);
705 g = gimple_build_assign_with_ops (NOP_EXPR, check_align,
706 ptr, NULL_TREE);
707 gimple_set_location (g, loc);
708 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
711 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
713 if (check_align == NULL_TREE && !check_null)
715 gsi_remove (gsip, true);
716 /* Unlink the UBSAN_NULLs vops before replacing it. */
717 unlink_stmt_vdef (stmt);
718 return true;
721 /* Split the original block holding the pointer dereference. */
722 edge e = split_block (cur_bb, stmt);
724 /* Get a hold on the 'condition block', the 'then block' and the
725 'else block'. */
726 basic_block cond_bb = e->src;
727 basic_block fallthru_bb = e->dest;
728 basic_block then_bb = create_empty_bb (cond_bb);
729 add_bb_to_loop (then_bb, cond_bb->loop_father);
730 loops_state_set (LOOPS_NEED_FIXUP);
732 /* Make an edge coming from the 'cond block' into the 'then block';
733 this edge is unlikely taken, so set up the probability accordingly. */
734 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
735 e->probability = PROB_VERY_UNLIKELY;
737 /* Connect 'then block' with the 'else block'. This is needed
738 as the ubsan routines we call in the 'then block' are not noreturn.
739 The 'then block' only has one outcoming edge. */
740 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
742 /* Set up the fallthrough basic block. */
743 e = find_edge (cond_bb, fallthru_bb);
744 e->flags = EDGE_FALSE_VALUE;
745 e->count = cond_bb->count;
746 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
748 /* Update dominance info for the newly created then_bb; note that
749 fallthru_bb's dominance info has already been updated by
750 split_block. */
751 if (dom_info_available_p (CDI_DOMINATORS))
752 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
754 /* Put the ubsan builtin call into the newly created BB. */
755 if (flag_sanitize_undefined_trap_on_error)
756 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
757 else
759 enum built_in_function bcode
760 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
761 | (check_null ? SANITIZE_NULL : 0)))
762 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
763 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
764 tree fn = builtin_decl_implicit (bcode);
765 tree data
766 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
767 ubsan_type_descriptor (TREE_TYPE (ckind),
768 UBSAN_PRINT_POINTER),
769 NULL_TREE,
770 align,
771 fold_convert (unsigned_char_type_node, ckind),
772 NULL_TREE);
773 data = build_fold_addr_expr_loc (loc, data);
774 g = gimple_build_call (fn, 2, data,
775 check_align ? check_align
776 : build_zero_cst (pointer_sized_int_node));
778 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
779 gimple_set_location (g, loc);
780 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
782 /* Unlink the UBSAN_NULLs vops before replacing it. */
783 unlink_stmt_vdef (stmt);
785 if (check_null)
787 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
788 NULL_TREE, NULL_TREE);
789 gimple_set_location (g, loc);
791 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
792 gsi_replace (&gsi, g, false);
795 if (check_align)
797 if (check_null)
799 /* Split the block with the condition again. */
800 e = split_block (cond_bb, stmt);
801 basic_block cond1_bb = e->src;
802 basic_block cond2_bb = e->dest;
804 /* Make an edge coming from the 'cond1 block' into the 'then block';
805 this edge is unlikely taken, so set up the probability
806 accordingly. */
807 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
808 e->probability = PROB_VERY_UNLIKELY;
810 /* Set up the fallthrough basic block. */
811 e = find_edge (cond1_bb, cond2_bb);
812 e->flags = EDGE_FALSE_VALUE;
813 e->count = cond1_bb->count;
814 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
816 /* Update dominance info. */
817 if (dom_info_available_p (CDI_DOMINATORS))
819 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
820 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
823 gsi2 = gsi_start_bb (cond2_bb);
826 tree mask = build_int_cst (pointer_sized_int_node,
827 tree_to_uhwi (align) - 1);
828 g = gimple_build_assign_with_ops (BIT_AND_EXPR,
829 make_ssa_name (pointer_sized_int_node,
830 NULL),
831 check_align, mask);
832 gimple_set_location (g, loc);
833 if (check_null)
834 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
835 else
836 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
838 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
839 build_int_cst (pointer_sized_int_node, 0),
840 NULL_TREE, NULL_TREE);
841 gimple_set_location (g, loc);
842 if (check_null)
843 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
844 else
845 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
846 gsi_replace (&gsi, g, false);
848 return false;
851 /* Expand UBSAN_OBJECT_SIZE internal call. */
853 bool
854 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
856 gimple stmt = gsi_stmt (*gsi);
857 location_t loc = gimple_location (stmt);
858 gcc_assert (gimple_call_num_args (stmt) == 4);
860 tree ptr = gimple_call_arg (stmt, 0);
861 tree offset = gimple_call_arg (stmt, 1);
862 tree size = gimple_call_arg (stmt, 2);
863 tree ckind = gimple_call_arg (stmt, 3);
864 gimple_stmt_iterator gsi_orig = *gsi;
865 gimple g;
867 /* See if we can discard the check. */
868 if (TREE_CODE (size) != INTEGER_CST
869 || integer_all_onesp (size))
870 /* Yes, __builtin_object_size couldn't determine the
871 object size. */;
872 else
874 /* if (offset > objsize) */
875 basic_block then_bb, fallthru_bb;
876 gimple_stmt_iterator cond_insert_point
877 = create_cond_insert_point (gsi, false, false, true,
878 &then_bb, &fallthru_bb);
879 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
880 gimple_set_location (g, loc);
881 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
883 /* Generate __ubsan_handle_type_mismatch call. */
884 *gsi = gsi_after_labels (then_bb);
885 if (flag_sanitize_undefined_trap_on_error)
886 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
887 else
889 tree data
890 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
891 ubsan_type_descriptor (TREE_TYPE (ptr),
892 UBSAN_PRINT_POINTER),
893 NULL_TREE,
894 build_zero_cst (pointer_sized_int_node),
895 ckind,
896 NULL_TREE);
897 data = build_fold_addr_expr_loc (loc, data);
898 enum built_in_function bcode
899 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
900 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
901 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
902 tree p = make_ssa_name (pointer_sized_int_node, NULL);
903 g = gimple_build_assign_with_ops (NOP_EXPR, p, ptr, NULL_TREE);
904 gimple_set_location (g, loc);
905 gsi_insert_before (gsi, g, GSI_SAME_STMT);
906 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
908 gimple_set_location (g, loc);
909 gsi_insert_before (gsi, g, GSI_SAME_STMT);
911 /* Point GSI to next logical statement. */
912 *gsi = gsi_start_bb (fallthru_bb);
915 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
916 unlink_stmt_vdef (stmt);
917 gsi_remove (&gsi_orig, true);
918 return gsi_end_p (*gsi);
921 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
922 whether the pointer is on the left hand side of the assignment. */
924 static void
925 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
926 bool is_lhs)
928 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
929 unsigned int align = 0;
930 if (flag_sanitize & SANITIZE_ALIGNMENT)
932 align = min_align_of_type (TREE_TYPE (base));
933 if (align <= 1)
934 align = 0;
936 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
937 return;
938 tree t = TREE_OPERAND (base, 0);
939 if (!POINTER_TYPE_P (TREE_TYPE (t)))
940 return;
941 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && mem != base)
942 ikind = UBSAN_MEMBER_ACCESS;
943 tree kind = build_int_cst (TREE_TYPE (t), ikind);
944 tree alignt = build_int_cst (pointer_sized_int_node, align);
945 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
946 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
947 gsi_insert_before (iter, g, GSI_SAME_STMT);
950 /* Perform the pointer instrumentation. */
952 static void
953 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
955 gimple stmt = gsi_stmt (gsi);
956 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
957 tree base = get_base_address (t);
958 const enum tree_code code = TREE_CODE (base);
959 if (code == MEM_REF
960 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
961 instrument_mem_ref (t, base, &gsi, is_lhs);
964 /* Build an ubsan builtin call for the signed-integer-overflow
965 sanitization. CODE says what kind of builtin are we building,
966 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
967 are operands of the binary operation. */
969 tree
970 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
971 tree op0, tree op1)
973 if (flag_sanitize_undefined_trap_on_error)
974 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
976 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
977 ubsan_type_descriptor (lhstype), NULL_TREE,
978 NULL_TREE);
979 enum built_in_function fn_code;
981 switch (code)
983 case PLUS_EXPR:
984 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
985 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
986 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
987 break;
988 case MINUS_EXPR:
989 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
990 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
991 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
992 break;
993 case MULT_EXPR:
994 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
995 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
996 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
997 break;
998 case NEGATE_EXPR:
999 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1000 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1001 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1002 break;
1003 default:
1004 gcc_unreachable ();
1006 tree fn = builtin_decl_explicit (fn_code);
1007 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1008 build_fold_addr_expr_loc (loc, data),
1009 ubsan_encode_value (op0, true),
1010 op1 ? ubsan_encode_value (op1, true)
1011 : NULL_TREE);
1014 /* Perform the signed integer instrumentation. GSI is the iterator
1015 pointing at statement we are trying to instrument. */
1017 static void
1018 instrument_si_overflow (gimple_stmt_iterator gsi)
1020 gimple stmt = gsi_stmt (gsi);
1021 tree_code code = gimple_assign_rhs_code (stmt);
1022 tree lhs = gimple_assign_lhs (stmt);
1023 tree lhstype = TREE_TYPE (lhs);
1024 tree a, b;
1025 gimple g;
1027 /* If this is not a signed operation, don't instrument anything here.
1028 Also punt on bit-fields. */
1029 if (!INTEGRAL_TYPE_P (lhstype)
1030 || TYPE_OVERFLOW_WRAPS (lhstype)
1031 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1032 return;
1034 switch (code)
1036 case MINUS_EXPR:
1037 case PLUS_EXPR:
1038 case MULT_EXPR:
1039 /* Transform
1040 i = u {+,-,*} 5;
1041 into
1042 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1043 a = gimple_assign_rhs1 (stmt);
1044 b = gimple_assign_rhs2 (stmt);
1045 g = gimple_build_call_internal (code == PLUS_EXPR
1046 ? IFN_UBSAN_CHECK_ADD
1047 : code == MINUS_EXPR
1048 ? IFN_UBSAN_CHECK_SUB
1049 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1050 gimple_call_set_lhs (g, lhs);
1051 gsi_replace (&gsi, g, false);
1052 break;
1053 case NEGATE_EXPR:
1054 /* Represent i = -u;
1056 i = UBSAN_CHECK_SUB (0, u); */
1057 a = build_int_cst (lhstype, 0);
1058 b = gimple_assign_rhs1 (stmt);
1059 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1060 gimple_call_set_lhs (g, lhs);
1061 gsi_replace (&gsi, g, false);
1062 break;
1063 case ABS_EXPR:
1064 /* Transform i = ABS_EXPR<u>;
1065 into
1066 _N = UBSAN_CHECK_SUB (0, u);
1067 i = ABS_EXPR<_N>; */
1068 a = build_int_cst (lhstype, 0);
1069 b = gimple_assign_rhs1 (stmt);
1070 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1071 a = make_ssa_name (lhstype, NULL);
1072 gimple_call_set_lhs (g, a);
1073 gimple_set_location (g, gimple_location (stmt));
1074 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1075 gimple_assign_set_rhs1 (stmt, a);
1076 update_stmt (stmt);
1077 break;
1078 default:
1079 break;
1083 /* Instrument loads from (non-bitfield) bool and C++ enum values
1084 to check if the memory value is outside of the range of the valid
1085 type values. */
1087 static void
1088 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1090 gimple stmt = gsi_stmt (*gsi);
1091 tree rhs = gimple_assign_rhs1 (stmt);
1092 tree type = TREE_TYPE (rhs);
1093 tree minv = NULL_TREE, maxv = NULL_TREE;
1095 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1097 minv = boolean_false_node;
1098 maxv = boolean_true_node;
1100 else if (TREE_CODE (type) == ENUMERAL_TYPE
1101 && (flag_sanitize & SANITIZE_ENUM)
1102 && TREE_TYPE (type) != NULL_TREE
1103 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1104 && (TYPE_PRECISION (TREE_TYPE (type))
1105 < GET_MODE_PRECISION (TYPE_MODE (type))))
1107 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1108 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1110 else
1111 return;
1113 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1114 HOST_WIDE_INT bitsize, bitpos;
1115 tree offset;
1116 enum machine_mode mode;
1117 int volatilep = 0, unsignedp = 0;
1118 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1119 &unsignedp, &volatilep, false);
1120 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1122 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1123 || (bitpos % modebitsize) != 0
1124 || bitsize != modebitsize
1125 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1126 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1127 return;
1129 location_t loc = gimple_location (stmt);
1130 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1131 tree atype = reference_alias_ptr_type (rhs);
1132 gimple g = gimple_build_assign (make_ssa_name (ptype, NULL),
1133 build_fold_addr_expr (rhs));
1134 gimple_set_location (g, loc);
1135 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1136 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1137 build_int_cst (atype, 0));
1138 tree urhs = make_ssa_name (utype, NULL);
1139 g = gimple_build_assign (urhs, mem);
1140 gimple_set_location (g, loc);
1141 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1142 minv = fold_convert (utype, minv);
1143 maxv = fold_convert (utype, maxv);
1144 if (!integer_zerop (minv))
1146 g = gimple_build_assign_with_ops (MINUS_EXPR,
1147 make_ssa_name (utype, NULL),
1148 urhs, minv);
1149 gimple_set_location (g, loc);
1150 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1153 gimple_stmt_iterator gsi2 = *gsi;
1154 basic_block then_bb, fallthru_bb;
1155 *gsi = create_cond_insert_point (gsi, true, false, true,
1156 &then_bb, &fallthru_bb);
1157 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1158 int_const_binop (MINUS_EXPR, maxv, minv),
1159 NULL_TREE, NULL_TREE);
1160 gimple_set_location (g, loc);
1161 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1163 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
1164 update_stmt (stmt);
1166 gsi2 = gsi_after_labels (then_bb);
1167 if (flag_sanitize_undefined_trap_on_error)
1168 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1169 else
1171 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1172 ubsan_type_descriptor (type), NULL_TREE,
1173 NULL_TREE);
1174 data = build_fold_addr_expr_loc (loc, data);
1175 enum built_in_function bcode
1176 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1177 ? SANITIZE_BOOL : SANITIZE_ENUM))
1178 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1179 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1180 tree fn = builtin_decl_explicit (bcode);
1182 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1183 true, NULL_TREE, true,
1184 GSI_SAME_STMT);
1185 g = gimple_build_call (fn, 2, data, val);
1187 gimple_set_location (g, loc);
1188 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1189 *gsi = gsi_for_stmt (stmt);
1192 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1193 destination, EXPR is floating-point expression. */
1195 tree
1196 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1198 tree expr_type = TREE_TYPE (expr);
1199 tree t, tt, fn, min, max;
1200 enum machine_mode mode = TYPE_MODE (expr_type);
1201 int prec = TYPE_PRECISION (type);
1202 bool uns_p = TYPE_UNSIGNED (type);
1204 /* Float to integer conversion first truncates toward zero, so
1205 even signed char c = 127.875f; is not problematic.
1206 Therefore, we should complain only if EXPR is unordered or smaller
1207 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1208 TYPE_MAX_VALUE + 1.0. */
1209 if (REAL_MODE_FORMAT (mode)->b == 2)
1211 /* For maximum, TYPE_MAX_VALUE might not be representable
1212 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1213 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1214 either representable or infinity. */
1215 REAL_VALUE_TYPE maxval = dconst1;
1216 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1217 real_convert (&maxval, mode, &maxval);
1218 max = build_real (expr_type, maxval);
1220 /* For unsigned, assume -1.0 is always representable. */
1221 if (uns_p)
1222 min = build_minus_one_cst (expr_type);
1223 else
1225 /* TYPE_MIN_VALUE is generally representable (or -inf),
1226 but TYPE_MIN_VALUE - 1.0 might not be. */
1227 REAL_VALUE_TYPE minval = dconstm1, minval2;
1228 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1229 real_convert (&minval, mode, &minval);
1230 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1231 real_convert (&minval2, mode, &minval2);
1232 if (real_compare (EQ_EXPR, &minval, &minval2)
1233 && !real_isinf (&minval))
1235 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1236 rounds to TYPE_MIN_VALUE, we need to subtract
1237 more. As REAL_MODE_FORMAT (mode)->p is the number
1238 of base digits, we want to subtract a number that
1239 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1240 times smaller than minval. */
1241 minval2 = dconst1;
1242 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1243 SET_REAL_EXP (&minval2,
1244 REAL_EXP (&minval2) + prec - 1
1245 - REAL_MODE_FORMAT (mode)->p + 1);
1246 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1247 real_convert (&minval2, mode, &minval2);
1249 min = build_real (expr_type, minval2);
1252 else if (REAL_MODE_FORMAT (mode)->b == 10)
1254 /* For _Decimal128 up to 34 decimal digits, - sign,
1255 dot, e, exponent. */
1256 char buf[64];
1257 mpfr_t m;
1258 int p = REAL_MODE_FORMAT (mode)->p;
1259 REAL_VALUE_TYPE maxval, minval;
1261 /* Use mpfr_snprintf rounding to compute the smallest
1262 representable decimal number greater or equal than
1263 1 << (prec - !uns_p). */
1264 mpfr_init2 (m, prec + 2);
1265 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1266 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1267 decimal_real_from_string (&maxval, buf);
1268 max = build_real (expr_type, maxval);
1270 /* For unsigned, assume -1.0 is always representable. */
1271 if (uns_p)
1272 min = build_minus_one_cst (expr_type);
1273 else
1275 /* Use mpfr_snprintf rounding to compute the largest
1276 representable decimal number less or equal than
1277 (-1 << (prec - 1)) - 1. */
1278 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1279 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1280 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1281 decimal_real_from_string (&minval, buf);
1282 min = build_real (expr_type, minval);
1284 mpfr_clear (m);
1286 else
1287 return NULL_TREE;
1289 if (flag_sanitize_undefined_trap_on_error)
1290 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1291 else
1293 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1294 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1295 NULL, ubsan_type_descriptor (expr_type),
1296 ubsan_type_descriptor (type), NULL_TREE,
1297 NULL_TREE);
1298 enum built_in_function bcode
1299 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1300 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1301 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1302 fn = builtin_decl_explicit (bcode);
1303 fn = build_call_expr_loc (loc, fn, 2,
1304 build_fold_addr_expr_loc (loc, data),
1305 ubsan_encode_value (expr, false));
1308 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1309 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1310 return fold_build3 (COND_EXPR, void_type_node,
1311 fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt),
1312 fn, integer_zero_node);
1315 /* Instrument values passed to function arguments with nonnull attribute. */
1317 static void
1318 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1320 gimple stmt = gsi_stmt (*gsi);
1321 location_t loc[2];
1322 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1323 while for nonnull sanitization it is clear. */
1324 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1325 flag_delete_null_pointer_checks = 1;
1326 loc[0] = gimple_location (stmt);
1327 loc[1] = UNKNOWN_LOCATION;
1328 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1330 tree arg = gimple_call_arg (stmt, i);
1331 if (POINTER_TYPE_P (TREE_TYPE (arg))
1332 && infer_nonnull_range (stmt, arg, false, true))
1334 gimple g;
1335 if (!is_gimple_val (arg))
1337 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg), NULL),
1338 arg);
1339 gimple_set_location (g, loc[0]);
1340 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1341 arg = gimple_assign_lhs (g);
1344 basic_block then_bb, fallthru_bb;
1345 *gsi = create_cond_insert_point (gsi, true, false, true,
1346 &then_bb, &fallthru_bb);
1347 g = gimple_build_cond (EQ_EXPR, arg,
1348 build_zero_cst (TREE_TYPE (arg)),
1349 NULL_TREE, NULL_TREE);
1350 gimple_set_location (g, loc[0]);
1351 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1353 *gsi = gsi_after_labels (then_bb);
1354 if (flag_sanitize_undefined_trap_on_error)
1355 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1356 else
1358 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1359 2, loc, NULL_TREE,
1360 build_int_cst (integer_type_node,
1361 i + 1),
1362 NULL_TREE);
1363 data = build_fold_addr_expr_loc (loc[0], data);
1364 enum built_in_function bcode
1365 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1366 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1367 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1368 tree fn = builtin_decl_explicit (bcode);
1370 g = gimple_build_call (fn, 1, data);
1372 gimple_set_location (g, loc[0]);
1373 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1375 *gsi = gsi_for_stmt (stmt);
1377 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1380 /* Instrument returns in functions with returns_nonnull attribute. */
1382 static void
1383 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1385 gimple stmt = gsi_stmt (*gsi);
1386 location_t loc[2];
1387 tree arg = gimple_return_retval (stmt);
1388 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1389 while for nonnull return sanitization it is clear. */
1390 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1391 flag_delete_null_pointer_checks = 1;
1392 loc[0] = gimple_location (stmt);
1393 loc[1] = UNKNOWN_LOCATION;
1394 if (arg
1395 && POINTER_TYPE_P (TREE_TYPE (arg))
1396 && is_gimple_val (arg)
1397 && infer_nonnull_range (stmt, arg, false, true))
1399 basic_block then_bb, fallthru_bb;
1400 *gsi = create_cond_insert_point (gsi, true, false, true,
1401 &then_bb, &fallthru_bb);
1402 gimple g = gimple_build_cond (EQ_EXPR, arg,
1403 build_zero_cst (TREE_TYPE (arg)),
1404 NULL_TREE, NULL_TREE);
1405 gimple_set_location (g, loc[0]);
1406 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1408 *gsi = gsi_after_labels (then_bb);
1409 if (flag_sanitize_undefined_trap_on_error)
1410 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1411 else
1413 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1414 2, loc, NULL_TREE, NULL_TREE);
1415 data = build_fold_addr_expr_loc (loc[0], data);
1416 enum built_in_function bcode
1417 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1418 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1419 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1420 tree fn = builtin_decl_explicit (bcode);
1422 g = gimple_build_call (fn, 1, data);
1424 gimple_set_location (g, loc[0]);
1425 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1426 *gsi = gsi_for_stmt (stmt);
1428 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1431 /* Instrument memory references. Here we check whether the pointer
1432 points to an out-of-bounds location. */
1434 static void
1435 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1437 gimple stmt = gsi_stmt (*gsi);
1438 location_t loc = gimple_location (stmt);
1439 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1440 tree type;
1441 HOST_WIDE_INT size_in_bytes;
1443 type = TREE_TYPE (t);
1444 if (VOID_TYPE_P (type))
1445 return;
1447 switch (TREE_CODE (t))
1449 case COMPONENT_REF:
1450 if (TREE_CODE (t) == COMPONENT_REF
1451 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1453 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1454 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1455 repr, NULL_TREE);
1457 break;
1458 case ARRAY_REF:
1459 case INDIRECT_REF:
1460 case MEM_REF:
1461 case VAR_DECL:
1462 case PARM_DECL:
1463 case RESULT_DECL:
1464 break;
1465 default:
1466 return;
1469 size_in_bytes = int_size_in_bytes (type);
1470 if (size_in_bytes <= 0)
1471 return;
1473 HOST_WIDE_INT bitsize, bitpos;
1474 tree offset;
1475 enum machine_mode mode;
1476 int volatilep = 0, unsignedp = 0;
1477 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1478 &unsignedp, &volatilep, false);
1480 if (bitpos % BITS_PER_UNIT != 0
1481 || bitsize != size_in_bytes * BITS_PER_UNIT)
1482 return;
1484 bool decl_p = DECL_P (inner);
1485 tree base = decl_p ? inner : TREE_OPERAND (inner, 0);
1486 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1488 while (TREE_CODE (base) == SSA_NAME)
1490 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1491 if (gimple_assign_ssa_name_copy_p (def_stmt)
1492 || (gimple_assign_cast_p (def_stmt)
1493 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1494 || (is_gimple_assign (def_stmt)
1495 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1496 base = gimple_assign_rhs1 (def_stmt);
1497 else
1498 break;
1501 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1502 return;
1504 tree sizet;
1505 tree base_addr = base;
1506 if (decl_p)
1507 base_addr = build1 (ADDR_EXPR,
1508 build_pointer_type (TREE_TYPE (base)), base);
1509 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1510 if (size != (unsigned HOST_WIDE_INT) -1)
1511 sizet = build_int_cst (sizetype, size);
1512 else if (optimize)
1514 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1515 loc = input_location;
1516 /* Generate __builtin_object_size call. */
1517 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1518 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1519 integer_zero_node);
1520 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1521 GSI_SAME_STMT);
1523 else
1524 return;
1526 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1527 call. */
1528 /* ptr + sizeof (*ptr) - base */
1529 t = fold_build2 (MINUS_EXPR, sizetype,
1530 fold_convert (pointer_sized_int_node, ptr),
1531 fold_convert (pointer_sized_int_node, base_addr));
1532 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1534 /* Perhaps we can omit the check. */
1535 if (TREE_CODE (t) == INTEGER_CST
1536 && TREE_CODE (sizet) == INTEGER_CST
1537 && tree_int_cst_le (t, sizet))
1538 return;
1540 /* Nope. Emit the check. */
1541 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1542 GSI_SAME_STMT);
1543 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1544 GSI_SAME_STMT);
1545 tree ckind = build_int_cst (unsigned_char_type_node,
1546 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1547 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1548 ptr, t, sizet, ckind);
1549 gimple_set_location (g, loc);
1550 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1553 namespace {
1555 const pass_data pass_data_ubsan =
1557 GIMPLE_PASS, /* type */
1558 "ubsan", /* name */
1559 OPTGROUP_NONE, /* optinfo_flags */
1560 TV_TREE_UBSAN, /* tv_id */
1561 ( PROP_cfg | PROP_ssa ), /* properties_required */
1562 0, /* properties_provided */
1563 0, /* properties_destroyed */
1564 0, /* todo_flags_start */
1565 TODO_update_ssa, /* todo_flags_finish */
1568 class pass_ubsan : public gimple_opt_pass
1570 public:
1571 pass_ubsan (gcc::context *ctxt)
1572 : gimple_opt_pass (pass_data_ubsan, ctxt)
1575 /* opt_pass methods: */
1576 virtual bool gate (function *)
1578 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1579 | SANITIZE_BOOL | SANITIZE_ENUM
1580 | SANITIZE_ALIGNMENT
1581 | SANITIZE_NONNULL_ATTRIBUTE
1582 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1583 | SANITIZE_OBJECT_SIZE)
1584 && current_function_decl != NULL_TREE
1585 && !lookup_attribute ("no_sanitize_undefined",
1586 DECL_ATTRIBUTES (current_function_decl));
1589 virtual unsigned int execute (function *);
1591 }; // class pass_ubsan
1593 unsigned int
1594 pass_ubsan::execute (function *fun)
1596 basic_block bb;
1597 gimple_stmt_iterator gsi;
1599 initialize_sanitizer_builtins ();
1601 FOR_EACH_BB_FN (bb, fun)
1603 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1605 gimple stmt = gsi_stmt (gsi);
1606 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1608 gsi_next (&gsi);
1609 continue;
1612 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1613 && is_gimple_assign (stmt))
1614 instrument_si_overflow (gsi);
1616 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1618 if (gimple_store_p (stmt))
1619 instrument_null (gsi, true);
1620 if (gimple_assign_load_p (stmt))
1621 instrument_null (gsi, false);
1624 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1625 && gimple_assign_load_p (stmt))
1627 instrument_bool_enum_load (&gsi);
1628 bb = gimple_bb (stmt);
1631 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1632 && is_gimple_call (stmt)
1633 && !gimple_call_internal_p (stmt))
1635 instrument_nonnull_arg (&gsi);
1636 bb = gimple_bb (stmt);
1639 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1640 && gimple_code (stmt) == GIMPLE_RETURN)
1642 instrument_nonnull_return (&gsi);
1643 bb = gimple_bb (stmt);
1646 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
1648 if (gimple_store_p (stmt))
1649 instrument_object_size (&gsi, true);
1650 if (gimple_assign_load_p (stmt))
1651 instrument_object_size (&gsi, false);
1654 gsi_next (&gsi);
1657 return 0;
1660 } // anon namespace
1662 gimple_opt_pass *
1663 make_pass_ubsan (gcc::context *ctxt)
1665 return new pass_ubsan (ctxt);
1668 #include "gt-ubsan.h"