compiler, runtime: drop size arguments to hash/equal functions
[official-gcc.git] / gcc / ubsan.c
blob0291401eecff4d317f3d62c160f0980168557618
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 && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
414 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
415 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
416 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
417 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
418 else
419 pp_wide_int (&pretty_name,
420 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
421 TYPE_SIGN (TREE_TYPE (dom)));
423 else
424 /* ??? We can't determine the variable name; print VLA unspec. */
425 pp_star (&pretty_name);
426 pp_right_bracket (&pretty_name);
427 t = TREE_TYPE (t);
429 pp_quote (&pretty_name);
431 /* Save the tree with stripped types. */
432 type = t;
434 else
435 pp_printf (&pretty_name, "'%s'", tname);
437 switch (TREE_CODE (type))
439 case BOOLEAN_TYPE:
440 case ENUMERAL_TYPE:
441 case INTEGER_TYPE:
442 tkind = 0x0000;
443 break;
444 case REAL_TYPE:
445 /* FIXME: libubsan right now only supports float, double and
446 long double type formats. */
447 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
448 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
449 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
450 tkind = 0x0001;
451 else
452 tkind = 0xffff;
453 break;
454 default:
455 tkind = 0xffff;
456 break;
458 tinfo = get_ubsan_type_info_for_type (type);
460 /* Create a new VAR_DECL of type descriptor. */
461 const char *tmp = pp_formatted_text (&pretty_name);
462 size_t len = strlen (tmp) + 1;
463 tree str = build_string (len, tmp);
464 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
465 TREE_READONLY (str) = 1;
466 TREE_STATIC (str) = 1;
468 char tmp_name[32];
469 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
470 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
471 dtype);
472 TREE_STATIC (decl) = 1;
473 TREE_PUBLIC (decl) = 0;
474 DECL_ARTIFICIAL (decl) = 1;
475 DECL_IGNORED_P (decl) = 1;
476 DECL_EXTERNAL (decl) = 0;
477 DECL_SIZE (decl)
478 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
479 DECL_SIZE_UNIT (decl)
480 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
481 TYPE_SIZE_UNIT (TREE_TYPE (str)));
483 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
484 build_int_cst (short_unsigned_type_node,
485 tkind), NULL_TREE,
486 build_int_cst (short_unsigned_type_node,
487 tinfo), NULL_TREE, str);
488 TREE_CONSTANT (ctor) = 1;
489 TREE_STATIC (ctor) = 1;
490 DECL_INITIAL (decl) = ctor;
491 varpool_node::finalize_decl (decl);
493 /* Save the VAR_DECL into the hash table. */
494 decl_for_type_insert (type, decl);
496 return build_fold_addr_expr (decl);
499 /* Create a structure for the ubsan library. NAME is a name of the new
500 structure. LOCCNT is number of locations, PLOC points to array of
501 locations. The arguments in ... are of __ubsan_type_descriptor type
502 and there are at most two of them, followed by NULL_TREE, followed
503 by optional extra arguments and another NULL_TREE. */
505 tree
506 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
508 va_list args;
509 tree ret, t;
510 tree fields[6];
511 vec<tree, va_gc> *saved_args = NULL;
512 size_t i = 0;
513 int j;
515 /* It is possible that PCH zapped table with definitions of sanitizer
516 builtins. Reinitialize them if needed. */
517 initialize_sanitizer_builtins ();
519 /* Firstly, create a pointer to type descriptor type. */
520 tree td_type = ubsan_get_type_descriptor_type ();
521 td_type = build_pointer_type (td_type);
523 /* Create the structure type. */
524 ret = make_node (RECORD_TYPE);
525 for (j = 0; j < loccnt; j++)
527 gcc_checking_assert (i < 2);
528 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
529 ubsan_get_source_location_type ());
530 DECL_CONTEXT (fields[i]) = ret;
531 if (i)
532 DECL_CHAIN (fields[i - 1]) = fields[i];
533 i++;
536 va_start (args, ploc);
537 for (t = va_arg (args, tree); t != NULL_TREE;
538 i++, t = va_arg (args, tree))
540 gcc_checking_assert (i < 4);
541 /* Save the tree arguments for later use. */
542 vec_safe_push (saved_args, t);
543 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
544 td_type);
545 DECL_CONTEXT (fields[i]) = ret;
546 if (i)
547 DECL_CHAIN (fields[i - 1]) = fields[i];
550 for (t = va_arg (args, tree); t != NULL_TREE;
551 i++, t = va_arg (args, tree))
553 gcc_checking_assert (i < 6);
554 /* Save the tree arguments for later use. */
555 vec_safe_push (saved_args, t);
556 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
557 TREE_TYPE (t));
558 DECL_CONTEXT (fields[i]) = ret;
559 if (i)
560 DECL_CHAIN (fields[i - 1]) = fields[i];
562 va_end (args);
564 tree type_decl = build_decl (input_location, TYPE_DECL,
565 get_identifier (name), ret);
566 DECL_IGNORED_P (type_decl) = 1;
567 DECL_ARTIFICIAL (type_decl) = 1;
568 TYPE_FIELDS (ret) = fields[0];
569 TYPE_NAME (ret) = type_decl;
570 TYPE_STUB_DECL (ret) = type_decl;
571 layout_type (ret);
573 /* Now, fill in the type. */
574 char tmp_name[32];
575 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
576 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
577 ret);
578 TREE_STATIC (var) = 1;
579 TREE_PUBLIC (var) = 0;
580 DECL_ARTIFICIAL (var) = 1;
581 DECL_IGNORED_P (var) = 1;
582 DECL_EXTERNAL (var) = 0;
584 vec<constructor_elt, va_gc> *v;
585 vec_alloc (v, i);
586 tree ctor = build_constructor (ret, v);
588 /* If desirable, set the __ubsan_source_location element. */
589 for (j = 0; j < loccnt; j++)
591 location_t loc = LOCATION_LOCUS (ploc[j]);
592 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
595 size_t nelts = vec_safe_length (saved_args);
596 for (i = 0; i < nelts; i++)
598 t = (*saved_args)[i];
599 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
602 TREE_CONSTANT (ctor) = 1;
603 TREE_STATIC (ctor) = 1;
604 DECL_INITIAL (var) = ctor;
605 varpool_node::finalize_decl (var);
607 return var;
610 /* Instrument the __builtin_unreachable call. We just call the libubsan
611 routine instead. */
613 bool
614 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
616 gimple *g;
617 location_t loc = gimple_location (gsi_stmt (*gsi));
619 if (flag_sanitize_undefined_trap_on_error)
620 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
621 else
623 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
624 NULL_TREE, NULL_TREE);
625 data = build_fold_addr_expr_loc (loc, data);
626 tree fn
627 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
628 g = gimple_build_call (fn, 1, data);
630 gimple_set_location (g, loc);
631 gsi_replace (gsi, g, false);
632 return false;
635 /* Return true if T is a call to a libubsan routine. */
637 bool
638 is_ubsan_builtin_p (tree t)
640 return TREE_CODE (t) == FUNCTION_DECL
641 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
642 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
643 "__builtin___ubsan_", 18) == 0;
646 /* Create a callgraph edge for statement STMT. */
648 static void
649 ubsan_create_edge (gimple *stmt)
651 gcall *call_stmt = dyn_cast <gcall *> (stmt);
652 basic_block bb = gimple_bb (stmt);
653 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
654 cgraph_node *node = cgraph_node::get (current_function_decl);
655 tree decl = gimple_call_fndecl (call_stmt);
656 if (decl)
657 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
658 freq);
661 /* Expand the UBSAN_BOUNDS special builtin function. */
663 bool
664 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
666 gimple *stmt = gsi_stmt (*gsi);
667 location_t loc = gimple_location (stmt);
668 gcc_assert (gimple_call_num_args (stmt) == 3);
670 /* Pick up the arguments of the UBSAN_BOUNDS call. */
671 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
672 tree index = gimple_call_arg (stmt, 1);
673 tree orig_index_type = TREE_TYPE (index);
674 tree bound = gimple_call_arg (stmt, 2);
676 gimple_stmt_iterator gsi_orig = *gsi;
678 /* Create condition "if (index > bound)". */
679 basic_block then_bb, fallthru_bb;
680 gimple_stmt_iterator cond_insert_point
681 = create_cond_insert_point (gsi, false, false, true,
682 &then_bb, &fallthru_bb);
683 index = fold_convert (TREE_TYPE (bound), index);
684 index = force_gimple_operand_gsi (&cond_insert_point, index,
685 true, NULL_TREE,
686 false, GSI_NEW_STMT);
687 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
688 gimple_set_location (g, loc);
689 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
691 /* Generate __ubsan_handle_out_of_bounds call. */
692 *gsi = gsi_after_labels (then_bb);
693 if (flag_sanitize_undefined_trap_on_error)
694 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
695 else
697 tree data
698 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
699 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
700 ubsan_type_descriptor (orig_index_type),
701 NULL_TREE, NULL_TREE);
702 data = build_fold_addr_expr_loc (loc, data);
703 enum built_in_function bcode
704 = (flag_sanitize_recover & SANITIZE_BOUNDS)
705 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
706 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
707 tree fn = builtin_decl_explicit (bcode);
708 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
709 true, NULL_TREE, true,
710 GSI_SAME_STMT);
711 g = gimple_build_call (fn, 2, data, val);
713 gimple_set_location (g, loc);
714 gsi_insert_before (gsi, g, GSI_SAME_STMT);
716 /* Get rid of the UBSAN_BOUNDS call from the IR. */
717 unlink_stmt_vdef (stmt);
718 gsi_remove (&gsi_orig, true);
720 /* Point GSI to next logical statement. */
721 *gsi = gsi_start_bb (fallthru_bb);
722 return true;
725 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
726 argument which is a constant, because the middle-end treats pointer
727 conversions as useless and therefore the type of the first argument
728 could be changed to any other pointer type. */
730 bool
731 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
733 gimple_stmt_iterator gsi = *gsip;
734 gimple *stmt = gsi_stmt (gsi);
735 location_t loc = gimple_location (stmt);
736 gcc_assert (gimple_call_num_args (stmt) == 3);
737 tree ptr = gimple_call_arg (stmt, 0);
738 tree ckind = gimple_call_arg (stmt, 1);
739 tree align = gimple_call_arg (stmt, 2);
740 tree check_align = NULL_TREE;
741 bool check_null;
743 basic_block cur_bb = gsi_bb (gsi);
745 gimple *g;
746 if (!integer_zerop (align))
748 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
749 if (compare_tree_int (align, ptralign) == 1)
751 check_align = make_ssa_name (pointer_sized_int_node);
752 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
753 gimple_set_location (g, loc);
754 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
757 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
759 if (check_align == NULL_TREE && !check_null)
761 gsi_remove (gsip, true);
762 /* Unlink the UBSAN_NULLs vops before replacing it. */
763 unlink_stmt_vdef (stmt);
764 return true;
767 /* Split the original block holding the pointer dereference. */
768 edge e = split_block (cur_bb, stmt);
770 /* Get a hold on the 'condition block', the 'then block' and the
771 'else block'. */
772 basic_block cond_bb = e->src;
773 basic_block fallthru_bb = e->dest;
774 basic_block then_bb = create_empty_bb (cond_bb);
775 add_bb_to_loop (then_bb, cond_bb->loop_father);
776 loops_state_set (LOOPS_NEED_FIXUP);
778 /* Make an edge coming from the 'cond block' into the 'then block';
779 this edge is unlikely taken, so set up the probability accordingly. */
780 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
781 e->probability = PROB_VERY_UNLIKELY;
783 /* Connect 'then block' with the 'else block'. This is needed
784 as the ubsan routines we call in the 'then block' are not noreturn.
785 The 'then block' only has one outcoming edge. */
786 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
788 /* Set up the fallthrough basic block. */
789 e = find_edge (cond_bb, fallthru_bb);
790 e->flags = EDGE_FALSE_VALUE;
791 e->count = cond_bb->count;
792 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
794 /* Update dominance info for the newly created then_bb; note that
795 fallthru_bb's dominance info has already been updated by
796 split_block. */
797 if (dom_info_available_p (CDI_DOMINATORS))
798 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
800 /* Put the ubsan builtin call into the newly created BB. */
801 if (flag_sanitize_undefined_trap_on_error)
802 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
803 else
805 enum built_in_function bcode
806 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
807 | (check_null ? SANITIZE_NULL : 0)))
808 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
809 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
810 tree fn = builtin_decl_implicit (bcode);
811 tree data
812 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
813 ubsan_type_descriptor (TREE_TYPE (ckind),
814 UBSAN_PRINT_POINTER),
815 NULL_TREE,
816 align,
817 fold_convert (unsigned_char_type_node, ckind),
818 NULL_TREE);
819 data = build_fold_addr_expr_loc (loc, data);
820 g = gimple_build_call (fn, 2, data,
821 check_align ? check_align
822 : build_zero_cst (pointer_sized_int_node));
824 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
825 gimple_set_location (g, loc);
826 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
828 /* Unlink the UBSAN_NULLs vops before replacing it. */
829 unlink_stmt_vdef (stmt);
831 if (check_null)
833 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
834 NULL_TREE, NULL_TREE);
835 gimple_set_location (g, loc);
837 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
838 gsi_replace (&gsi, g, false);
839 stmt = g;
842 if (check_align)
844 if (check_null)
846 /* Split the block with the condition again. */
847 e = split_block (cond_bb, stmt);
848 basic_block cond1_bb = e->src;
849 basic_block cond2_bb = e->dest;
851 /* Make an edge coming from the 'cond1 block' into the 'then block';
852 this edge is unlikely taken, so set up the probability
853 accordingly. */
854 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
855 e->probability = PROB_VERY_UNLIKELY;
857 /* Set up the fallthrough basic block. */
858 e = find_edge (cond1_bb, cond2_bb);
859 e->flags = EDGE_FALSE_VALUE;
860 e->count = cond1_bb->count;
861 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
863 /* Update dominance info. */
864 if (dom_info_available_p (CDI_DOMINATORS))
866 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
867 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
870 gsi2 = gsi_start_bb (cond2_bb);
873 tree mask = build_int_cst (pointer_sized_int_node,
874 tree_to_uhwi (align) - 1);
875 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
876 BIT_AND_EXPR, check_align, mask);
877 gimple_set_location (g, loc);
878 if (check_null)
879 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
880 else
881 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
883 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
884 build_int_cst (pointer_sized_int_node, 0),
885 NULL_TREE, NULL_TREE);
886 gimple_set_location (g, loc);
887 if (check_null)
888 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
889 else
890 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
891 gsi_replace (&gsi, g, false);
893 return false;
896 #define OBJSZ_MAX_OFFSET (1024 * 16)
898 /* Expand UBSAN_OBJECT_SIZE internal call. */
900 bool
901 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
903 gimple *stmt = gsi_stmt (*gsi);
904 location_t loc = gimple_location (stmt);
905 gcc_assert (gimple_call_num_args (stmt) == 4);
907 tree ptr = gimple_call_arg (stmt, 0);
908 tree offset = gimple_call_arg (stmt, 1);
909 tree size = gimple_call_arg (stmt, 2);
910 tree ckind = gimple_call_arg (stmt, 3);
911 gimple_stmt_iterator gsi_orig = *gsi;
912 gimple *g;
914 /* See if we can discard the check. */
915 if (TREE_CODE (size) != INTEGER_CST
916 || integer_all_onesp (size))
917 /* Yes, __builtin_object_size couldn't determine the
918 object size. */;
919 else if (TREE_CODE (offset) == INTEGER_CST
920 && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
921 && wi::to_widest (offset) <= -1)
922 /* The offset is in range [-16K, -1]. */;
923 else
925 /* if (offset > objsize) */
926 basic_block then_bb, fallthru_bb;
927 gimple_stmt_iterator cond_insert_point
928 = create_cond_insert_point (gsi, false, false, true,
929 &then_bb, &fallthru_bb);
930 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
931 gimple_set_location (g, loc);
932 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
934 /* If the offset is small enough, we don't need the second
935 run-time check. */
936 if (TREE_CODE (offset) == INTEGER_CST
937 && wi::to_widest (offset) >= 0
938 && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
939 *gsi = gsi_after_labels (then_bb);
940 else
942 /* Don't issue run-time error if (ptr > ptr + offset). That
943 may happen when computing a POINTER_PLUS_EXPR. */
944 basic_block then2_bb, fallthru2_bb;
946 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
947 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
948 true, &then2_bb,
949 &fallthru2_bb);
950 /* Convert the pointer to an integer type. */
951 tree p = make_ssa_name (pointer_sized_int_node);
952 g = gimple_build_assign (p, NOP_EXPR, ptr);
953 gimple_set_location (g, loc);
954 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
955 p = gimple_assign_lhs (g);
956 /* Compute ptr + offset. */
957 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
958 PLUS_EXPR, p, offset);
959 gimple_set_location (g, loc);
960 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
961 /* Now build the conditional and put it into the IR. */
962 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
963 NULL_TREE, NULL_TREE);
964 gimple_set_location (g, loc);
965 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
966 *gsi = gsi_after_labels (then2_bb);
969 /* Generate __ubsan_handle_type_mismatch call. */
970 if (flag_sanitize_undefined_trap_on_error)
971 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
972 else
974 tree data
975 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
976 ubsan_type_descriptor (TREE_TYPE (ptr),
977 UBSAN_PRINT_POINTER),
978 NULL_TREE,
979 build_zero_cst (pointer_sized_int_node),
980 ckind,
981 NULL_TREE);
982 data = build_fold_addr_expr_loc (loc, data);
983 enum built_in_function bcode
984 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
985 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
986 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
987 tree p = make_ssa_name (pointer_sized_int_node);
988 g = gimple_build_assign (p, NOP_EXPR, ptr);
989 gimple_set_location (g, loc);
990 gsi_insert_before (gsi, g, GSI_SAME_STMT);
991 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
993 gimple_set_location (g, loc);
994 gsi_insert_before (gsi, g, GSI_SAME_STMT);
996 /* Point GSI to next logical statement. */
997 *gsi = gsi_start_bb (fallthru_bb);
999 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1000 unlink_stmt_vdef (stmt);
1001 gsi_remove (&gsi_orig, true);
1002 return true;
1005 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1006 unlink_stmt_vdef (stmt);
1007 gsi_remove (gsi, true);
1008 return true;
1011 /* Cached __ubsan_vptr_type_cache decl. */
1012 static GTY(()) tree ubsan_vptr_type_cache_decl;
1014 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1015 argument which is a constant, because the middle-end treats pointer
1016 conversions as useless and therefore the type of the first argument
1017 could be changed to any other pointer type. */
1019 bool
1020 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1022 gimple_stmt_iterator gsi = *gsip;
1023 gimple *stmt = gsi_stmt (gsi);
1024 location_t loc = gimple_location (stmt);
1025 gcc_assert (gimple_call_num_args (stmt) == 5);
1026 tree op = gimple_call_arg (stmt, 0);
1027 tree vptr = gimple_call_arg (stmt, 1);
1028 tree str_hash = gimple_call_arg (stmt, 2);
1029 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1030 tree ckind_tree = gimple_call_arg (stmt, 4);
1031 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1032 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1033 gimple *g;
1034 basic_block fallthru_bb = NULL;
1036 if (ckind == UBSAN_DOWNCAST_POINTER)
1038 /* Guard everything with if (op != NULL) { ... }. */
1039 basic_block then_bb;
1040 gimple_stmt_iterator cond_insert_point
1041 = create_cond_insert_point (gsip, false, false, true,
1042 &then_bb, &fallthru_bb);
1043 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1044 NULL_TREE, NULL_TREE);
1045 gimple_set_location (g, loc);
1046 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1047 *gsip = gsi_after_labels (then_bb);
1048 gsi_remove (&gsi, false);
1049 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1050 gsi = *gsip;
1053 tree htype = TREE_TYPE (str_hash);
1054 tree cst = wide_int_to_tree (htype,
1055 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1056 | 0xeb382d69, 64));
1057 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1058 vptr, str_hash);
1059 gimple_set_location (g, loc);
1060 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1061 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1062 gimple_assign_lhs (g), cst);
1063 gimple_set_location (g, loc);
1064 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1065 tree t1 = gimple_assign_lhs (g);
1066 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1067 t1, build_int_cst (integer_type_node, 47));
1068 gimple_set_location (g, loc);
1069 tree t2 = gimple_assign_lhs (g);
1070 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1071 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1072 vptr, t1);
1073 gimple_set_location (g, loc);
1074 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1075 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1076 t2, gimple_assign_lhs (g));
1077 gimple_set_location (g, loc);
1078 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1079 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1080 gimple_assign_lhs (g), cst);
1081 gimple_set_location (g, loc);
1082 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1083 tree t3 = gimple_assign_lhs (g);
1084 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1085 t3, build_int_cst (integer_type_node, 47));
1086 gimple_set_location (g, loc);
1087 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1088 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1089 t3, gimple_assign_lhs (g));
1090 gimple_set_location (g, loc);
1091 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1092 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1093 gimple_assign_lhs (g), cst);
1094 gimple_set_location (g, loc);
1095 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1096 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1098 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1099 NOP_EXPR, gimple_assign_lhs (g));
1100 gimple_set_location (g, loc);
1101 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1103 tree hash = gimple_assign_lhs (g);
1105 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1107 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1108 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1109 get_identifier ("__ubsan_vptr_type_cache"),
1110 atype);
1111 DECL_ARTIFICIAL (array) = 1;
1112 DECL_IGNORED_P (array) = 1;
1113 TREE_PUBLIC (array) = 1;
1114 TREE_STATIC (array) = 1;
1115 DECL_EXTERNAL (array) = 1;
1116 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1117 DECL_VISIBILITY_SPECIFIED (array) = 1;
1118 varpool_node::finalize_decl (array);
1119 ubsan_vptr_type_cache_decl = array;
1122 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1123 BIT_AND_EXPR, hash,
1124 build_int_cst (pointer_sized_int_node, 127));
1125 gimple_set_location (g, loc);
1126 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1128 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1129 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1130 NULL_TREE, NULL_TREE);
1131 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1132 ARRAY_REF, c);
1133 gimple_set_location (g, loc);
1134 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1136 basic_block then_bb, fallthru2_bb;
1137 gimple_stmt_iterator cond_insert_point
1138 = create_cond_insert_point (gsip, false, false, true,
1139 &then_bb, &fallthru2_bb);
1140 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1141 NULL_TREE, NULL_TREE);
1142 gimple_set_location (g, loc);
1143 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1144 *gsip = gsi_after_labels (then_bb);
1145 if (fallthru_bb == NULL)
1146 fallthru_bb = fallthru2_bb;
1148 tree data
1149 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1150 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1151 build_int_cst (unsigned_char_type_node, ckind),
1152 NULL_TREE);
1153 data = build_fold_addr_expr_loc (loc, data);
1154 enum built_in_function bcode
1155 = (flag_sanitize_recover & SANITIZE_VPTR)
1156 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1157 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1159 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1160 gimple_set_location (g, loc);
1161 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1163 /* Point GSI to next logical statement. */
1164 *gsip = gsi_start_bb (fallthru_bb);
1166 /* Get rid of the UBSAN_VPTR call from the IR. */
1167 unlink_stmt_vdef (stmt);
1168 gsi_remove (&gsi, true);
1169 return true;
1172 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1173 whether the pointer is on the left hand side of the assignment. */
1175 static void
1176 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1177 bool is_lhs)
1179 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1180 unsigned int align = 0;
1181 if (flag_sanitize & SANITIZE_ALIGNMENT)
1183 align = min_align_of_type (TREE_TYPE (base));
1184 if (align <= 1)
1185 align = 0;
1187 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1188 return;
1189 tree t = TREE_OPERAND (base, 0);
1190 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1191 return;
1192 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1193 ikind = UBSAN_MEMBER_ACCESS;
1194 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1195 tree alignt = build_int_cst (pointer_sized_int_node, align);
1196 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1197 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1198 gsi_insert_before (iter, g, GSI_SAME_STMT);
1201 /* Perform the pointer instrumentation. */
1203 static void
1204 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1206 gimple *stmt = gsi_stmt (gsi);
1207 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1208 tree base = get_base_address (t);
1209 const enum tree_code code = TREE_CODE (base);
1210 if (code == MEM_REF
1211 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1212 instrument_mem_ref (t, base, &gsi, is_lhs);
1215 /* Build an ubsan builtin call for the signed-integer-overflow
1216 sanitization. CODE says what kind of builtin are we building,
1217 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1218 are operands of the binary operation. */
1220 tree
1221 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1222 tree op0, tree op1, tree *datap)
1224 if (flag_sanitize_undefined_trap_on_error)
1225 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1227 tree data;
1228 if (datap && *datap)
1229 data = *datap;
1230 else
1231 data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1232 ubsan_type_descriptor (lhstype), NULL_TREE,
1233 NULL_TREE);
1234 if (datap)
1235 *datap = data;
1236 enum built_in_function fn_code;
1238 switch (code)
1240 case PLUS_EXPR:
1241 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1242 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1243 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1244 break;
1245 case MINUS_EXPR:
1246 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1247 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1248 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1249 break;
1250 case MULT_EXPR:
1251 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1252 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1253 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1254 break;
1255 case NEGATE_EXPR:
1256 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1257 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1258 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1259 break;
1260 default:
1261 gcc_unreachable ();
1263 tree fn = builtin_decl_explicit (fn_code);
1264 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1265 build_fold_addr_expr_loc (loc, data),
1266 ubsan_encode_value (op0, true),
1267 op1 ? ubsan_encode_value (op1, true)
1268 : NULL_TREE);
1271 /* Perform the signed integer instrumentation. GSI is the iterator
1272 pointing at statement we are trying to instrument. */
1274 static void
1275 instrument_si_overflow (gimple_stmt_iterator gsi)
1277 gimple *stmt = gsi_stmt (gsi);
1278 tree_code code = gimple_assign_rhs_code (stmt);
1279 tree lhs = gimple_assign_lhs (stmt);
1280 tree lhstype = TREE_TYPE (lhs);
1281 tree lhsinner = VECTOR_TYPE_P (lhstype) ? TREE_TYPE (lhstype) : lhstype;
1282 tree a, b;
1283 gimple *g;
1285 /* If this is not a signed operation, don't instrument anything here.
1286 Also punt on bit-fields. */
1287 if (!INTEGRAL_TYPE_P (lhsinner)
1288 || TYPE_OVERFLOW_WRAPS (lhsinner)
1289 || GET_MODE_BITSIZE (TYPE_MODE (lhsinner)) != TYPE_PRECISION (lhsinner))
1290 return;
1292 switch (code)
1294 case MINUS_EXPR:
1295 case PLUS_EXPR:
1296 case MULT_EXPR:
1297 /* Transform
1298 i = u {+,-,*} 5;
1299 into
1300 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1301 a = gimple_assign_rhs1 (stmt);
1302 b = gimple_assign_rhs2 (stmt);
1303 g = gimple_build_call_internal (code == PLUS_EXPR
1304 ? IFN_UBSAN_CHECK_ADD
1305 : code == MINUS_EXPR
1306 ? IFN_UBSAN_CHECK_SUB
1307 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1308 gimple_call_set_lhs (g, lhs);
1309 gsi_replace (&gsi, g, true);
1310 break;
1311 case NEGATE_EXPR:
1312 /* Represent i = -u;
1314 i = UBSAN_CHECK_SUB (0, u); */
1315 a = build_zero_cst (lhstype);
1316 b = gimple_assign_rhs1 (stmt);
1317 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1318 gimple_call_set_lhs (g, lhs);
1319 gsi_replace (&gsi, g, true);
1320 break;
1321 case ABS_EXPR:
1322 /* Transform i = ABS_EXPR<u>;
1323 into
1324 _N = UBSAN_CHECK_SUB (0, u);
1325 i = ABS_EXPR<_N>; */
1326 a = build_zero_cst (lhstype);
1327 b = gimple_assign_rhs1 (stmt);
1328 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1329 a = make_ssa_name (lhstype);
1330 gimple_call_set_lhs (g, a);
1331 gimple_set_location (g, gimple_location (stmt));
1332 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1333 gimple_assign_set_rhs1 (stmt, a);
1334 update_stmt (stmt);
1335 break;
1336 default:
1337 break;
1341 /* Instrument loads from (non-bitfield) bool and C++ enum values
1342 to check if the memory value is outside of the range of the valid
1343 type values. */
1345 static void
1346 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1348 gimple *stmt = gsi_stmt (*gsi);
1349 tree rhs = gimple_assign_rhs1 (stmt);
1350 tree type = TREE_TYPE (rhs);
1351 tree minv = NULL_TREE, maxv = NULL_TREE;
1353 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1355 minv = boolean_false_node;
1356 maxv = boolean_true_node;
1358 else if (TREE_CODE (type) == ENUMERAL_TYPE
1359 && (flag_sanitize & SANITIZE_ENUM)
1360 && TREE_TYPE (type) != NULL_TREE
1361 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1362 && (TYPE_PRECISION (TREE_TYPE (type))
1363 < GET_MODE_PRECISION (TYPE_MODE (type))))
1365 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1366 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1368 else
1369 return;
1371 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1372 HOST_WIDE_INT bitsize, bitpos;
1373 tree offset;
1374 machine_mode mode;
1375 int volatilep = 0, reversep, unsignedp = 0;
1376 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1377 &unsignedp, &reversep, &volatilep);
1378 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1380 if ((VAR_P (base) && DECL_HARD_REGISTER (base))
1381 || (bitpos % modebitsize) != 0
1382 || bitsize != modebitsize
1383 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1384 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1385 return;
1387 bool ends_bb = stmt_ends_bb_p (stmt);
1388 location_t loc = gimple_location (stmt);
1389 tree lhs = gimple_assign_lhs (stmt);
1390 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1391 tree atype = reference_alias_ptr_type (rhs);
1392 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1393 build_fold_addr_expr (rhs));
1394 gimple_set_location (g, loc);
1395 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1396 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1397 build_int_cst (atype, 0));
1398 tree urhs = make_ssa_name (utype);
1399 if (ends_bb)
1401 gimple_assign_set_lhs (stmt, urhs);
1402 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1403 gimple_set_location (g, loc);
1404 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1405 gsi_insert_on_edge_immediate (e, g);
1406 gimple_assign_set_rhs_from_tree (gsi, mem);
1407 update_stmt (stmt);
1408 *gsi = gsi_for_stmt (g);
1409 g = stmt;
1411 else
1413 g = gimple_build_assign (urhs, mem);
1414 gimple_set_location (g, loc);
1415 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1417 minv = fold_convert (utype, minv);
1418 maxv = fold_convert (utype, maxv);
1419 if (!integer_zerop (minv))
1421 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1422 gimple_set_location (g, loc);
1423 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1426 gimple_stmt_iterator gsi2 = *gsi;
1427 basic_block then_bb, fallthru_bb;
1428 *gsi = create_cond_insert_point (gsi, true, false, true,
1429 &then_bb, &fallthru_bb);
1430 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1431 int_const_binop (MINUS_EXPR, maxv, minv),
1432 NULL_TREE, NULL_TREE);
1433 gimple_set_location (g, loc);
1434 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1436 if (!ends_bb)
1438 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1439 update_stmt (stmt);
1442 gsi2 = gsi_after_labels (then_bb);
1443 if (flag_sanitize_undefined_trap_on_error)
1444 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1445 else
1447 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1448 ubsan_type_descriptor (type), NULL_TREE,
1449 NULL_TREE);
1450 data = build_fold_addr_expr_loc (loc, data);
1451 enum built_in_function bcode
1452 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1453 ? SANITIZE_BOOL : SANITIZE_ENUM))
1454 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1455 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1456 tree fn = builtin_decl_explicit (bcode);
1458 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1459 true, NULL_TREE, true,
1460 GSI_SAME_STMT);
1461 g = gimple_build_call (fn, 2, data, val);
1463 gimple_set_location (g, loc);
1464 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1465 ubsan_create_edge (g);
1466 *gsi = gsi_for_stmt (stmt);
1469 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1470 new style handlers. Libubsan uses heuristics to destinguish between old and
1471 new styles and relies on these properties for filename:
1473 a) Location's filename must not be NULL.
1474 b) Location's filename must not be equal to "".
1475 c) Location's filename must not be equal to "\1".
1476 d) First two bytes of filename must not contain '\xff' symbol. */
1478 static bool
1479 ubsan_use_new_style_p (location_t loc)
1481 if (loc == UNKNOWN_LOCATION)
1482 return false;
1484 expanded_location xloc = expand_location (loc);
1485 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1486 || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1487 || xloc.file[1] == '\xff')
1488 return false;
1490 return true;
1493 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1494 destination, EXPR is floating-point expression. */
1496 tree
1497 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1499 tree expr_type = TREE_TYPE (expr);
1500 tree t, tt, fn, min, max;
1501 machine_mode mode = TYPE_MODE (expr_type);
1502 int prec = TYPE_PRECISION (type);
1503 bool uns_p = TYPE_UNSIGNED (type);
1504 if (loc == UNKNOWN_LOCATION)
1505 loc = input_location;
1507 /* Float to integer conversion first truncates toward zero, so
1508 even signed char c = 127.875f; is not problematic.
1509 Therefore, we should complain only if EXPR is unordered or smaller
1510 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1511 TYPE_MAX_VALUE + 1.0. */
1512 if (REAL_MODE_FORMAT (mode)->b == 2)
1514 /* For maximum, TYPE_MAX_VALUE might not be representable
1515 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1516 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1517 either representable or infinity. */
1518 REAL_VALUE_TYPE maxval = dconst1;
1519 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1520 real_convert (&maxval, mode, &maxval);
1521 max = build_real (expr_type, maxval);
1523 /* For unsigned, assume -1.0 is always representable. */
1524 if (uns_p)
1525 min = build_minus_one_cst (expr_type);
1526 else
1528 /* TYPE_MIN_VALUE is generally representable (or -inf),
1529 but TYPE_MIN_VALUE - 1.0 might not be. */
1530 REAL_VALUE_TYPE minval = dconstm1, minval2;
1531 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1532 real_convert (&minval, mode, &minval);
1533 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1534 real_convert (&minval2, mode, &minval2);
1535 if (real_compare (EQ_EXPR, &minval, &minval2)
1536 && !real_isinf (&minval))
1538 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1539 rounds to TYPE_MIN_VALUE, we need to subtract
1540 more. As REAL_MODE_FORMAT (mode)->p is the number
1541 of base digits, we want to subtract a number that
1542 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1543 times smaller than minval. */
1544 minval2 = dconst1;
1545 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1546 SET_REAL_EXP (&minval2,
1547 REAL_EXP (&minval2) + prec - 1
1548 - REAL_MODE_FORMAT (mode)->p + 1);
1549 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1550 real_convert (&minval2, mode, &minval2);
1552 min = build_real (expr_type, minval2);
1555 else if (REAL_MODE_FORMAT (mode)->b == 10)
1557 /* For _Decimal128 up to 34 decimal digits, - sign,
1558 dot, e, exponent. */
1559 char buf[64];
1560 mpfr_t m;
1561 int p = REAL_MODE_FORMAT (mode)->p;
1562 REAL_VALUE_TYPE maxval, minval;
1564 /* Use mpfr_snprintf rounding to compute the smallest
1565 representable decimal number greater or equal than
1566 1 << (prec - !uns_p). */
1567 mpfr_init2 (m, prec + 2);
1568 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1569 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1570 decimal_real_from_string (&maxval, buf);
1571 max = build_real (expr_type, maxval);
1573 /* For unsigned, assume -1.0 is always representable. */
1574 if (uns_p)
1575 min = build_minus_one_cst (expr_type);
1576 else
1578 /* Use mpfr_snprintf rounding to compute the largest
1579 representable decimal number less or equal than
1580 (-1 << (prec - 1)) - 1. */
1581 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1582 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1583 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1584 decimal_real_from_string (&minval, buf);
1585 min = build_real (expr_type, minval);
1587 mpfr_clear (m);
1589 else
1590 return NULL_TREE;
1592 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1593 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1594 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1595 if (integer_zerop (t))
1596 return NULL_TREE;
1598 if (flag_sanitize_undefined_trap_on_error)
1599 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1600 else
1602 location_t *loc_ptr = NULL;
1603 unsigned num_locations = 0;
1604 /* Figure out if we can propagate location to ubsan_data and use new
1605 style handlers in libubsan. */
1606 if (ubsan_use_new_style_p (loc))
1608 loc_ptr = &loc;
1609 num_locations = 1;
1611 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1612 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1613 num_locations, loc_ptr,
1614 ubsan_type_descriptor (expr_type),
1615 ubsan_type_descriptor (type), NULL_TREE,
1616 NULL_TREE);
1617 enum built_in_function bcode
1618 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1619 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1620 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1621 fn = builtin_decl_explicit (bcode);
1622 fn = build_call_expr_loc (loc, fn, 2,
1623 build_fold_addr_expr_loc (loc, data),
1624 ubsan_encode_value (expr, false));
1627 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1630 /* Instrument values passed to function arguments with nonnull attribute. */
1632 static void
1633 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1635 gimple *stmt = gsi_stmt (*gsi);
1636 location_t loc[2];
1637 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1638 while for nonnull sanitization it is clear. */
1639 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1640 flag_delete_null_pointer_checks = 1;
1641 loc[0] = gimple_location (stmt);
1642 loc[1] = UNKNOWN_LOCATION;
1643 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1645 tree arg = gimple_call_arg (stmt, i);
1646 if (POINTER_TYPE_P (TREE_TYPE (arg))
1647 && infer_nonnull_range_by_attribute (stmt, arg))
1649 gimple *g;
1650 if (!is_gimple_val (arg))
1652 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1653 gimple_set_location (g, loc[0]);
1654 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1655 arg = gimple_assign_lhs (g);
1658 basic_block then_bb, fallthru_bb;
1659 *gsi = create_cond_insert_point (gsi, true, false, true,
1660 &then_bb, &fallthru_bb);
1661 g = gimple_build_cond (EQ_EXPR, arg,
1662 build_zero_cst (TREE_TYPE (arg)),
1663 NULL_TREE, NULL_TREE);
1664 gimple_set_location (g, loc[0]);
1665 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1667 *gsi = gsi_after_labels (then_bb);
1668 if (flag_sanitize_undefined_trap_on_error)
1669 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1670 else
1672 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1673 2, loc, NULL_TREE,
1674 build_int_cst (integer_type_node,
1675 i + 1),
1676 NULL_TREE);
1677 data = build_fold_addr_expr_loc (loc[0], data);
1678 enum built_in_function bcode
1679 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1680 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1681 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1682 tree fn = builtin_decl_explicit (bcode);
1684 g = gimple_build_call (fn, 1, data);
1686 gimple_set_location (g, loc[0]);
1687 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1688 ubsan_create_edge (g);
1690 *gsi = gsi_for_stmt (stmt);
1692 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1695 /* Instrument returns in functions with returns_nonnull attribute. */
1697 static void
1698 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1700 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1701 location_t loc[2];
1702 tree arg = gimple_return_retval (stmt);
1703 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1704 while for nonnull return sanitization it is clear. */
1705 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1706 flag_delete_null_pointer_checks = 1;
1707 loc[0] = gimple_location (stmt);
1708 loc[1] = UNKNOWN_LOCATION;
1709 if (arg
1710 && POINTER_TYPE_P (TREE_TYPE (arg))
1711 && is_gimple_val (arg)
1712 && infer_nonnull_range_by_attribute (stmt, arg))
1714 basic_block then_bb, fallthru_bb;
1715 *gsi = create_cond_insert_point (gsi, true, false, true,
1716 &then_bb, &fallthru_bb);
1717 gimple *g = gimple_build_cond (EQ_EXPR, arg,
1718 build_zero_cst (TREE_TYPE (arg)),
1719 NULL_TREE, NULL_TREE);
1720 gimple_set_location (g, loc[0]);
1721 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1723 *gsi = gsi_after_labels (then_bb);
1724 if (flag_sanitize_undefined_trap_on_error)
1725 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1726 else
1728 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1729 2, loc, NULL_TREE, NULL_TREE);
1730 data = build_fold_addr_expr_loc (loc[0], data);
1731 enum built_in_function bcode
1732 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1733 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1734 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1735 tree fn = builtin_decl_explicit (bcode);
1737 g = gimple_build_call (fn, 1, data);
1739 gimple_set_location (g, loc[0]);
1740 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1741 ubsan_create_edge (g);
1742 *gsi = gsi_for_stmt (stmt);
1744 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1747 /* Instrument memory references. Here we check whether the pointer
1748 points to an out-of-bounds location. */
1750 static void
1751 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1753 gimple *stmt = gsi_stmt (*gsi);
1754 location_t loc = gimple_location (stmt);
1755 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1756 tree type;
1757 tree index = NULL_TREE;
1758 HOST_WIDE_INT size_in_bytes;
1760 type = TREE_TYPE (t);
1761 if (VOID_TYPE_P (type))
1762 return;
1764 switch (TREE_CODE (t))
1766 case COMPONENT_REF:
1767 if (TREE_CODE (t) == COMPONENT_REF
1768 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1770 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1771 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1772 repr, NULL_TREE);
1774 break;
1775 case ARRAY_REF:
1776 index = TREE_OPERAND (t, 1);
1777 break;
1778 case INDIRECT_REF:
1779 case MEM_REF:
1780 case VAR_DECL:
1781 case PARM_DECL:
1782 case RESULT_DECL:
1783 break;
1784 default:
1785 return;
1788 size_in_bytes = int_size_in_bytes (type);
1789 if (size_in_bytes <= 0)
1790 return;
1792 HOST_WIDE_INT bitsize, bitpos;
1793 tree offset;
1794 machine_mode mode;
1795 int volatilep = 0, reversep, unsignedp = 0;
1796 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1797 &unsignedp, &reversep, &volatilep);
1799 if (bitpos % BITS_PER_UNIT != 0
1800 || bitsize != size_in_bytes * BITS_PER_UNIT)
1801 return;
1803 bool decl_p = DECL_P (inner);
1804 tree base;
1805 if (decl_p)
1806 base = inner;
1807 else if (TREE_CODE (inner) == MEM_REF)
1808 base = TREE_OPERAND (inner, 0);
1809 else
1810 return;
1811 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1813 while (TREE_CODE (base) == SSA_NAME)
1815 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
1816 if (gimple_assign_ssa_name_copy_p (def_stmt)
1817 || (gimple_assign_cast_p (def_stmt)
1818 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1819 || (is_gimple_assign (def_stmt)
1820 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1822 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1823 if (TREE_CODE (rhs1) == SSA_NAME
1824 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1825 break;
1826 else
1827 base = rhs1;
1829 else
1830 break;
1833 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1834 return;
1836 tree sizet;
1837 tree base_addr = base;
1838 gimple *bos_stmt = NULL;
1839 if (decl_p)
1840 base_addr = build1 (ADDR_EXPR,
1841 build_pointer_type (TREE_TYPE (base)), base);
1842 unsigned HOST_WIDE_INT size;
1843 if (compute_builtin_object_size (base_addr, 0, &size))
1844 sizet = build_int_cst (sizetype, size);
1845 else if (optimize)
1847 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1848 loc = input_location;
1849 /* Generate __builtin_object_size call. */
1850 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1851 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1852 integer_zero_node);
1853 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1854 GSI_SAME_STMT);
1855 /* If the call above didn't end up being an integer constant, go one
1856 statement back and get the __builtin_object_size stmt. Save it,
1857 we might need it later. */
1858 if (SSA_VAR_P (sizet))
1860 gsi_prev (gsi);
1861 bos_stmt = gsi_stmt (*gsi);
1863 /* Move on to where we were. */
1864 gsi_next (gsi);
1867 else
1868 return;
1870 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1871 call. */
1872 /* ptr + sizeof (*ptr) - base */
1873 t = fold_build2 (MINUS_EXPR, sizetype,
1874 fold_convert (pointer_sized_int_node, ptr),
1875 fold_convert (pointer_sized_int_node, base_addr));
1876 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1878 /* Perhaps we can omit the check. */
1879 if (TREE_CODE (t) == INTEGER_CST
1880 && TREE_CODE (sizet) == INTEGER_CST
1881 && tree_int_cst_le (t, sizet))
1882 return;
1884 if (index != NULL_TREE
1885 && TREE_CODE (index) == SSA_NAME
1886 && TREE_CODE (sizet) == INTEGER_CST)
1888 gimple *def = SSA_NAME_DEF_STMT (index);
1889 if (is_gimple_assign (def)
1890 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1891 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1893 tree cst = gimple_assign_rhs2 (def);
1894 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1895 TYPE_SIZE_UNIT (type));
1896 if (tree_int_cst_sgn (cst) >= 0
1897 && tree_int_cst_lt (cst, sz))
1898 return;
1902 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1903 ubsan_create_edge (bos_stmt);
1905 /* We have to emit the check. */
1906 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1907 GSI_SAME_STMT);
1908 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1909 GSI_SAME_STMT);
1910 tree ckind = build_int_cst (unsigned_char_type_node,
1911 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1912 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1913 ptr, t, sizet, ckind);
1914 gimple_set_location (g, loc);
1915 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1918 /* True if we want to play UBSan games in the current function. */
1920 bool
1921 do_ubsan_in_current_function ()
1923 return (current_function_decl != NULL_TREE
1924 && !lookup_attribute ("no_sanitize_undefined",
1925 DECL_ATTRIBUTES (current_function_decl)));
1928 namespace {
1930 const pass_data pass_data_ubsan =
1932 GIMPLE_PASS, /* type */
1933 "ubsan", /* name */
1934 OPTGROUP_NONE, /* optinfo_flags */
1935 TV_TREE_UBSAN, /* tv_id */
1936 ( PROP_cfg | PROP_ssa ), /* properties_required */
1937 0, /* properties_provided */
1938 0, /* properties_destroyed */
1939 0, /* todo_flags_start */
1940 TODO_update_ssa, /* todo_flags_finish */
1943 class pass_ubsan : public gimple_opt_pass
1945 public:
1946 pass_ubsan (gcc::context *ctxt)
1947 : gimple_opt_pass (pass_data_ubsan, ctxt)
1950 /* opt_pass methods: */
1951 virtual bool gate (function *)
1953 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1954 | SANITIZE_BOOL | SANITIZE_ENUM
1955 | SANITIZE_ALIGNMENT
1956 | SANITIZE_NONNULL_ATTRIBUTE
1957 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1958 | SANITIZE_OBJECT_SIZE)
1959 && do_ubsan_in_current_function ();
1962 virtual unsigned int execute (function *);
1964 }; // class pass_ubsan
1966 unsigned int
1967 pass_ubsan::execute (function *fun)
1969 basic_block bb;
1970 gimple_stmt_iterator gsi;
1971 unsigned int ret = 0;
1973 initialize_sanitizer_builtins ();
1975 FOR_EACH_BB_FN (bb, fun)
1977 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1979 gimple *stmt = gsi_stmt (gsi);
1980 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1982 gsi_next (&gsi);
1983 continue;
1986 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1987 && is_gimple_assign (stmt))
1988 instrument_si_overflow (gsi);
1990 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1992 if (gimple_store_p (stmt))
1993 instrument_null (gsi, true);
1994 if (gimple_assign_load_p (stmt))
1995 instrument_null (gsi, false);
1998 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1999 && gimple_assign_load_p (stmt))
2001 instrument_bool_enum_load (&gsi);
2002 bb = gimple_bb (stmt);
2005 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
2006 && is_gimple_call (stmt)
2007 && !gimple_call_internal_p (stmt))
2009 instrument_nonnull_arg (&gsi);
2010 bb = gimple_bb (stmt);
2013 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2014 && gimple_code (stmt) == GIMPLE_RETURN)
2016 instrument_nonnull_return (&gsi);
2017 bb = gimple_bb (stmt);
2020 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2022 if (gimple_store_p (stmt))
2023 instrument_object_size (&gsi, true);
2024 if (gimple_assign_load_p (stmt))
2025 instrument_object_size (&gsi, false);
2028 gsi_next (&gsi);
2030 if (gimple_purge_dead_eh_edges (bb))
2031 ret = TODO_cleanup_cfg;
2033 return ret;
2036 } // anon namespace
2038 gimple_opt_pass *
2039 make_pass_ubsan (gcc::context *ctxt)
2041 return new pass_ubsan (ctxt);
2044 #include "gt-ubsan.h"