runtime: set library name based on compiler name
[official-gcc.git] / gcc / ubsan.c
blobb5b1b924c67561d1f88407eb7436d5c4d47e4811
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 bool
592 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
594 gimple g;
595 location_t loc = gimple_location (gsi_stmt (*gsi));
597 if (flag_sanitize_undefined_trap_on_error)
598 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
599 else
601 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
602 NULL_TREE, NULL_TREE);
603 data = build_fold_addr_expr_loc (loc, data);
604 tree fn
605 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
606 g = gimple_build_call (fn, 1, data);
608 gimple_set_location (g, loc);
609 gsi_replace (gsi, g, false);
610 return false;
613 /* Return true if T is a call to a libubsan routine. */
615 bool
616 is_ubsan_builtin_p (tree t)
618 return TREE_CODE (t) == FUNCTION_DECL
619 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
620 "__builtin___ubsan_", 18) == 0;
623 /* Expand the UBSAN_BOUNDS special builtin function. */
625 bool
626 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
628 gimple stmt = gsi_stmt (*gsi);
629 location_t loc = gimple_location (stmt);
630 gcc_assert (gimple_call_num_args (stmt) == 3);
632 /* Pick up the arguments of the UBSAN_BOUNDS call. */
633 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
634 tree index = gimple_call_arg (stmt, 1);
635 tree orig_index_type = TREE_TYPE (index);
636 tree bound = gimple_call_arg (stmt, 2);
638 gimple_stmt_iterator gsi_orig = *gsi;
640 /* Create condition "if (index > bound)". */
641 basic_block then_bb, fallthru_bb;
642 gimple_stmt_iterator cond_insert_point
643 = create_cond_insert_point (gsi, false, false, true,
644 &then_bb, &fallthru_bb);
645 index = fold_convert (TREE_TYPE (bound), index);
646 index = force_gimple_operand_gsi (&cond_insert_point, index,
647 true, NULL_TREE,
648 false, GSI_NEW_STMT);
649 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
650 gimple_set_location (g, loc);
651 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
653 /* Generate __ubsan_handle_out_of_bounds call. */
654 *gsi = gsi_after_labels (then_bb);
655 if (flag_sanitize_undefined_trap_on_error)
656 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
657 else
659 tree data
660 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
661 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
662 ubsan_type_descriptor (orig_index_type),
663 NULL_TREE, NULL_TREE);
664 data = build_fold_addr_expr_loc (loc, data);
665 enum built_in_function bcode
666 = (flag_sanitize_recover & SANITIZE_BOUNDS)
667 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
668 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
669 tree fn = builtin_decl_explicit (bcode);
670 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
671 true, NULL_TREE, true,
672 GSI_SAME_STMT);
673 g = gimple_build_call (fn, 2, data, val);
675 gimple_set_location (g, loc);
676 gsi_insert_before (gsi, g, GSI_SAME_STMT);
678 /* Get rid of the UBSAN_BOUNDS call from the IR. */
679 unlink_stmt_vdef (stmt);
680 gsi_remove (&gsi_orig, true);
682 /* Point GSI to next logical statement. */
683 *gsi = gsi_start_bb (fallthru_bb);
684 return true;
687 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
688 argument which is a constant, because the middle-end treats pointer
689 conversions as useless and therefore the type of the first argument
690 could be changed to any other pointer type. */
692 bool
693 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
695 gimple_stmt_iterator gsi = *gsip;
696 gimple stmt = gsi_stmt (gsi);
697 location_t loc = gimple_location (stmt);
698 gcc_assert (gimple_call_num_args (stmt) == 3);
699 tree ptr = gimple_call_arg (stmt, 0);
700 tree ckind = gimple_call_arg (stmt, 1);
701 tree align = gimple_call_arg (stmt, 2);
702 tree check_align = NULL_TREE;
703 bool check_null;
705 basic_block cur_bb = gsi_bb (gsi);
707 gimple g;
708 if (!integer_zerop (align))
710 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
711 if (compare_tree_int (align, ptralign) == 1)
713 check_align = make_ssa_name (pointer_sized_int_node, NULL);
714 g = gimple_build_assign_with_ops (NOP_EXPR, check_align,
715 ptr, NULL_TREE);
716 gimple_set_location (g, loc);
717 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
720 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
722 if (check_align == NULL_TREE && !check_null)
724 gsi_remove (gsip, true);
725 /* Unlink the UBSAN_NULLs vops before replacing it. */
726 unlink_stmt_vdef (stmt);
727 return true;
730 /* Split the original block holding the pointer dereference. */
731 edge e = split_block (cur_bb, stmt);
733 /* Get a hold on the 'condition block', the 'then block' and the
734 'else block'. */
735 basic_block cond_bb = e->src;
736 basic_block fallthru_bb = e->dest;
737 basic_block then_bb = create_empty_bb (cond_bb);
738 add_bb_to_loop (then_bb, cond_bb->loop_father);
739 loops_state_set (LOOPS_NEED_FIXUP);
741 /* Make an edge coming from the 'cond block' into the 'then block';
742 this edge is unlikely taken, so set up the probability accordingly. */
743 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
744 e->probability = PROB_VERY_UNLIKELY;
746 /* Connect 'then block' with the 'else block'. This is needed
747 as the ubsan routines we call in the 'then block' are not noreturn.
748 The 'then block' only has one outcoming edge. */
749 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
751 /* Set up the fallthrough basic block. */
752 e = find_edge (cond_bb, fallthru_bb);
753 e->flags = EDGE_FALSE_VALUE;
754 e->count = cond_bb->count;
755 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
757 /* Update dominance info for the newly created then_bb; note that
758 fallthru_bb's dominance info has already been updated by
759 split_block. */
760 if (dom_info_available_p (CDI_DOMINATORS))
761 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
763 /* Put the ubsan builtin call into the newly created BB. */
764 if (flag_sanitize_undefined_trap_on_error)
765 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
766 else
768 enum built_in_function bcode
769 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
770 | (check_null ? SANITIZE_NULL : 0)))
771 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
772 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
773 tree fn = builtin_decl_implicit (bcode);
774 tree data
775 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
776 ubsan_type_descriptor (TREE_TYPE (ckind),
777 UBSAN_PRINT_POINTER),
778 NULL_TREE,
779 align,
780 fold_convert (unsigned_char_type_node, ckind),
781 NULL_TREE);
782 data = build_fold_addr_expr_loc (loc, data);
783 g = gimple_build_call (fn, 2, data,
784 check_align ? check_align
785 : build_zero_cst (pointer_sized_int_node));
787 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
788 gimple_set_location (g, loc);
789 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
791 /* Unlink the UBSAN_NULLs vops before replacing it. */
792 unlink_stmt_vdef (stmt);
794 if (check_null)
796 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
797 NULL_TREE, NULL_TREE);
798 gimple_set_location (g, loc);
800 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
801 gsi_replace (&gsi, g, false);
804 if (check_align)
806 if (check_null)
808 /* Split the block with the condition again. */
809 e = split_block (cond_bb, stmt);
810 basic_block cond1_bb = e->src;
811 basic_block cond2_bb = e->dest;
813 /* Make an edge coming from the 'cond1 block' into the 'then block';
814 this edge is unlikely taken, so set up the probability
815 accordingly. */
816 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
817 e->probability = PROB_VERY_UNLIKELY;
819 /* Set up the fallthrough basic block. */
820 e = find_edge (cond1_bb, cond2_bb);
821 e->flags = EDGE_FALSE_VALUE;
822 e->count = cond1_bb->count;
823 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
825 /* Update dominance info. */
826 if (dom_info_available_p (CDI_DOMINATORS))
828 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
829 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
832 gsi2 = gsi_start_bb (cond2_bb);
835 tree mask = build_int_cst (pointer_sized_int_node,
836 tree_to_uhwi (align) - 1);
837 g = gimple_build_assign_with_ops (BIT_AND_EXPR,
838 make_ssa_name (pointer_sized_int_node,
839 NULL),
840 check_align, mask);
841 gimple_set_location (g, loc);
842 if (check_null)
843 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
844 else
845 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
847 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
848 build_int_cst (pointer_sized_int_node, 0),
849 NULL_TREE, NULL_TREE);
850 gimple_set_location (g, loc);
851 if (check_null)
852 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
853 else
854 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
855 gsi_replace (&gsi, g, false);
857 return false;
860 /* Expand UBSAN_OBJECT_SIZE internal call. */
862 bool
863 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
865 gimple stmt = gsi_stmt (*gsi);
866 location_t loc = gimple_location (stmt);
867 gcc_assert (gimple_call_num_args (stmt) == 4);
869 tree ptr = gimple_call_arg (stmt, 0);
870 tree offset = gimple_call_arg (stmt, 1);
871 tree size = gimple_call_arg (stmt, 2);
872 tree ckind = gimple_call_arg (stmt, 3);
873 gimple_stmt_iterator gsi_orig = *gsi;
874 gimple g;
876 /* See if we can discard the check. */
877 if (TREE_CODE (size) != INTEGER_CST
878 || integer_all_onesp (size))
879 /* Yes, __builtin_object_size couldn't determine the
880 object size. */;
881 else
883 /* if (offset > objsize) */
884 basic_block then_bb, fallthru_bb;
885 gimple_stmt_iterator cond_insert_point
886 = create_cond_insert_point (gsi, false, false, true,
887 &then_bb, &fallthru_bb);
888 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
889 gimple_set_location (g, loc);
890 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
892 /* Generate __ubsan_handle_type_mismatch call. */
893 *gsi = gsi_after_labels (then_bb);
894 if (flag_sanitize_undefined_trap_on_error)
895 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
896 else
898 tree data
899 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
900 ubsan_type_descriptor (TREE_TYPE (ptr),
901 UBSAN_PRINT_POINTER),
902 NULL_TREE,
903 build_zero_cst (pointer_sized_int_node),
904 ckind,
905 NULL_TREE);
906 data = build_fold_addr_expr_loc (loc, data);
907 enum built_in_function bcode
908 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
909 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
910 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
911 tree p = make_ssa_name (pointer_sized_int_node, NULL);
912 g = gimple_build_assign_with_ops (NOP_EXPR, p, ptr, NULL_TREE);
913 gimple_set_location (g, loc);
914 gsi_insert_before (gsi, g, GSI_SAME_STMT);
915 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
917 gimple_set_location (g, loc);
918 gsi_insert_before (gsi, g, GSI_SAME_STMT);
920 /* Point GSI to next logical statement. */
921 *gsi = gsi_start_bb (fallthru_bb);
924 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
925 unlink_stmt_vdef (stmt);
926 gsi_remove (&gsi_orig, true);
927 return gsi_end_p (*gsi);
930 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
931 whether the pointer is on the left hand side of the assignment. */
933 static void
934 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
935 bool is_lhs)
937 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
938 unsigned int align = 0;
939 if (flag_sanitize & SANITIZE_ALIGNMENT)
941 align = min_align_of_type (TREE_TYPE (base));
942 if (align <= 1)
943 align = 0;
945 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
946 return;
947 tree t = TREE_OPERAND (base, 0);
948 if (!POINTER_TYPE_P (TREE_TYPE (t)))
949 return;
950 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && mem != base)
951 ikind = UBSAN_MEMBER_ACCESS;
952 tree kind = build_int_cst (TREE_TYPE (t), ikind);
953 tree alignt = build_int_cst (pointer_sized_int_node, align);
954 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
955 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
956 gsi_insert_before (iter, g, GSI_SAME_STMT);
959 /* Perform the pointer instrumentation. */
961 static void
962 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
964 gimple stmt = gsi_stmt (gsi);
965 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
966 tree base = get_base_address (t);
967 const enum tree_code code = TREE_CODE (base);
968 if (code == MEM_REF
969 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
970 instrument_mem_ref (t, base, &gsi, is_lhs);
973 /* Build an ubsan builtin call for the signed-integer-overflow
974 sanitization. CODE says what kind of builtin are we building,
975 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
976 are operands of the binary operation. */
978 tree
979 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
980 tree op0, tree op1)
982 if (flag_sanitize_undefined_trap_on_error)
983 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
985 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
986 ubsan_type_descriptor (lhstype), NULL_TREE,
987 NULL_TREE);
988 enum built_in_function fn_code;
990 switch (code)
992 case PLUS_EXPR:
993 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
994 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
995 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
996 break;
997 case MINUS_EXPR:
998 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
999 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1000 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1001 break;
1002 case MULT_EXPR:
1003 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1004 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1005 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1006 break;
1007 case NEGATE_EXPR:
1008 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1009 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1010 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1011 break;
1012 default:
1013 gcc_unreachable ();
1015 tree fn = builtin_decl_explicit (fn_code);
1016 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1017 build_fold_addr_expr_loc (loc, data),
1018 ubsan_encode_value (op0, true),
1019 op1 ? ubsan_encode_value (op1, true)
1020 : NULL_TREE);
1023 /* Perform the signed integer instrumentation. GSI is the iterator
1024 pointing at statement we are trying to instrument. */
1026 static void
1027 instrument_si_overflow (gimple_stmt_iterator gsi)
1029 gimple stmt = gsi_stmt (gsi);
1030 tree_code code = gimple_assign_rhs_code (stmt);
1031 tree lhs = gimple_assign_lhs (stmt);
1032 tree lhstype = TREE_TYPE (lhs);
1033 tree a, b;
1034 gimple g;
1036 /* If this is not a signed operation, don't instrument anything here.
1037 Also punt on bit-fields. */
1038 if (!INTEGRAL_TYPE_P (lhstype)
1039 || TYPE_OVERFLOW_WRAPS (lhstype)
1040 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1041 return;
1043 switch (code)
1045 case MINUS_EXPR:
1046 case PLUS_EXPR:
1047 case MULT_EXPR:
1048 /* Transform
1049 i = u {+,-,*} 5;
1050 into
1051 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1052 a = gimple_assign_rhs1 (stmt);
1053 b = gimple_assign_rhs2 (stmt);
1054 g = gimple_build_call_internal (code == PLUS_EXPR
1055 ? IFN_UBSAN_CHECK_ADD
1056 : code == MINUS_EXPR
1057 ? IFN_UBSAN_CHECK_SUB
1058 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1059 gimple_call_set_lhs (g, lhs);
1060 gsi_replace (&gsi, g, false);
1061 break;
1062 case NEGATE_EXPR:
1063 /* Represent i = -u;
1065 i = UBSAN_CHECK_SUB (0, u); */
1066 a = build_int_cst (lhstype, 0);
1067 b = gimple_assign_rhs1 (stmt);
1068 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1069 gimple_call_set_lhs (g, lhs);
1070 gsi_replace (&gsi, g, false);
1071 break;
1072 case ABS_EXPR:
1073 /* Transform i = ABS_EXPR<u>;
1074 into
1075 _N = UBSAN_CHECK_SUB (0, u);
1076 i = ABS_EXPR<_N>; */
1077 a = build_int_cst (lhstype, 0);
1078 b = gimple_assign_rhs1 (stmt);
1079 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1080 a = make_ssa_name (lhstype, NULL);
1081 gimple_call_set_lhs (g, a);
1082 gimple_set_location (g, gimple_location (stmt));
1083 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1084 gimple_assign_set_rhs1 (stmt, a);
1085 update_stmt (stmt);
1086 break;
1087 default:
1088 break;
1092 /* Instrument loads from (non-bitfield) bool and C++ enum values
1093 to check if the memory value is outside of the range of the valid
1094 type values. */
1096 static void
1097 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1099 gimple stmt = gsi_stmt (*gsi);
1100 tree rhs = gimple_assign_rhs1 (stmt);
1101 tree type = TREE_TYPE (rhs);
1102 tree minv = NULL_TREE, maxv = NULL_TREE;
1104 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1106 minv = boolean_false_node;
1107 maxv = boolean_true_node;
1109 else if (TREE_CODE (type) == ENUMERAL_TYPE
1110 && (flag_sanitize & SANITIZE_ENUM)
1111 && TREE_TYPE (type) != NULL_TREE
1112 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1113 && (TYPE_PRECISION (TREE_TYPE (type))
1114 < GET_MODE_PRECISION (TYPE_MODE (type))))
1116 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1117 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1119 else
1120 return;
1122 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1123 HOST_WIDE_INT bitsize, bitpos;
1124 tree offset;
1125 machine_mode mode;
1126 int volatilep = 0, unsignedp = 0;
1127 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1128 &unsignedp, &volatilep, false);
1129 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1131 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1132 || (bitpos % modebitsize) != 0
1133 || bitsize != modebitsize
1134 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1135 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1136 return;
1138 location_t loc = gimple_location (stmt);
1139 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1140 tree atype = reference_alias_ptr_type (rhs);
1141 gimple g = gimple_build_assign (make_ssa_name (ptype, NULL),
1142 build_fold_addr_expr (rhs));
1143 gimple_set_location (g, loc);
1144 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1145 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1146 build_int_cst (atype, 0));
1147 tree urhs = make_ssa_name (utype, NULL);
1148 g = gimple_build_assign (urhs, mem);
1149 gimple_set_location (g, loc);
1150 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1151 minv = fold_convert (utype, minv);
1152 maxv = fold_convert (utype, maxv);
1153 if (!integer_zerop (minv))
1155 g = gimple_build_assign_with_ops (MINUS_EXPR,
1156 make_ssa_name (utype, NULL),
1157 urhs, minv);
1158 gimple_set_location (g, loc);
1159 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1162 gimple_stmt_iterator gsi2 = *gsi;
1163 basic_block then_bb, fallthru_bb;
1164 *gsi = create_cond_insert_point (gsi, true, false, true,
1165 &then_bb, &fallthru_bb);
1166 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1167 int_const_binop (MINUS_EXPR, maxv, minv),
1168 NULL_TREE, NULL_TREE);
1169 gimple_set_location (g, loc);
1170 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1172 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
1173 update_stmt (stmt);
1175 gsi2 = gsi_after_labels (then_bb);
1176 if (flag_sanitize_undefined_trap_on_error)
1177 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1178 else
1180 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1181 ubsan_type_descriptor (type), NULL_TREE,
1182 NULL_TREE);
1183 data = build_fold_addr_expr_loc (loc, data);
1184 enum built_in_function bcode
1185 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1186 ? SANITIZE_BOOL : SANITIZE_ENUM))
1187 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1188 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1189 tree fn = builtin_decl_explicit (bcode);
1191 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1192 true, NULL_TREE, true,
1193 GSI_SAME_STMT);
1194 g = gimple_build_call (fn, 2, data, val);
1196 gimple_set_location (g, loc);
1197 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1198 *gsi = gsi_for_stmt (stmt);
1201 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1202 destination, EXPR is floating-point expression. */
1204 tree
1205 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1207 tree expr_type = TREE_TYPE (expr);
1208 tree t, tt, fn, min, max;
1209 machine_mode mode = TYPE_MODE (expr_type);
1210 int prec = TYPE_PRECISION (type);
1211 bool uns_p = TYPE_UNSIGNED (type);
1213 /* Float to integer conversion first truncates toward zero, so
1214 even signed char c = 127.875f; is not problematic.
1215 Therefore, we should complain only if EXPR is unordered or smaller
1216 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1217 TYPE_MAX_VALUE + 1.0. */
1218 if (REAL_MODE_FORMAT (mode)->b == 2)
1220 /* For maximum, TYPE_MAX_VALUE might not be representable
1221 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1222 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1223 either representable or infinity. */
1224 REAL_VALUE_TYPE maxval = dconst1;
1225 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1226 real_convert (&maxval, mode, &maxval);
1227 max = build_real (expr_type, maxval);
1229 /* For unsigned, assume -1.0 is always representable. */
1230 if (uns_p)
1231 min = build_minus_one_cst (expr_type);
1232 else
1234 /* TYPE_MIN_VALUE is generally representable (or -inf),
1235 but TYPE_MIN_VALUE - 1.0 might not be. */
1236 REAL_VALUE_TYPE minval = dconstm1, minval2;
1237 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1238 real_convert (&minval, mode, &minval);
1239 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1240 real_convert (&minval2, mode, &minval2);
1241 if (real_compare (EQ_EXPR, &minval, &minval2)
1242 && !real_isinf (&minval))
1244 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1245 rounds to TYPE_MIN_VALUE, we need to subtract
1246 more. As REAL_MODE_FORMAT (mode)->p is the number
1247 of base digits, we want to subtract a number that
1248 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1249 times smaller than minval. */
1250 minval2 = dconst1;
1251 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1252 SET_REAL_EXP (&minval2,
1253 REAL_EXP (&minval2) + prec - 1
1254 - REAL_MODE_FORMAT (mode)->p + 1);
1255 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1256 real_convert (&minval2, mode, &minval2);
1258 min = build_real (expr_type, minval2);
1261 else if (REAL_MODE_FORMAT (mode)->b == 10)
1263 /* For _Decimal128 up to 34 decimal digits, - sign,
1264 dot, e, exponent. */
1265 char buf[64];
1266 mpfr_t m;
1267 int p = REAL_MODE_FORMAT (mode)->p;
1268 REAL_VALUE_TYPE maxval, minval;
1270 /* Use mpfr_snprintf rounding to compute the smallest
1271 representable decimal number greater or equal than
1272 1 << (prec - !uns_p). */
1273 mpfr_init2 (m, prec + 2);
1274 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1275 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1276 decimal_real_from_string (&maxval, buf);
1277 max = build_real (expr_type, maxval);
1279 /* For unsigned, assume -1.0 is always representable. */
1280 if (uns_p)
1281 min = build_minus_one_cst (expr_type);
1282 else
1284 /* Use mpfr_snprintf rounding to compute the largest
1285 representable decimal number less or equal than
1286 (-1 << (prec - 1)) - 1. */
1287 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1288 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1289 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1290 decimal_real_from_string (&minval, buf);
1291 min = build_real (expr_type, minval);
1293 mpfr_clear (m);
1295 else
1296 return NULL_TREE;
1298 if (flag_sanitize_undefined_trap_on_error)
1299 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1300 else
1302 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1303 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1304 NULL, ubsan_type_descriptor (expr_type),
1305 ubsan_type_descriptor (type), NULL_TREE,
1306 NULL_TREE);
1307 enum built_in_function bcode
1308 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1309 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1310 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1311 fn = builtin_decl_explicit (bcode);
1312 fn = build_call_expr_loc (loc, fn, 2,
1313 build_fold_addr_expr_loc (loc, data),
1314 ubsan_encode_value (expr, false));
1317 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1318 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1319 return fold_build3 (COND_EXPR, void_type_node,
1320 fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt),
1321 fn, integer_zero_node);
1324 /* Instrument values passed to function arguments with nonnull attribute. */
1326 static void
1327 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1329 gimple stmt = gsi_stmt (*gsi);
1330 location_t loc[2];
1331 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1332 while for nonnull sanitization it is clear. */
1333 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1334 flag_delete_null_pointer_checks = 1;
1335 loc[0] = gimple_location (stmt);
1336 loc[1] = UNKNOWN_LOCATION;
1337 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1339 tree arg = gimple_call_arg (stmt, i);
1340 if (POINTER_TYPE_P (TREE_TYPE (arg))
1341 && infer_nonnull_range (stmt, arg, false, true))
1343 gimple g;
1344 if (!is_gimple_val (arg))
1346 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg), NULL),
1347 arg);
1348 gimple_set_location (g, loc[0]);
1349 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1350 arg = gimple_assign_lhs (g);
1353 basic_block then_bb, fallthru_bb;
1354 *gsi = create_cond_insert_point (gsi, true, false, true,
1355 &then_bb, &fallthru_bb);
1356 g = gimple_build_cond (EQ_EXPR, arg,
1357 build_zero_cst (TREE_TYPE (arg)),
1358 NULL_TREE, NULL_TREE);
1359 gimple_set_location (g, loc[0]);
1360 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1362 *gsi = gsi_after_labels (then_bb);
1363 if (flag_sanitize_undefined_trap_on_error)
1364 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1365 else
1367 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1368 2, loc, NULL_TREE,
1369 build_int_cst (integer_type_node,
1370 i + 1),
1371 NULL_TREE);
1372 data = build_fold_addr_expr_loc (loc[0], data);
1373 enum built_in_function bcode
1374 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1375 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1376 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1377 tree fn = builtin_decl_explicit (bcode);
1379 g = gimple_build_call (fn, 1, data);
1381 gimple_set_location (g, loc[0]);
1382 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1384 *gsi = gsi_for_stmt (stmt);
1386 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1389 /* Instrument returns in functions with returns_nonnull attribute. */
1391 static void
1392 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1394 gimple stmt = gsi_stmt (*gsi);
1395 location_t loc[2];
1396 tree arg = gimple_return_retval (stmt);
1397 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1398 while for nonnull return sanitization it is clear. */
1399 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1400 flag_delete_null_pointer_checks = 1;
1401 loc[0] = gimple_location (stmt);
1402 loc[1] = UNKNOWN_LOCATION;
1403 if (arg
1404 && POINTER_TYPE_P (TREE_TYPE (arg))
1405 && is_gimple_val (arg)
1406 && infer_nonnull_range (stmt, arg, false, true))
1408 basic_block then_bb, fallthru_bb;
1409 *gsi = create_cond_insert_point (gsi, true, false, true,
1410 &then_bb, &fallthru_bb);
1411 gimple g = gimple_build_cond (EQ_EXPR, arg,
1412 build_zero_cst (TREE_TYPE (arg)),
1413 NULL_TREE, NULL_TREE);
1414 gimple_set_location (g, loc[0]);
1415 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1417 *gsi = gsi_after_labels (then_bb);
1418 if (flag_sanitize_undefined_trap_on_error)
1419 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1420 else
1422 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1423 2, loc, NULL_TREE, NULL_TREE);
1424 data = build_fold_addr_expr_loc (loc[0], data);
1425 enum built_in_function bcode
1426 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1427 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1428 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1429 tree fn = builtin_decl_explicit (bcode);
1431 g = gimple_build_call (fn, 1, data);
1433 gimple_set_location (g, loc[0]);
1434 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1435 *gsi = gsi_for_stmt (stmt);
1437 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1440 /* Instrument memory references. Here we check whether the pointer
1441 points to an out-of-bounds location. */
1443 static void
1444 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1446 gimple stmt = gsi_stmt (*gsi);
1447 location_t loc = gimple_location (stmt);
1448 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1449 tree type;
1450 tree index = NULL_TREE;
1451 HOST_WIDE_INT size_in_bytes;
1453 type = TREE_TYPE (t);
1454 if (VOID_TYPE_P (type))
1455 return;
1457 switch (TREE_CODE (t))
1459 case COMPONENT_REF:
1460 if (TREE_CODE (t) == COMPONENT_REF
1461 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1463 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1464 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1465 repr, NULL_TREE);
1467 break;
1468 case ARRAY_REF:
1469 index = TREE_OPERAND (t, 1);
1470 break;
1471 case INDIRECT_REF:
1472 case MEM_REF:
1473 case VAR_DECL:
1474 case PARM_DECL:
1475 case RESULT_DECL:
1476 break;
1477 default:
1478 return;
1481 size_in_bytes = int_size_in_bytes (type);
1482 if (size_in_bytes <= 0)
1483 return;
1485 HOST_WIDE_INT bitsize, bitpos;
1486 tree offset;
1487 machine_mode mode;
1488 int volatilep = 0, unsignedp = 0;
1489 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1490 &unsignedp, &volatilep, false);
1492 if (bitpos % BITS_PER_UNIT != 0
1493 || bitsize != size_in_bytes * BITS_PER_UNIT)
1494 return;
1496 bool decl_p = DECL_P (inner);
1497 tree base = decl_p ? inner : TREE_OPERAND (inner, 0);
1498 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1500 while (TREE_CODE (base) == SSA_NAME)
1502 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1503 if (gimple_assign_ssa_name_copy_p (def_stmt)
1504 || (gimple_assign_cast_p (def_stmt)
1505 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1506 || (is_gimple_assign (def_stmt)
1507 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1508 base = gimple_assign_rhs1 (def_stmt);
1509 else
1510 break;
1513 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1514 return;
1516 tree sizet;
1517 tree base_addr = base;
1518 if (decl_p)
1519 base_addr = build1 (ADDR_EXPR,
1520 build_pointer_type (TREE_TYPE (base)), base);
1521 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1522 if (size != (unsigned HOST_WIDE_INT) -1)
1523 sizet = build_int_cst (sizetype, size);
1524 else if (optimize)
1526 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1527 loc = input_location;
1528 /* Generate __builtin_object_size call. */
1529 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1530 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1531 integer_zero_node);
1532 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1533 GSI_SAME_STMT);
1535 else
1536 return;
1538 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1539 call. */
1540 /* ptr + sizeof (*ptr) - base */
1541 t = fold_build2 (MINUS_EXPR, sizetype,
1542 fold_convert (pointer_sized_int_node, ptr),
1543 fold_convert (pointer_sized_int_node, base_addr));
1544 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1546 /* Perhaps we can omit the check. */
1547 if (TREE_CODE (t) == INTEGER_CST
1548 && TREE_CODE (sizet) == INTEGER_CST
1549 && tree_int_cst_le (t, sizet))
1550 return;
1552 if (index != NULL_TREE
1553 && TREE_CODE (index) == SSA_NAME
1554 && TREE_CODE (sizet) == INTEGER_CST)
1556 gimple def = SSA_NAME_DEF_STMT (index);
1557 if (is_gimple_assign (def)
1558 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1559 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1561 tree cst = gimple_assign_rhs2 (def);
1562 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1563 TYPE_SIZE_UNIT (type));
1564 if (tree_int_cst_sgn (cst) >= 0
1565 && tree_int_cst_lt (cst, sz))
1566 return;
1570 /* Nope. Emit the check. */
1571 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1572 GSI_SAME_STMT);
1573 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1574 GSI_SAME_STMT);
1575 tree ckind = build_int_cst (unsigned_char_type_node,
1576 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1577 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1578 ptr, t, sizet, ckind);
1579 gimple_set_location (g, loc);
1580 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1583 namespace {
1585 const pass_data pass_data_ubsan =
1587 GIMPLE_PASS, /* type */
1588 "ubsan", /* name */
1589 OPTGROUP_NONE, /* optinfo_flags */
1590 TV_TREE_UBSAN, /* tv_id */
1591 ( PROP_cfg | PROP_ssa ), /* properties_required */
1592 0, /* properties_provided */
1593 0, /* properties_destroyed */
1594 0, /* todo_flags_start */
1595 TODO_update_ssa, /* todo_flags_finish */
1598 class pass_ubsan : public gimple_opt_pass
1600 public:
1601 pass_ubsan (gcc::context *ctxt)
1602 : gimple_opt_pass (pass_data_ubsan, ctxt)
1605 /* opt_pass methods: */
1606 virtual bool gate (function *)
1608 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1609 | SANITIZE_BOOL | SANITIZE_ENUM
1610 | SANITIZE_ALIGNMENT
1611 | SANITIZE_NONNULL_ATTRIBUTE
1612 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1613 | SANITIZE_OBJECT_SIZE)
1614 && current_function_decl != NULL_TREE
1615 && !lookup_attribute ("no_sanitize_undefined",
1616 DECL_ATTRIBUTES (current_function_decl));
1619 virtual unsigned int execute (function *);
1621 }; // class pass_ubsan
1623 unsigned int
1624 pass_ubsan::execute (function *fun)
1626 basic_block bb;
1627 gimple_stmt_iterator gsi;
1629 initialize_sanitizer_builtins ();
1631 FOR_EACH_BB_FN (bb, fun)
1633 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1635 gimple stmt = gsi_stmt (gsi);
1636 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1638 gsi_next (&gsi);
1639 continue;
1642 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1643 && is_gimple_assign (stmt))
1644 instrument_si_overflow (gsi);
1646 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1648 if (gimple_store_p (stmt))
1649 instrument_null (gsi, true);
1650 if (gimple_assign_load_p (stmt))
1651 instrument_null (gsi, false);
1654 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1655 && gimple_assign_load_p (stmt))
1657 instrument_bool_enum_load (&gsi);
1658 bb = gimple_bb (stmt);
1661 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1662 && is_gimple_call (stmt)
1663 && !gimple_call_internal_p (stmt))
1665 instrument_nonnull_arg (&gsi);
1666 bb = gimple_bb (stmt);
1669 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1670 && gimple_code (stmt) == GIMPLE_RETURN)
1672 instrument_nonnull_return (&gsi);
1673 bb = gimple_bb (stmt);
1676 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
1678 if (gimple_store_p (stmt))
1679 instrument_object_size (&gsi, true);
1680 if (gimple_assign_load_p (stmt))
1681 instrument_object_size (&gsi, false);
1684 gsi_next (&gsi);
1687 return 0;
1690 } // anon namespace
1692 gimple_opt_pass *
1693 make_pass_ubsan (gcc::context *ctxt)
1695 return new pass_ubsan (ctxt);
1698 #include "gt-ubsan.h"