PR sanitizer/79558
[official-gcc.git] / gcc / ubsan.c
blob11a41e1dc535eb87167450879d025bb8537d6d8a
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2017 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 "backend.h"
25 #include "rtl.h"
26 #include "c-family/c-common.h"
27 #include "gimple.h"
28 #include "cfghooks.h"
29 #include "tree-pass.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "ssa.h"
33 #include "cgraph.h"
34 #include "tree-pretty-print.h"
35 #include "stor-layout.h"
36 #include "cfganal.h"
37 #include "gimple-iterator.h"
38 #include "output.h"
39 #include "cfgloop.h"
40 #include "ubsan.h"
41 #include "expr.h"
42 #include "asan.h"
43 #include "gimplify-me.h"
44 #include "dfp.h"
45 #include "builtins.h"
46 #include "tree-object-size.h"
47 #include "tree-cfg.h"
49 /* Map from a tree to a VAR_DECL tree. */
51 struct GTY((for_user)) tree_type_map {
52 struct tree_map_base type;
53 tree decl;
56 struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
58 static inline hashval_t
59 hash (tree_type_map *t)
61 return TYPE_UID (t->type.from);
64 static inline bool
65 equal (tree_type_map *a, tree_type_map *b)
67 return a->type.from == b->type.from;
70 static int
71 keep_cache_entry (tree_type_map *&m)
73 return ggc_marked_p (m->type.from);
77 static GTY ((cache))
78 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
80 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
82 static tree
83 decl_for_type_lookup (tree type)
85 /* If the hash table is not initialized yet, create it now. */
86 if (decl_tree_for_type == NULL)
88 decl_tree_for_type
89 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
90 /* That also means we don't have to bother with the lookup. */
91 return NULL_TREE;
94 struct tree_type_map *h, in;
95 in.type.from = type;
97 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
98 return h ? h->decl : NULL_TREE;
101 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
103 static void
104 decl_for_type_insert (tree type, tree decl)
106 struct tree_type_map *h;
108 h = ggc_alloc<tree_type_map> ();
109 h->type.from = type;
110 h->decl = decl;
111 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
114 /* Helper routine, which encodes a value in the pointer_sized_int_node.
115 Arguments with precision <= POINTER_SIZE are passed directly,
116 the rest is passed by reference. T is a value we are to encode.
117 IN_EXPAND_P is true if this function is called during expansion. */
119 tree
120 ubsan_encode_value (tree t, bool in_expand_p)
122 tree type = TREE_TYPE (t);
123 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
124 if (bitsize <= POINTER_SIZE)
125 switch (TREE_CODE (type))
127 case BOOLEAN_TYPE:
128 case ENUMERAL_TYPE:
129 case INTEGER_TYPE:
130 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
131 case REAL_TYPE:
133 tree itype = build_nonstandard_integer_type (bitsize, true);
134 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
135 return fold_convert (pointer_sized_int_node, t);
137 default:
138 gcc_unreachable ();
140 else
142 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
144 /* The reason for this is that we don't want to pessimize
145 code by making vars unnecessarily addressable. */
146 tree var = create_tmp_var (type);
147 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
148 if (in_expand_p)
150 rtx mem
151 = assign_stack_temp_for_type (TYPE_MODE (type),
152 GET_MODE_SIZE (TYPE_MODE (type)),
153 type);
154 SET_DECL_RTL (var, mem);
155 expand_assignment (var, t, false);
156 return build_fold_addr_expr (var);
158 t = build_fold_addr_expr (var);
159 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
161 else
162 return build_fold_addr_expr (t);
166 /* Cached ubsan_get_type_descriptor_type () return value. */
167 static GTY(()) tree ubsan_type_descriptor_type;
169 /* Build
170 struct __ubsan_type_descriptor
172 unsigned short __typekind;
173 unsigned short __typeinfo;
174 char __typename[];
176 type. */
178 static tree
179 ubsan_get_type_descriptor_type (void)
181 static const char *field_names[3]
182 = { "__typekind", "__typeinfo", "__typename" };
183 tree fields[3], ret;
185 if (ubsan_type_descriptor_type)
186 return ubsan_type_descriptor_type;
188 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
189 tree flex_arr_type = build_array_type (char_type_node, itype);
191 ret = make_node (RECORD_TYPE);
192 for (int i = 0; i < 3; i++)
194 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
195 get_identifier (field_names[i]),
196 (i == 2) ? flex_arr_type
197 : short_unsigned_type_node);
198 DECL_CONTEXT (fields[i]) = ret;
199 if (i)
200 DECL_CHAIN (fields[i - 1]) = fields[i];
202 tree type_decl = build_decl (input_location, TYPE_DECL,
203 get_identifier ("__ubsan_type_descriptor"),
204 ret);
205 DECL_IGNORED_P (type_decl) = 1;
206 DECL_ARTIFICIAL (type_decl) = 1;
207 TYPE_FIELDS (ret) = fields[0];
208 TYPE_NAME (ret) = type_decl;
209 TYPE_STUB_DECL (ret) = type_decl;
210 layout_type (ret);
211 ubsan_type_descriptor_type = ret;
212 return ret;
215 /* Cached ubsan_get_source_location_type () return value. */
216 static GTY(()) tree ubsan_source_location_type;
218 /* Build
219 struct __ubsan_source_location
221 const char *__filename;
222 unsigned int __line;
223 unsigned int __column;
225 type. */
227 tree
228 ubsan_get_source_location_type (void)
230 static const char *field_names[3]
231 = { "__filename", "__line", "__column" };
232 tree fields[3], ret;
233 if (ubsan_source_location_type)
234 return ubsan_source_location_type;
236 tree const_char_type = build_qualified_type (char_type_node,
237 TYPE_QUAL_CONST);
239 ret = make_node (RECORD_TYPE);
240 for (int i = 0; i < 3; i++)
242 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
243 get_identifier (field_names[i]),
244 (i == 0) ? build_pointer_type (const_char_type)
245 : unsigned_type_node);
246 DECL_CONTEXT (fields[i]) = ret;
247 if (i)
248 DECL_CHAIN (fields[i - 1]) = fields[i];
250 tree type_decl = build_decl (input_location, TYPE_DECL,
251 get_identifier ("__ubsan_source_location"),
252 ret);
253 DECL_IGNORED_P (type_decl) = 1;
254 DECL_ARTIFICIAL (type_decl) = 1;
255 TYPE_FIELDS (ret) = fields[0];
256 TYPE_NAME (ret) = type_decl;
257 TYPE_STUB_DECL (ret) = type_decl;
258 layout_type (ret);
259 ubsan_source_location_type = ret;
260 return ret;
263 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
264 type with its fields filled from a location_t LOC. */
266 static tree
267 ubsan_source_location (location_t loc)
269 expanded_location xloc;
270 tree type = ubsan_get_source_location_type ();
272 xloc = expand_location (loc);
273 tree str;
274 if (xloc.file == NULL)
276 str = build_int_cst (ptr_type_node, 0);
277 xloc.line = 0;
278 xloc.column = 0;
280 else
282 /* Fill in the values from LOC. */
283 size_t len = strlen (xloc.file) + 1;
284 str = build_string (len, xloc.file);
285 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
286 TREE_READONLY (str) = 1;
287 TREE_STATIC (str) = 1;
288 str = build_fold_addr_expr (str);
290 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
291 build_int_cst (unsigned_type_node,
292 xloc.line), NULL_TREE,
293 build_int_cst (unsigned_type_node,
294 xloc.column));
295 TREE_CONSTANT (ctor) = 1;
296 TREE_STATIC (ctor) = 1;
298 return ctor;
301 /* This routine returns a magic number for TYPE. */
303 static unsigned short
304 get_ubsan_type_info_for_type (tree type)
306 if (TREE_CODE (type) == REAL_TYPE)
307 return tree_to_uhwi (TYPE_SIZE (type));
308 else if (INTEGRAL_TYPE_P (type))
310 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
311 gcc_assert (prec != -1);
312 return (prec << 1) | !TYPE_UNSIGNED (type);
314 else
315 return 0;
318 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
319 ubsan_ids[1] for Lubsan_data labels. */
320 static GTY(()) unsigned int ubsan_ids[2];
322 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
323 descriptor. It first looks into the hash table; if not found,
324 create the VAR_DECL, put it into the hash table and return the
325 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
326 an enum controlling how we want to print the type. */
328 tree
329 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
331 /* See through any typedefs. */
332 type = TYPE_MAIN_VARIANT (type);
334 tree decl = decl_for_type_lookup (type);
335 /* It is possible that some of the earlier created DECLs were found
336 unused, in that case they weren't emitted and varpool_node::get
337 returns NULL node on them. But now we really need them. Thus,
338 renew them here. */
339 if (decl != NULL_TREE && varpool_node::get (decl))
340 return build_fold_addr_expr (decl);
342 tree dtype = ubsan_get_type_descriptor_type ();
343 tree type2 = type;
344 const char *tname = NULL;
345 pretty_printer pretty_name;
346 unsigned char deref_depth = 0;
347 unsigned short tkind, tinfo;
349 /* Get the name of the type, or the name of the pointer type. */
350 if (pstyle == UBSAN_PRINT_POINTER)
352 gcc_assert (POINTER_TYPE_P (type));
353 type2 = TREE_TYPE (type);
355 /* Remove any '*' operators from TYPE. */
356 while (POINTER_TYPE_P (type2))
357 deref_depth++, type2 = TREE_TYPE (type2);
359 if (TREE_CODE (type2) == METHOD_TYPE)
360 type2 = TYPE_METHOD_BASETYPE (type2);
363 /* If an array, get its type. */
364 type2 = strip_array_types (type2);
366 if (pstyle == UBSAN_PRINT_ARRAY)
368 while (POINTER_TYPE_P (type2))
369 deref_depth++, type2 = TREE_TYPE (type2);
372 if (TYPE_NAME (type2) != NULL)
374 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
375 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
376 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
377 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
380 if (tname == NULL)
381 /* We weren't able to determine the type name. */
382 tname = "<unknown>";
384 if (pstyle == UBSAN_PRINT_POINTER)
386 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
387 TYPE_VOLATILE (type2) ? "volatile " : "",
388 TYPE_READONLY (type2) ? "const " : "",
389 TYPE_RESTRICT (type2) ? "restrict " : "",
390 TYPE_ATOMIC (type2) ? "_Atomic " : "",
391 TREE_CODE (type2) == RECORD_TYPE
392 ? "struct "
393 : TREE_CODE (type2) == UNION_TYPE
394 ? "union " : "", tname,
395 deref_depth == 0 ? "" : " ");
396 while (deref_depth-- > 0)
397 pp_star (&pretty_name);
398 pp_quote (&pretty_name);
400 else if (pstyle == UBSAN_PRINT_ARRAY)
402 /* Pretty print the array dimensions. */
403 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
404 tree t = type;
405 pp_printf (&pretty_name, "'%s ", tname);
406 while (deref_depth-- > 0)
407 pp_star (&pretty_name);
408 while (TREE_CODE (t) == ARRAY_TYPE)
410 pp_left_bracket (&pretty_name);
411 tree dom = TYPE_DOMAIN (t);
412 if (dom != NULL_TREE
413 && TYPE_MAX_VALUE (dom) != NULL_TREE
414 && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
416 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
417 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
418 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
419 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
420 else
421 pp_wide_int (&pretty_name,
422 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
423 TYPE_SIGN (TREE_TYPE (dom)));
425 else
426 /* ??? We can't determine the variable name; print VLA unspec. */
427 pp_star (&pretty_name);
428 pp_right_bracket (&pretty_name);
429 t = TREE_TYPE (t);
431 pp_quote (&pretty_name);
433 /* Save the tree with stripped types. */
434 type = t;
436 else
437 pp_printf (&pretty_name, "'%s'", tname);
439 switch (TREE_CODE (type))
441 case BOOLEAN_TYPE:
442 case ENUMERAL_TYPE:
443 case INTEGER_TYPE:
444 tkind = 0x0000;
445 break;
446 case REAL_TYPE:
447 /* FIXME: libubsan right now only supports float, double and
448 long double type formats. */
449 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
450 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
451 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
452 tkind = 0x0001;
453 else
454 tkind = 0xffff;
455 break;
456 default:
457 tkind = 0xffff;
458 break;
460 tinfo = get_ubsan_type_info_for_type (type);
462 /* Create a new VAR_DECL of type descriptor. */
463 const char *tmp = pp_formatted_text (&pretty_name);
464 size_t len = strlen (tmp) + 1;
465 tree str = build_string (len, tmp);
466 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
467 TREE_READONLY (str) = 1;
468 TREE_STATIC (str) = 1;
470 char tmp_name[32];
471 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
472 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
473 dtype);
474 TREE_STATIC (decl) = 1;
475 TREE_PUBLIC (decl) = 0;
476 DECL_ARTIFICIAL (decl) = 1;
477 DECL_IGNORED_P (decl) = 1;
478 DECL_EXTERNAL (decl) = 0;
479 DECL_SIZE (decl)
480 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
481 DECL_SIZE_UNIT (decl)
482 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
483 TYPE_SIZE_UNIT (TREE_TYPE (str)));
485 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
486 build_int_cst (short_unsigned_type_node,
487 tkind), NULL_TREE,
488 build_int_cst (short_unsigned_type_node,
489 tinfo), NULL_TREE, str);
490 TREE_CONSTANT (ctor) = 1;
491 TREE_STATIC (ctor) = 1;
492 DECL_INITIAL (decl) = ctor;
493 varpool_node::finalize_decl (decl);
495 /* Save the VAR_DECL into the hash table. */
496 decl_for_type_insert (type, decl);
498 return build_fold_addr_expr (decl);
501 /* Create a structure for the ubsan library. NAME is a name of the new
502 structure. LOCCNT is number of locations, PLOC points to array of
503 locations. The arguments in ... are of __ubsan_type_descriptor type
504 and there are at most two of them, followed by NULL_TREE, followed
505 by optional extra arguments and another NULL_TREE. */
507 tree
508 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
510 va_list args;
511 tree ret, t;
512 tree fields[6];
513 vec<tree, va_gc> *saved_args = NULL;
514 size_t i = 0;
515 int j;
517 /* It is possible that PCH zapped table with definitions of sanitizer
518 builtins. Reinitialize them if needed. */
519 initialize_sanitizer_builtins ();
521 /* Firstly, create a pointer to type descriptor type. */
522 tree td_type = ubsan_get_type_descriptor_type ();
523 td_type = build_pointer_type (td_type);
525 /* Create the structure type. */
526 ret = make_node (RECORD_TYPE);
527 for (j = 0; j < loccnt; j++)
529 gcc_checking_assert (i < 2);
530 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
531 ubsan_get_source_location_type ());
532 DECL_CONTEXT (fields[i]) = ret;
533 if (i)
534 DECL_CHAIN (fields[i - 1]) = fields[i];
535 i++;
538 va_start (args, ploc);
539 for (t = va_arg (args, tree); t != NULL_TREE;
540 i++, t = va_arg (args, tree))
542 gcc_checking_assert (i < 4);
543 /* Save the tree arguments for later use. */
544 vec_safe_push (saved_args, t);
545 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
546 td_type);
547 DECL_CONTEXT (fields[i]) = ret;
548 if (i)
549 DECL_CHAIN (fields[i - 1]) = fields[i];
552 for (t = va_arg (args, tree); t != NULL_TREE;
553 i++, t = va_arg (args, tree))
555 gcc_checking_assert (i < 6);
556 /* Save the tree arguments for later use. */
557 vec_safe_push (saved_args, t);
558 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
559 TREE_TYPE (t));
560 DECL_CONTEXT (fields[i]) = ret;
561 if (i)
562 DECL_CHAIN (fields[i - 1]) = fields[i];
564 va_end (args);
566 tree type_decl = build_decl (input_location, TYPE_DECL,
567 get_identifier (name), ret);
568 DECL_IGNORED_P (type_decl) = 1;
569 DECL_ARTIFICIAL (type_decl) = 1;
570 TYPE_FIELDS (ret) = fields[0];
571 TYPE_NAME (ret) = type_decl;
572 TYPE_STUB_DECL (ret) = type_decl;
573 layout_type (ret);
575 /* Now, fill in the type. */
576 char tmp_name[32];
577 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
578 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
579 ret);
580 TREE_STATIC (var) = 1;
581 TREE_PUBLIC (var) = 0;
582 DECL_ARTIFICIAL (var) = 1;
583 DECL_IGNORED_P (var) = 1;
584 DECL_EXTERNAL (var) = 0;
586 vec<constructor_elt, va_gc> *v;
587 vec_alloc (v, i);
588 tree ctor = build_constructor (ret, v);
590 /* If desirable, set the __ubsan_source_location element. */
591 for (j = 0; j < loccnt; j++)
593 location_t loc = LOCATION_LOCUS (ploc[j]);
594 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
597 size_t nelts = vec_safe_length (saved_args);
598 for (i = 0; i < nelts; i++)
600 t = (*saved_args)[i];
601 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
604 TREE_CONSTANT (ctor) = 1;
605 TREE_STATIC (ctor) = 1;
606 DECL_INITIAL (var) = ctor;
607 varpool_node::finalize_decl (var);
609 return var;
612 /* Instrument the __builtin_unreachable call. We just call the libubsan
613 routine instead. */
615 bool
616 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
618 gimple *g;
619 location_t loc = gimple_location (gsi_stmt (*gsi));
621 if (flag_sanitize_undefined_trap_on_error)
622 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
623 else
625 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
626 NULL_TREE, NULL_TREE);
627 data = build_fold_addr_expr_loc (loc, data);
628 tree fn
629 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
630 g = gimple_build_call (fn, 1, data);
632 gimple_set_location (g, loc);
633 gsi_replace (gsi, g, false);
634 return false;
637 /* Return true if T is a call to a libubsan routine. */
639 bool
640 is_ubsan_builtin_p (tree t)
642 return TREE_CODE (t) == FUNCTION_DECL
643 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
644 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
645 "__builtin___ubsan_", 18) == 0;
648 /* Create a callgraph edge for statement STMT. */
650 static void
651 ubsan_create_edge (gimple *stmt)
653 gcall *call_stmt = dyn_cast <gcall *> (stmt);
654 basic_block bb = gimple_bb (stmt);
655 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
656 cgraph_node *node = cgraph_node::get (current_function_decl);
657 tree decl = gimple_call_fndecl (call_stmt);
658 if (decl)
659 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
660 freq);
663 /* Expand the UBSAN_BOUNDS special builtin function. */
665 bool
666 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
668 gimple *stmt = gsi_stmt (*gsi);
669 location_t loc = gimple_location (stmt);
670 gcc_assert (gimple_call_num_args (stmt) == 3);
672 /* Pick up the arguments of the UBSAN_BOUNDS call. */
673 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
674 tree index = gimple_call_arg (stmt, 1);
675 tree orig_index_type = TREE_TYPE (index);
676 tree bound = gimple_call_arg (stmt, 2);
678 gimple_stmt_iterator gsi_orig = *gsi;
680 /* Create condition "if (index > bound)". */
681 basic_block then_bb, fallthru_bb;
682 gimple_stmt_iterator cond_insert_point
683 = create_cond_insert_point (gsi, false, false, true,
684 &then_bb, &fallthru_bb);
685 index = fold_convert (TREE_TYPE (bound), index);
686 index = force_gimple_operand_gsi (&cond_insert_point, index,
687 true, NULL_TREE,
688 false, GSI_NEW_STMT);
689 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
690 gimple_set_location (g, loc);
691 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
693 /* Generate __ubsan_handle_out_of_bounds call. */
694 *gsi = gsi_after_labels (then_bb);
695 if (flag_sanitize_undefined_trap_on_error)
696 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
697 else
699 tree data
700 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
701 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
702 ubsan_type_descriptor (orig_index_type),
703 NULL_TREE, NULL_TREE);
704 data = build_fold_addr_expr_loc (loc, data);
705 enum built_in_function bcode
706 = (flag_sanitize_recover & SANITIZE_BOUNDS)
707 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
708 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
709 tree fn = builtin_decl_explicit (bcode);
710 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
711 true, NULL_TREE, true,
712 GSI_SAME_STMT);
713 g = gimple_build_call (fn, 2, data, val);
715 gimple_set_location (g, loc);
716 gsi_insert_before (gsi, g, GSI_SAME_STMT);
718 /* Get rid of the UBSAN_BOUNDS call from the IR. */
719 unlink_stmt_vdef (stmt);
720 gsi_remove (&gsi_orig, true);
722 /* Point GSI to next logical statement. */
723 *gsi = gsi_start_bb (fallthru_bb);
724 return true;
727 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
728 argument which is a constant, because the middle-end treats pointer
729 conversions as useless and therefore the type of the first argument
730 could be changed to any other pointer type. */
732 bool
733 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
735 gimple_stmt_iterator gsi = *gsip;
736 gimple *stmt = gsi_stmt (gsi);
737 location_t loc = gimple_location (stmt);
738 gcc_assert (gimple_call_num_args (stmt) == 3);
739 tree ptr = gimple_call_arg (stmt, 0);
740 tree ckind = gimple_call_arg (stmt, 1);
741 tree align = gimple_call_arg (stmt, 2);
742 tree check_align = NULL_TREE;
743 bool check_null;
745 basic_block cur_bb = gsi_bb (gsi);
747 gimple *g;
748 if (!integer_zerop (align))
750 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
751 if (compare_tree_int (align, ptralign) == 1)
753 check_align = make_ssa_name (pointer_sized_int_node);
754 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
755 gimple_set_location (g, loc);
756 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
759 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
761 if (check_align == NULL_TREE && !check_null)
763 gsi_remove (gsip, true);
764 /* Unlink the UBSAN_NULLs vops before replacing it. */
765 unlink_stmt_vdef (stmt);
766 return true;
769 /* Split the original block holding the pointer dereference. */
770 edge e = split_block (cur_bb, stmt);
772 /* Get a hold on the 'condition block', the 'then block' and the
773 'else block'. */
774 basic_block cond_bb = e->src;
775 basic_block fallthru_bb = e->dest;
776 basic_block then_bb = create_empty_bb (cond_bb);
777 add_bb_to_loop (then_bb, cond_bb->loop_father);
778 loops_state_set (LOOPS_NEED_FIXUP);
780 /* Make an edge coming from the 'cond block' into the 'then block';
781 this edge is unlikely taken, so set up the probability accordingly. */
782 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
783 e->probability = PROB_VERY_UNLIKELY;
785 /* Connect 'then block' with the 'else block'. This is needed
786 as the ubsan routines we call in the 'then block' are not noreturn.
787 The 'then block' only has one outcoming edge. */
788 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
790 /* Set up the fallthrough basic block. */
791 e = find_edge (cond_bb, fallthru_bb);
792 e->flags = EDGE_FALSE_VALUE;
793 e->count = cond_bb->count;
794 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
796 /* Update dominance info for the newly created then_bb; note that
797 fallthru_bb's dominance info has already been updated by
798 split_block. */
799 if (dom_info_available_p (CDI_DOMINATORS))
800 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
802 /* Put the ubsan builtin call into the newly created BB. */
803 if (flag_sanitize_undefined_trap_on_error)
804 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
805 else
807 enum built_in_function bcode
808 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
809 | (check_null ? SANITIZE_NULL : 0)))
810 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
811 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
812 tree fn = builtin_decl_implicit (bcode);
813 tree data
814 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
815 ubsan_type_descriptor (TREE_TYPE (ckind),
816 UBSAN_PRINT_POINTER),
817 NULL_TREE,
818 align,
819 fold_convert (unsigned_char_type_node, ckind),
820 NULL_TREE);
821 data = build_fold_addr_expr_loc (loc, data);
822 g = gimple_build_call (fn, 2, data,
823 check_align ? check_align
824 : build_zero_cst (pointer_sized_int_node));
826 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
827 gimple_set_location (g, loc);
828 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
830 /* Unlink the UBSAN_NULLs vops before replacing it. */
831 unlink_stmt_vdef (stmt);
833 if (check_null)
835 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
836 NULL_TREE, NULL_TREE);
837 gimple_set_location (g, loc);
839 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
840 gsi_replace (&gsi, g, false);
841 stmt = g;
844 if (check_align)
846 if (check_null)
848 /* Split the block with the condition again. */
849 e = split_block (cond_bb, stmt);
850 basic_block cond1_bb = e->src;
851 basic_block cond2_bb = e->dest;
853 /* Make an edge coming from the 'cond1 block' into the 'then block';
854 this edge is unlikely taken, so set up the probability
855 accordingly. */
856 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
857 e->probability = PROB_VERY_UNLIKELY;
859 /* Set up the fallthrough basic block. */
860 e = find_edge (cond1_bb, cond2_bb);
861 e->flags = EDGE_FALSE_VALUE;
862 e->count = cond1_bb->count;
863 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
865 /* Update dominance info. */
866 if (dom_info_available_p (CDI_DOMINATORS))
868 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
869 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
872 gsi2 = gsi_start_bb (cond2_bb);
875 tree mask = build_int_cst (pointer_sized_int_node,
876 tree_to_uhwi (align) - 1);
877 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
878 BIT_AND_EXPR, check_align, mask);
879 gimple_set_location (g, loc);
880 if (check_null)
881 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
882 else
883 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
885 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
886 build_int_cst (pointer_sized_int_node, 0),
887 NULL_TREE, NULL_TREE);
888 gimple_set_location (g, loc);
889 if (check_null)
890 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
891 else
892 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
893 gsi_replace (&gsi, g, false);
895 return false;
898 #define OBJSZ_MAX_OFFSET (1024 * 16)
900 /* Expand UBSAN_OBJECT_SIZE internal call. */
902 bool
903 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
905 gimple *stmt = gsi_stmt (*gsi);
906 location_t loc = gimple_location (stmt);
907 gcc_assert (gimple_call_num_args (stmt) == 4);
909 tree ptr = gimple_call_arg (stmt, 0);
910 tree offset = gimple_call_arg (stmt, 1);
911 tree size = gimple_call_arg (stmt, 2);
912 tree ckind = gimple_call_arg (stmt, 3);
913 gimple_stmt_iterator gsi_orig = *gsi;
914 gimple *g;
916 /* See if we can discard the check. */
917 if (TREE_CODE (size) != INTEGER_CST
918 || integer_all_onesp (size))
919 /* Yes, __builtin_object_size couldn't determine the
920 object size. */;
921 else if (TREE_CODE (offset) == INTEGER_CST
922 && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
923 && wi::to_widest (offset) <= -1)
924 /* The offset is in range [-16K, -1]. */;
925 else
927 /* if (offset > objsize) */
928 basic_block then_bb, fallthru_bb;
929 gimple_stmt_iterator cond_insert_point
930 = create_cond_insert_point (gsi, false, false, true,
931 &then_bb, &fallthru_bb);
932 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
933 gimple_set_location (g, loc);
934 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
936 /* If the offset is small enough, we don't need the second
937 run-time check. */
938 if (TREE_CODE (offset) == INTEGER_CST
939 && wi::to_widest (offset) >= 0
940 && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
941 *gsi = gsi_after_labels (then_bb);
942 else
944 /* Don't issue run-time error if (ptr > ptr + offset). That
945 may happen when computing a POINTER_PLUS_EXPR. */
946 basic_block then2_bb, fallthru2_bb;
948 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
949 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
950 true, &then2_bb,
951 &fallthru2_bb);
952 /* Convert the pointer to an integer type. */
953 tree p = make_ssa_name (pointer_sized_int_node);
954 g = gimple_build_assign (p, NOP_EXPR, ptr);
955 gimple_set_location (g, loc);
956 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
957 p = gimple_assign_lhs (g);
958 /* Compute ptr + offset. */
959 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
960 PLUS_EXPR, p, offset);
961 gimple_set_location (g, loc);
962 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
963 /* Now build the conditional and put it into the IR. */
964 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
965 NULL_TREE, NULL_TREE);
966 gimple_set_location (g, loc);
967 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
968 *gsi = gsi_after_labels (then2_bb);
971 /* Generate __ubsan_handle_type_mismatch call. */
972 if (flag_sanitize_undefined_trap_on_error)
973 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
974 else
976 tree data
977 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
978 ubsan_type_descriptor (TREE_TYPE (ptr),
979 UBSAN_PRINT_POINTER),
980 NULL_TREE,
981 build_zero_cst (pointer_sized_int_node),
982 ckind,
983 NULL_TREE);
984 data = build_fold_addr_expr_loc (loc, data);
985 enum built_in_function bcode
986 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
987 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
988 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
989 tree p = make_ssa_name (pointer_sized_int_node);
990 g = gimple_build_assign (p, NOP_EXPR, ptr);
991 gimple_set_location (g, loc);
992 gsi_insert_before (gsi, g, GSI_SAME_STMT);
993 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
995 gimple_set_location (g, loc);
996 gsi_insert_before (gsi, g, GSI_SAME_STMT);
998 /* Point GSI to next logical statement. */
999 *gsi = gsi_start_bb (fallthru_bb);
1001 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1002 unlink_stmt_vdef (stmt);
1003 gsi_remove (&gsi_orig, true);
1004 return true;
1007 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1008 unlink_stmt_vdef (stmt);
1009 gsi_remove (gsi, true);
1010 return true;
1013 /* Cached __ubsan_vptr_type_cache decl. */
1014 static GTY(()) tree ubsan_vptr_type_cache_decl;
1016 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1017 argument which is a constant, because the middle-end treats pointer
1018 conversions as useless and therefore the type of the first argument
1019 could be changed to any other pointer type. */
1021 bool
1022 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1024 gimple_stmt_iterator gsi = *gsip;
1025 gimple *stmt = gsi_stmt (gsi);
1026 location_t loc = gimple_location (stmt);
1027 gcc_assert (gimple_call_num_args (stmt) == 5);
1028 tree op = gimple_call_arg (stmt, 0);
1029 tree vptr = gimple_call_arg (stmt, 1);
1030 tree str_hash = gimple_call_arg (stmt, 2);
1031 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1032 tree ckind_tree = gimple_call_arg (stmt, 4);
1033 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1034 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1035 gimple *g;
1036 basic_block fallthru_bb = NULL;
1038 if (ckind == UBSAN_DOWNCAST_POINTER)
1040 /* Guard everything with if (op != NULL) { ... }. */
1041 basic_block then_bb;
1042 gimple_stmt_iterator cond_insert_point
1043 = create_cond_insert_point (gsip, false, false, true,
1044 &then_bb, &fallthru_bb);
1045 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1046 NULL_TREE, NULL_TREE);
1047 gimple_set_location (g, loc);
1048 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1049 *gsip = gsi_after_labels (then_bb);
1050 gsi_remove (&gsi, false);
1051 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1052 gsi = *gsip;
1055 tree htype = TREE_TYPE (str_hash);
1056 tree cst = wide_int_to_tree (htype,
1057 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1058 | 0xeb382d69, 64));
1059 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1060 vptr, str_hash);
1061 gimple_set_location (g, loc);
1062 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1063 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1064 gimple_assign_lhs (g), cst);
1065 gimple_set_location (g, loc);
1066 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1067 tree t1 = gimple_assign_lhs (g);
1068 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1069 t1, build_int_cst (integer_type_node, 47));
1070 gimple_set_location (g, loc);
1071 tree t2 = gimple_assign_lhs (g);
1072 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1073 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1074 vptr, t1);
1075 gimple_set_location (g, loc);
1076 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1077 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1078 t2, gimple_assign_lhs (g));
1079 gimple_set_location (g, loc);
1080 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1081 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1082 gimple_assign_lhs (g), cst);
1083 gimple_set_location (g, loc);
1084 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1085 tree t3 = gimple_assign_lhs (g);
1086 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1087 t3, build_int_cst (integer_type_node, 47));
1088 gimple_set_location (g, loc);
1089 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1090 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1091 t3, gimple_assign_lhs (g));
1092 gimple_set_location (g, loc);
1093 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1094 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1095 gimple_assign_lhs (g), cst);
1096 gimple_set_location (g, loc);
1097 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1098 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1100 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1101 NOP_EXPR, gimple_assign_lhs (g));
1102 gimple_set_location (g, loc);
1103 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1105 tree hash = gimple_assign_lhs (g);
1107 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1109 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1110 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1111 get_identifier ("__ubsan_vptr_type_cache"),
1112 atype);
1113 DECL_ARTIFICIAL (array) = 1;
1114 DECL_IGNORED_P (array) = 1;
1115 TREE_PUBLIC (array) = 1;
1116 TREE_STATIC (array) = 1;
1117 DECL_EXTERNAL (array) = 1;
1118 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1119 DECL_VISIBILITY_SPECIFIED (array) = 1;
1120 varpool_node::finalize_decl (array);
1121 ubsan_vptr_type_cache_decl = array;
1124 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1125 BIT_AND_EXPR, hash,
1126 build_int_cst (pointer_sized_int_node, 127));
1127 gimple_set_location (g, loc);
1128 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1130 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1131 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1132 NULL_TREE, NULL_TREE);
1133 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1134 ARRAY_REF, c);
1135 gimple_set_location (g, loc);
1136 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1138 basic_block then_bb, fallthru2_bb;
1139 gimple_stmt_iterator cond_insert_point
1140 = create_cond_insert_point (gsip, false, false, true,
1141 &then_bb, &fallthru2_bb);
1142 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1143 NULL_TREE, NULL_TREE);
1144 gimple_set_location (g, loc);
1145 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1146 *gsip = gsi_after_labels (then_bb);
1147 if (fallthru_bb == NULL)
1148 fallthru_bb = fallthru2_bb;
1150 tree data
1151 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1152 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1153 build_int_cst (unsigned_char_type_node, ckind),
1154 NULL_TREE);
1155 data = build_fold_addr_expr_loc (loc, data);
1156 enum built_in_function bcode
1157 = (flag_sanitize_recover & SANITIZE_VPTR)
1158 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1159 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1161 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1162 gimple_set_location (g, loc);
1163 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1165 /* Point GSI to next logical statement. */
1166 *gsip = gsi_start_bb (fallthru_bb);
1168 /* Get rid of the UBSAN_VPTR call from the IR. */
1169 unlink_stmt_vdef (stmt);
1170 gsi_remove (&gsi, true);
1171 return true;
1174 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1175 whether the pointer is on the left hand side of the assignment. */
1177 static void
1178 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1179 bool is_lhs)
1181 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1182 unsigned int align = 0;
1183 if (flag_sanitize & SANITIZE_ALIGNMENT)
1185 align = min_align_of_type (TREE_TYPE (base));
1186 if (align <= 1)
1187 align = 0;
1189 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1190 return;
1191 tree t = TREE_OPERAND (base, 0);
1192 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1193 return;
1194 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1195 ikind = UBSAN_MEMBER_ACCESS;
1196 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1197 tree alignt = build_int_cst (pointer_sized_int_node, align);
1198 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1199 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1200 gsi_insert_before (iter, g, GSI_SAME_STMT);
1203 /* Perform the pointer instrumentation. */
1205 static void
1206 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1208 gimple *stmt = gsi_stmt (gsi);
1209 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1210 tree base = get_base_address (t);
1211 const enum tree_code code = TREE_CODE (base);
1212 if (code == MEM_REF
1213 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1214 instrument_mem_ref (t, base, &gsi, is_lhs);
1217 /* Build an ubsan builtin call for the signed-integer-overflow
1218 sanitization. CODE says what kind of builtin are we building,
1219 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1220 are operands of the binary operation. */
1222 tree
1223 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1224 tree op0, tree op1, tree *datap)
1226 if (flag_sanitize_undefined_trap_on_error)
1227 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1229 tree data;
1230 if (datap && *datap)
1231 data = *datap;
1232 else
1233 data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1234 ubsan_type_descriptor (lhstype), NULL_TREE,
1235 NULL_TREE);
1236 if (datap)
1237 *datap = data;
1238 enum built_in_function fn_code;
1240 switch (code)
1242 case PLUS_EXPR:
1243 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1244 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1245 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1246 break;
1247 case MINUS_EXPR:
1248 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1249 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1250 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1251 break;
1252 case MULT_EXPR:
1253 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1254 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1255 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1256 break;
1257 case NEGATE_EXPR:
1258 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1259 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1260 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1261 break;
1262 default:
1263 gcc_unreachable ();
1265 tree fn = builtin_decl_explicit (fn_code);
1266 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1267 build_fold_addr_expr_loc (loc, data),
1268 ubsan_encode_value (op0, true),
1269 op1 ? ubsan_encode_value (op1, true)
1270 : NULL_TREE);
1273 /* Perform the signed integer instrumentation. GSI is the iterator
1274 pointing at statement we are trying to instrument. */
1276 static void
1277 instrument_si_overflow (gimple_stmt_iterator gsi)
1279 gimple *stmt = gsi_stmt (gsi);
1280 tree_code code = gimple_assign_rhs_code (stmt);
1281 tree lhs = gimple_assign_lhs (stmt);
1282 tree lhstype = TREE_TYPE (lhs);
1283 tree lhsinner = VECTOR_TYPE_P (lhstype) ? TREE_TYPE (lhstype) : lhstype;
1284 tree a, b;
1285 gimple *g;
1287 /* If this is not a signed operation, don't instrument anything here.
1288 Also punt on bit-fields. */
1289 if (!INTEGRAL_TYPE_P (lhsinner)
1290 || TYPE_OVERFLOW_WRAPS (lhsinner)
1291 || GET_MODE_BITSIZE (TYPE_MODE (lhsinner)) != TYPE_PRECISION (lhsinner))
1292 return;
1294 switch (code)
1296 case MINUS_EXPR:
1297 case PLUS_EXPR:
1298 case MULT_EXPR:
1299 /* Transform
1300 i = u {+,-,*} 5;
1301 into
1302 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1303 a = gimple_assign_rhs1 (stmt);
1304 b = gimple_assign_rhs2 (stmt);
1305 g = gimple_build_call_internal (code == PLUS_EXPR
1306 ? IFN_UBSAN_CHECK_ADD
1307 : code == MINUS_EXPR
1308 ? IFN_UBSAN_CHECK_SUB
1309 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1310 gimple_call_set_lhs (g, lhs);
1311 gsi_replace (&gsi, g, true);
1312 break;
1313 case NEGATE_EXPR:
1314 /* Represent i = -u;
1316 i = UBSAN_CHECK_SUB (0, u); */
1317 a = build_zero_cst (lhstype);
1318 b = gimple_assign_rhs1 (stmt);
1319 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1320 gimple_call_set_lhs (g, lhs);
1321 gsi_replace (&gsi, g, true);
1322 break;
1323 case ABS_EXPR:
1324 /* Transform i = ABS_EXPR<u>;
1325 into
1326 _N = UBSAN_CHECK_SUB (0, u);
1327 i = ABS_EXPR<_N>; */
1328 a = build_zero_cst (lhstype);
1329 b = gimple_assign_rhs1 (stmt);
1330 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1331 a = make_ssa_name (lhstype);
1332 gimple_call_set_lhs (g, a);
1333 gimple_set_location (g, gimple_location (stmt));
1334 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1335 gimple_assign_set_rhs1 (stmt, a);
1336 update_stmt (stmt);
1337 break;
1338 default:
1339 break;
1343 /* Instrument loads from (non-bitfield) bool and C++ enum values
1344 to check if the memory value is outside of the range of the valid
1345 type values. */
1347 static void
1348 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1350 gimple *stmt = gsi_stmt (*gsi);
1351 tree rhs = gimple_assign_rhs1 (stmt);
1352 tree type = TREE_TYPE (rhs);
1353 tree minv = NULL_TREE, maxv = NULL_TREE;
1355 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1357 minv = boolean_false_node;
1358 maxv = boolean_true_node;
1360 else if (TREE_CODE (type) == ENUMERAL_TYPE
1361 && (flag_sanitize & SANITIZE_ENUM)
1362 && TREE_TYPE (type) != NULL_TREE
1363 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1364 && (TYPE_PRECISION (TREE_TYPE (type))
1365 < GET_MODE_PRECISION (TYPE_MODE (type))))
1367 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1368 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1370 else
1371 return;
1373 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1374 HOST_WIDE_INT bitsize, bitpos;
1375 tree offset;
1376 machine_mode mode;
1377 int volatilep = 0, reversep, unsignedp = 0;
1378 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1379 &unsignedp, &reversep, &volatilep);
1380 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1382 if ((VAR_P (base) && DECL_HARD_REGISTER (base))
1383 || (bitpos % modebitsize) != 0
1384 || bitsize != modebitsize
1385 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1386 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1387 return;
1389 bool ends_bb = stmt_ends_bb_p (stmt);
1390 location_t loc = gimple_location (stmt);
1391 tree lhs = gimple_assign_lhs (stmt);
1392 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1393 tree atype = reference_alias_ptr_type (rhs);
1394 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1395 build_fold_addr_expr (rhs));
1396 gimple_set_location (g, loc);
1397 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1398 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1399 build_int_cst (atype, 0));
1400 tree urhs = make_ssa_name (utype);
1401 if (ends_bb)
1403 gimple_assign_set_lhs (stmt, urhs);
1404 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1405 gimple_set_location (g, loc);
1406 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1407 gsi_insert_on_edge_immediate (e, g);
1408 gimple_assign_set_rhs_from_tree (gsi, mem);
1409 update_stmt (stmt);
1410 *gsi = gsi_for_stmt (g);
1411 g = stmt;
1413 else
1415 g = gimple_build_assign (urhs, mem);
1416 gimple_set_location (g, loc);
1417 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1419 minv = fold_convert (utype, minv);
1420 maxv = fold_convert (utype, maxv);
1421 if (!integer_zerop (minv))
1423 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1424 gimple_set_location (g, loc);
1425 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1428 gimple_stmt_iterator gsi2 = *gsi;
1429 basic_block then_bb, fallthru_bb;
1430 *gsi = create_cond_insert_point (gsi, true, false, true,
1431 &then_bb, &fallthru_bb);
1432 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1433 int_const_binop (MINUS_EXPR, maxv, minv),
1434 NULL_TREE, NULL_TREE);
1435 gimple_set_location (g, loc);
1436 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1438 if (!ends_bb)
1440 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1441 update_stmt (stmt);
1444 gsi2 = gsi_after_labels (then_bb);
1445 if (flag_sanitize_undefined_trap_on_error)
1446 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1447 else
1449 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1450 ubsan_type_descriptor (type), NULL_TREE,
1451 NULL_TREE);
1452 data = build_fold_addr_expr_loc (loc, data);
1453 enum built_in_function bcode
1454 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1455 ? SANITIZE_BOOL : SANITIZE_ENUM))
1456 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1457 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1458 tree fn = builtin_decl_explicit (bcode);
1460 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1461 true, NULL_TREE, true,
1462 GSI_SAME_STMT);
1463 g = gimple_build_call (fn, 2, data, val);
1465 gimple_set_location (g, loc);
1466 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1467 ubsan_create_edge (g);
1468 *gsi = gsi_for_stmt (stmt);
1471 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1472 new style handlers. Libubsan uses heuristics to destinguish between old and
1473 new styles and relies on these properties for filename:
1475 a) Location's filename must not be NULL.
1476 b) Location's filename must not be equal to "".
1477 c) Location's filename must not be equal to "\1".
1478 d) First two bytes of filename must not contain '\xff' symbol. */
1480 static bool
1481 ubsan_use_new_style_p (location_t loc)
1483 if (loc == UNKNOWN_LOCATION)
1484 return false;
1486 expanded_location xloc = expand_location (loc);
1487 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1488 || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1489 || xloc.file[1] == '\xff')
1490 return false;
1492 return true;
1495 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1496 destination, EXPR is floating-point expression. */
1498 tree
1499 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1501 tree expr_type = TREE_TYPE (expr);
1502 tree t, tt, fn, min, max;
1503 machine_mode mode = TYPE_MODE (expr_type);
1504 int prec = TYPE_PRECISION (type);
1505 bool uns_p = TYPE_UNSIGNED (type);
1506 if (loc == UNKNOWN_LOCATION)
1507 loc = input_location;
1509 /* Float to integer conversion first truncates toward zero, so
1510 even signed char c = 127.875f; is not problematic.
1511 Therefore, we should complain only if EXPR is unordered or smaller
1512 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1513 TYPE_MAX_VALUE + 1.0. */
1514 if (REAL_MODE_FORMAT (mode)->b == 2)
1516 /* For maximum, TYPE_MAX_VALUE might not be representable
1517 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1518 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1519 either representable or infinity. */
1520 REAL_VALUE_TYPE maxval = dconst1;
1521 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1522 real_convert (&maxval, mode, &maxval);
1523 max = build_real (expr_type, maxval);
1525 /* For unsigned, assume -1.0 is always representable. */
1526 if (uns_p)
1527 min = build_minus_one_cst (expr_type);
1528 else
1530 /* TYPE_MIN_VALUE is generally representable (or -inf),
1531 but TYPE_MIN_VALUE - 1.0 might not be. */
1532 REAL_VALUE_TYPE minval = dconstm1, minval2;
1533 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1534 real_convert (&minval, mode, &minval);
1535 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1536 real_convert (&minval2, mode, &minval2);
1537 if (real_compare (EQ_EXPR, &minval, &minval2)
1538 && !real_isinf (&minval))
1540 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1541 rounds to TYPE_MIN_VALUE, we need to subtract
1542 more. As REAL_MODE_FORMAT (mode)->p is the number
1543 of base digits, we want to subtract a number that
1544 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1545 times smaller than minval. */
1546 minval2 = dconst1;
1547 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1548 SET_REAL_EXP (&minval2,
1549 REAL_EXP (&minval2) + prec - 1
1550 - REAL_MODE_FORMAT (mode)->p + 1);
1551 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1552 real_convert (&minval2, mode, &minval2);
1554 min = build_real (expr_type, minval2);
1557 else if (REAL_MODE_FORMAT (mode)->b == 10)
1559 /* For _Decimal128 up to 34 decimal digits, - sign,
1560 dot, e, exponent. */
1561 char buf[64];
1562 mpfr_t m;
1563 int p = REAL_MODE_FORMAT (mode)->p;
1564 REAL_VALUE_TYPE maxval, minval;
1566 /* Use mpfr_snprintf rounding to compute the smallest
1567 representable decimal number greater or equal than
1568 1 << (prec - !uns_p). */
1569 mpfr_init2 (m, prec + 2);
1570 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1571 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1572 decimal_real_from_string (&maxval, buf);
1573 max = build_real (expr_type, maxval);
1575 /* For unsigned, assume -1.0 is always representable. */
1576 if (uns_p)
1577 min = build_minus_one_cst (expr_type);
1578 else
1580 /* Use mpfr_snprintf rounding to compute the largest
1581 representable decimal number less or equal than
1582 (-1 << (prec - 1)) - 1. */
1583 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1584 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1585 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1586 decimal_real_from_string (&minval, buf);
1587 min = build_real (expr_type, minval);
1589 mpfr_clear (m);
1591 else
1592 return NULL_TREE;
1594 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1595 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1596 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1597 if (integer_zerop (t))
1598 return NULL_TREE;
1600 if (flag_sanitize_undefined_trap_on_error)
1601 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1602 else
1604 location_t *loc_ptr = NULL;
1605 unsigned num_locations = 0;
1606 /* Figure out if we can propagate location to ubsan_data and use new
1607 style handlers in libubsan. */
1608 if (ubsan_use_new_style_p (loc))
1610 loc_ptr = &loc;
1611 num_locations = 1;
1613 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1614 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1615 num_locations, loc_ptr,
1616 ubsan_type_descriptor (expr_type),
1617 ubsan_type_descriptor (type), NULL_TREE,
1618 NULL_TREE);
1619 enum built_in_function bcode
1620 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1621 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1622 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1623 fn = builtin_decl_explicit (bcode);
1624 fn = build_call_expr_loc (loc, fn, 2,
1625 build_fold_addr_expr_loc (loc, data),
1626 ubsan_encode_value (expr, false));
1629 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1632 /* Instrument values passed to function arguments with nonnull attribute. */
1634 static void
1635 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1637 gimple *stmt = gsi_stmt (*gsi);
1638 location_t loc[2];
1639 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1640 while for nonnull sanitization it is clear. */
1641 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1642 flag_delete_null_pointer_checks = 1;
1643 loc[0] = gimple_location (stmt);
1644 loc[1] = UNKNOWN_LOCATION;
1645 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1647 tree arg = gimple_call_arg (stmt, i);
1648 if (POINTER_TYPE_P (TREE_TYPE (arg))
1649 && infer_nonnull_range_by_attribute (stmt, arg))
1651 gimple *g;
1652 if (!is_gimple_val (arg))
1654 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1655 gimple_set_location (g, loc[0]);
1656 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1657 arg = gimple_assign_lhs (g);
1660 basic_block then_bb, fallthru_bb;
1661 *gsi = create_cond_insert_point (gsi, true, false, true,
1662 &then_bb, &fallthru_bb);
1663 g = gimple_build_cond (EQ_EXPR, arg,
1664 build_zero_cst (TREE_TYPE (arg)),
1665 NULL_TREE, NULL_TREE);
1666 gimple_set_location (g, loc[0]);
1667 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1669 *gsi = gsi_after_labels (then_bb);
1670 if (flag_sanitize_undefined_trap_on_error)
1671 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1672 else
1674 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1675 2, loc, NULL_TREE,
1676 build_int_cst (integer_type_node,
1677 i + 1),
1678 NULL_TREE);
1679 data = build_fold_addr_expr_loc (loc[0], data);
1680 enum built_in_function bcode
1681 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1682 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1683 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1684 tree fn = builtin_decl_explicit (bcode);
1686 g = gimple_build_call (fn, 1, data);
1688 gimple_set_location (g, loc[0]);
1689 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1690 ubsan_create_edge (g);
1692 *gsi = gsi_for_stmt (stmt);
1694 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1697 /* Instrument returns in functions with returns_nonnull attribute. */
1699 static void
1700 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1702 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1703 location_t loc[2];
1704 tree arg = gimple_return_retval (stmt);
1705 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1706 while for nonnull return sanitization it is clear. */
1707 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1708 flag_delete_null_pointer_checks = 1;
1709 loc[0] = gimple_location (stmt);
1710 loc[1] = UNKNOWN_LOCATION;
1711 if (arg
1712 && POINTER_TYPE_P (TREE_TYPE (arg))
1713 && is_gimple_val (arg)
1714 && infer_nonnull_range_by_attribute (stmt, arg))
1716 basic_block then_bb, fallthru_bb;
1717 *gsi = create_cond_insert_point (gsi, true, false, true,
1718 &then_bb, &fallthru_bb);
1719 gimple *g = gimple_build_cond (EQ_EXPR, arg,
1720 build_zero_cst (TREE_TYPE (arg)),
1721 NULL_TREE, NULL_TREE);
1722 gimple_set_location (g, loc[0]);
1723 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1725 *gsi = gsi_after_labels (then_bb);
1726 if (flag_sanitize_undefined_trap_on_error)
1727 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1728 else
1730 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1731 2, loc, NULL_TREE, NULL_TREE);
1732 data = build_fold_addr_expr_loc (loc[0], data);
1733 enum built_in_function bcode
1734 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1735 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1736 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1737 tree fn = builtin_decl_explicit (bcode);
1739 g = gimple_build_call (fn, 1, data);
1741 gimple_set_location (g, loc[0]);
1742 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1743 ubsan_create_edge (g);
1744 *gsi = gsi_for_stmt (stmt);
1746 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1749 /* Instrument memory references. Here we check whether the pointer
1750 points to an out-of-bounds location. */
1752 static void
1753 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1755 gimple *stmt = gsi_stmt (*gsi);
1756 location_t loc = gimple_location (stmt);
1757 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1758 tree type;
1759 tree index = NULL_TREE;
1760 HOST_WIDE_INT size_in_bytes;
1762 type = TREE_TYPE (t);
1763 if (VOID_TYPE_P (type))
1764 return;
1766 switch (TREE_CODE (t))
1768 case COMPONENT_REF:
1769 if (TREE_CODE (t) == COMPONENT_REF
1770 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1772 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1773 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1774 repr, NULL_TREE);
1776 break;
1777 case ARRAY_REF:
1778 index = TREE_OPERAND (t, 1);
1779 break;
1780 case INDIRECT_REF:
1781 case MEM_REF:
1782 case VAR_DECL:
1783 case PARM_DECL:
1784 case RESULT_DECL:
1785 break;
1786 default:
1787 return;
1790 size_in_bytes = int_size_in_bytes (type);
1791 if (size_in_bytes <= 0)
1792 return;
1794 HOST_WIDE_INT bitsize, bitpos;
1795 tree offset;
1796 machine_mode mode;
1797 int volatilep = 0, reversep, unsignedp = 0;
1798 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1799 &unsignedp, &reversep, &volatilep);
1801 if (bitpos % BITS_PER_UNIT != 0
1802 || bitsize != size_in_bytes * BITS_PER_UNIT)
1803 return;
1805 bool decl_p = DECL_P (inner);
1806 tree base;
1807 if (decl_p)
1808 base = inner;
1809 else if (TREE_CODE (inner) == MEM_REF)
1810 base = TREE_OPERAND (inner, 0);
1811 else
1812 return;
1813 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1815 while (TREE_CODE (base) == SSA_NAME)
1817 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
1818 if (gimple_assign_ssa_name_copy_p (def_stmt)
1819 || (gimple_assign_cast_p (def_stmt)
1820 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1821 || (is_gimple_assign (def_stmt)
1822 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1824 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1825 if (TREE_CODE (rhs1) == SSA_NAME
1826 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1827 break;
1828 else
1829 base = rhs1;
1831 else
1832 break;
1835 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1836 return;
1838 tree sizet;
1839 tree base_addr = base;
1840 gimple *bos_stmt = NULL;
1841 if (decl_p)
1842 base_addr = build1 (ADDR_EXPR,
1843 build_pointer_type (TREE_TYPE (base)), base);
1844 unsigned HOST_WIDE_INT size;
1845 if (compute_builtin_object_size (base_addr, 0, &size))
1846 sizet = build_int_cst (sizetype, size);
1847 else if (optimize)
1849 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1850 loc = input_location;
1851 /* Generate __builtin_object_size call. */
1852 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1853 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1854 integer_zero_node);
1855 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1856 GSI_SAME_STMT);
1857 /* If the call above didn't end up being an integer constant, go one
1858 statement back and get the __builtin_object_size stmt. Save it,
1859 we might need it later. */
1860 if (SSA_VAR_P (sizet))
1862 gsi_prev (gsi);
1863 bos_stmt = gsi_stmt (*gsi);
1865 /* Move on to where we were. */
1866 gsi_next (gsi);
1869 else
1870 return;
1872 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1873 call. */
1874 /* ptr + sizeof (*ptr) - base */
1875 t = fold_build2 (MINUS_EXPR, sizetype,
1876 fold_convert (pointer_sized_int_node, ptr),
1877 fold_convert (pointer_sized_int_node, base_addr));
1878 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1880 /* Perhaps we can omit the check. */
1881 if (TREE_CODE (t) == INTEGER_CST
1882 && TREE_CODE (sizet) == INTEGER_CST
1883 && tree_int_cst_le (t, sizet))
1884 return;
1886 if (index != NULL_TREE
1887 && TREE_CODE (index) == SSA_NAME
1888 && TREE_CODE (sizet) == INTEGER_CST)
1890 gimple *def = SSA_NAME_DEF_STMT (index);
1891 if (is_gimple_assign (def)
1892 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1893 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1895 tree cst = gimple_assign_rhs2 (def);
1896 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1897 TYPE_SIZE_UNIT (type));
1898 if (tree_int_cst_sgn (cst) >= 0
1899 && tree_int_cst_lt (cst, sz))
1900 return;
1904 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1905 ubsan_create_edge (bos_stmt);
1907 /* We have to emit the check. */
1908 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1909 GSI_SAME_STMT);
1910 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1911 GSI_SAME_STMT);
1912 tree ckind = build_int_cst (unsigned_char_type_node,
1913 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1914 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1915 ptr, t, sizet, ckind);
1916 gimple_set_location (g, loc);
1917 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1920 /* True if we want to play UBSan games in the current function. */
1922 bool
1923 do_ubsan_in_current_function ()
1925 return (current_function_decl != NULL_TREE
1926 && !lookup_attribute ("no_sanitize_undefined",
1927 DECL_ATTRIBUTES (current_function_decl)));
1930 namespace {
1932 const pass_data pass_data_ubsan =
1934 GIMPLE_PASS, /* type */
1935 "ubsan", /* name */
1936 OPTGROUP_NONE, /* optinfo_flags */
1937 TV_TREE_UBSAN, /* tv_id */
1938 ( PROP_cfg | PROP_ssa ), /* properties_required */
1939 0, /* properties_provided */
1940 0, /* properties_destroyed */
1941 0, /* todo_flags_start */
1942 TODO_update_ssa, /* todo_flags_finish */
1945 class pass_ubsan : public gimple_opt_pass
1947 public:
1948 pass_ubsan (gcc::context *ctxt)
1949 : gimple_opt_pass (pass_data_ubsan, ctxt)
1952 /* opt_pass methods: */
1953 virtual bool gate (function *)
1955 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1956 | SANITIZE_BOOL | SANITIZE_ENUM
1957 | SANITIZE_ALIGNMENT
1958 | SANITIZE_NONNULL_ATTRIBUTE
1959 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1960 | SANITIZE_OBJECT_SIZE)
1961 && do_ubsan_in_current_function ();
1964 virtual unsigned int execute (function *);
1966 }; // class pass_ubsan
1968 unsigned int
1969 pass_ubsan::execute (function *fun)
1971 basic_block bb;
1972 gimple_stmt_iterator gsi;
1973 unsigned int ret = 0;
1975 initialize_sanitizer_builtins ();
1977 FOR_EACH_BB_FN (bb, fun)
1979 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1981 gimple *stmt = gsi_stmt (gsi);
1982 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1984 gsi_next (&gsi);
1985 continue;
1988 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1989 && is_gimple_assign (stmt))
1990 instrument_si_overflow (gsi);
1992 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1994 if (gimple_store_p (stmt))
1995 instrument_null (gsi, true);
1996 if (gimple_assign_load_p (stmt))
1997 instrument_null (gsi, false);
2000 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
2001 && gimple_assign_load_p (stmt))
2003 instrument_bool_enum_load (&gsi);
2004 bb = gimple_bb (stmt);
2007 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
2008 && is_gimple_call (stmt)
2009 && !gimple_call_internal_p (stmt))
2011 instrument_nonnull_arg (&gsi);
2012 bb = gimple_bb (stmt);
2015 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2016 && gimple_code (stmt) == GIMPLE_RETURN)
2018 instrument_nonnull_return (&gsi);
2019 bb = gimple_bb (stmt);
2022 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2024 if (gimple_store_p (stmt))
2025 instrument_object_size (&gsi, true);
2026 if (gimple_assign_load_p (stmt))
2027 instrument_object_size (&gsi, false);
2030 gsi_next (&gsi);
2032 if (gimple_purge_dead_eh_edges (bb))
2033 ret = TODO_cleanup_cfg;
2035 return ret;
2038 } // anon namespace
2040 gimple_opt_pass *
2041 make_pass_ubsan (gcc::context *ctxt)
2043 return new pass_ubsan (ctxt);
2046 #include "gt-ubsan.h"