* tree-ssa.c (target_for_debug_bind, verify_phi_args,
[official-gcc.git] / gcc / ubsan.c
blob5fe6f3d0e2a393aee963974d7ab95256ad4b557d
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2016 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 "tm_p.h"
31 #include "ssa.h"
32 #include "cgraph.h"
33 #include "tree-pretty-print.h"
34 #include "stor-layout.h"
35 #include "cfganal.h"
36 #include "gimple-iterator.h"
37 #include "output.h"
38 #include "cfgloop.h"
39 #include "ubsan.h"
40 #include "expr.h"
41 #include "asan.h"
42 #include "gimplify-me.h"
43 #include "dfp.h"
44 #include "builtins.h"
45 #include "tree-object-size.h"
46 #include "tree-cfg.h"
48 /* Map from a tree to a VAR_DECL tree. */
50 struct GTY((for_user)) tree_type_map {
51 struct tree_map_base type;
52 tree decl;
55 struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
57 static inline hashval_t
58 hash (tree_type_map *t)
60 return TYPE_UID (t->type.from);
63 static inline bool
64 equal (tree_type_map *a, tree_type_map *b)
66 return a->type.from == b->type.from;
69 static int
70 keep_cache_entry (tree_type_map *&m)
72 return ggc_marked_p (m->type.from);
76 static GTY ((cache))
77 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
79 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
81 static tree
82 decl_for_type_lookup (tree type)
84 /* If the hash table is not initialized yet, create it now. */
85 if (decl_tree_for_type == NULL)
87 decl_tree_for_type
88 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
89 /* That also means we don't have to bother with the lookup. */
90 return NULL_TREE;
93 struct tree_type_map *h, in;
94 in.type.from = type;
96 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
97 return h ? h->decl : NULL_TREE;
100 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
102 static void
103 decl_for_type_insert (tree type, tree decl)
105 struct tree_type_map *h;
107 h = ggc_alloc<tree_type_map> ();
108 h->type.from = type;
109 h->decl = decl;
110 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
113 /* Helper routine, which encodes a value in the pointer_sized_int_node.
114 Arguments with precision <= POINTER_SIZE are passed directly,
115 the rest is passed by reference. T is a value we are to encode.
116 IN_EXPAND_P is true if this function is called during expansion. */
118 tree
119 ubsan_encode_value (tree t, bool in_expand_p)
121 tree type = TREE_TYPE (t);
122 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
123 if (bitsize <= POINTER_SIZE)
124 switch (TREE_CODE (type))
126 case BOOLEAN_TYPE:
127 case ENUMERAL_TYPE:
128 case INTEGER_TYPE:
129 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
130 case REAL_TYPE:
132 tree itype = build_nonstandard_integer_type (bitsize, true);
133 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
134 return fold_convert (pointer_sized_int_node, t);
136 default:
137 gcc_unreachable ();
139 else
141 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
143 /* The reason for this is that we don't want to pessimize
144 code by making vars unnecessarily addressable. */
145 tree var = create_tmp_var (type);
146 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
147 if (in_expand_p)
149 rtx mem
150 = assign_stack_temp_for_type (TYPE_MODE (type),
151 GET_MODE_SIZE (TYPE_MODE (type)),
152 type);
153 SET_DECL_RTL (var, mem);
154 expand_assignment (var, t, false);
155 return build_fold_addr_expr (var);
157 t = build_fold_addr_expr (var);
158 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
160 else
161 return build_fold_addr_expr (t);
165 /* Cached ubsan_get_type_descriptor_type () return value. */
166 static GTY(()) tree ubsan_type_descriptor_type;
168 /* Build
169 struct __ubsan_type_descriptor
171 unsigned short __typekind;
172 unsigned short __typeinfo;
173 char __typename[];
175 type. */
177 static tree
178 ubsan_get_type_descriptor_type (void)
180 static const char *field_names[3]
181 = { "__typekind", "__typeinfo", "__typename" };
182 tree fields[3], ret;
184 if (ubsan_type_descriptor_type)
185 return ubsan_type_descriptor_type;
187 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
188 tree flex_arr_type = build_array_type (char_type_node, itype);
190 ret = make_node (RECORD_TYPE);
191 for (int i = 0; i < 3; i++)
193 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
194 get_identifier (field_names[i]),
195 (i == 2) ? flex_arr_type
196 : short_unsigned_type_node);
197 DECL_CONTEXT (fields[i]) = ret;
198 if (i)
199 DECL_CHAIN (fields[i - 1]) = fields[i];
201 tree type_decl = build_decl (input_location, TYPE_DECL,
202 get_identifier ("__ubsan_type_descriptor"),
203 ret);
204 DECL_IGNORED_P (type_decl) = 1;
205 DECL_ARTIFICIAL (type_decl) = 1;
206 TYPE_FIELDS (ret) = fields[0];
207 TYPE_NAME (ret) = type_decl;
208 TYPE_STUB_DECL (ret) = type_decl;
209 layout_type (ret);
210 ubsan_type_descriptor_type = ret;
211 return ret;
214 /* Cached ubsan_get_source_location_type () return value. */
215 static GTY(()) tree ubsan_source_location_type;
217 /* Build
218 struct __ubsan_source_location
220 const char *__filename;
221 unsigned int __line;
222 unsigned int __column;
224 type. */
226 tree
227 ubsan_get_source_location_type (void)
229 static const char *field_names[3]
230 = { "__filename", "__line", "__column" };
231 tree fields[3], ret;
232 if (ubsan_source_location_type)
233 return ubsan_source_location_type;
235 tree const_char_type = build_qualified_type (char_type_node,
236 TYPE_QUAL_CONST);
238 ret = make_node (RECORD_TYPE);
239 for (int i = 0; i < 3; i++)
241 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
242 get_identifier (field_names[i]),
243 (i == 0) ? build_pointer_type (const_char_type)
244 : unsigned_type_node);
245 DECL_CONTEXT (fields[i]) = ret;
246 if (i)
247 DECL_CHAIN (fields[i - 1]) = fields[i];
249 tree type_decl = build_decl (input_location, TYPE_DECL,
250 get_identifier ("__ubsan_source_location"),
251 ret);
252 DECL_IGNORED_P (type_decl) = 1;
253 DECL_ARTIFICIAL (type_decl) = 1;
254 TYPE_FIELDS (ret) = fields[0];
255 TYPE_NAME (ret) = type_decl;
256 TYPE_STUB_DECL (ret) = type_decl;
257 layout_type (ret);
258 ubsan_source_location_type = ret;
259 return ret;
262 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
263 type with its fields filled from a location_t LOC. */
265 static tree
266 ubsan_source_location (location_t loc)
268 expanded_location xloc;
269 tree type = ubsan_get_source_location_type ();
271 xloc = expand_location (loc);
272 tree str;
273 if (xloc.file == NULL)
275 str = build_int_cst (ptr_type_node, 0);
276 xloc.line = 0;
277 xloc.column = 0;
279 else
281 /* Fill in the values from LOC. */
282 size_t len = strlen (xloc.file) + 1;
283 str = build_string (len, xloc.file);
284 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
285 TREE_READONLY (str) = 1;
286 TREE_STATIC (str) = 1;
287 str = build_fold_addr_expr (str);
289 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
290 build_int_cst (unsigned_type_node,
291 xloc.line), NULL_TREE,
292 build_int_cst (unsigned_type_node,
293 xloc.column));
294 TREE_CONSTANT (ctor) = 1;
295 TREE_STATIC (ctor) = 1;
297 return ctor;
300 /* This routine returns a magic number for TYPE. */
302 static unsigned short
303 get_ubsan_type_info_for_type (tree type)
305 if (TREE_CODE (type) == REAL_TYPE)
306 return tree_to_uhwi (TYPE_SIZE (type));
307 else if (INTEGRAL_TYPE_P (type))
309 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
310 gcc_assert (prec != -1);
311 return (prec << 1) | !TYPE_UNSIGNED (type);
313 else
314 return 0;
317 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
318 ubsan_ids[1] for Lubsan_data labels. */
319 static GTY(()) unsigned int ubsan_ids[2];
321 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
322 descriptor. It first looks into the hash table; if not found,
323 create the VAR_DECL, put it into the hash table and return the
324 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
325 an enum controlling how we want to print the type. */
327 tree
328 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
330 /* See through any typedefs. */
331 type = TYPE_MAIN_VARIANT (type);
333 tree decl = decl_for_type_lookup (type);
334 /* It is possible that some of the earlier created DECLs were found
335 unused, in that case they weren't emitted and varpool_node::get
336 returns NULL node on them. But now we really need them. Thus,
337 renew them here. */
338 if (decl != NULL_TREE && varpool_node::get (decl))
339 return build_fold_addr_expr (decl);
341 tree dtype = ubsan_get_type_descriptor_type ();
342 tree type2 = type;
343 const char *tname = NULL;
344 pretty_printer pretty_name;
345 unsigned char deref_depth = 0;
346 unsigned short tkind, tinfo;
348 /* Get the name of the type, or the name of the pointer type. */
349 if (pstyle == UBSAN_PRINT_POINTER)
351 gcc_assert (POINTER_TYPE_P (type));
352 type2 = TREE_TYPE (type);
354 /* Remove any '*' operators from TYPE. */
355 while (POINTER_TYPE_P (type2))
356 deref_depth++, type2 = TREE_TYPE (type2);
358 if (TREE_CODE (type2) == METHOD_TYPE)
359 type2 = TYPE_METHOD_BASETYPE (type2);
362 /* If an array, get its type. */
363 type2 = strip_array_types (type2);
365 if (pstyle == UBSAN_PRINT_ARRAY)
367 while (POINTER_TYPE_P (type2))
368 deref_depth++, type2 = TREE_TYPE (type2);
371 if (TYPE_NAME (type2) != NULL)
373 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
374 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
375 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
376 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
379 if (tname == NULL)
380 /* We weren't able to determine the type name. */
381 tname = "<unknown>";
383 if (pstyle == UBSAN_PRINT_POINTER)
385 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
386 TYPE_VOLATILE (type2) ? "volatile " : "",
387 TYPE_READONLY (type2) ? "const " : "",
388 TYPE_RESTRICT (type2) ? "restrict " : "",
389 TYPE_ATOMIC (type2) ? "_Atomic " : "",
390 TREE_CODE (type2) == RECORD_TYPE
391 ? "struct "
392 : TREE_CODE (type2) == UNION_TYPE
393 ? "union " : "", tname,
394 deref_depth == 0 ? "" : " ");
395 while (deref_depth-- > 0)
396 pp_star (&pretty_name);
397 pp_quote (&pretty_name);
399 else if (pstyle == UBSAN_PRINT_ARRAY)
401 /* Pretty print the array dimensions. */
402 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
403 tree t = type;
404 pp_printf (&pretty_name, "'%s ", tname);
405 while (deref_depth-- > 0)
406 pp_star (&pretty_name);
407 while (TREE_CODE (t) == ARRAY_TYPE)
409 pp_left_bracket (&pretty_name);
410 tree dom = TYPE_DOMAIN (t);
411 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
413 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
414 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
415 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
416 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
417 else
418 pp_wide_int (&pretty_name,
419 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
420 TYPE_SIGN (TREE_TYPE (dom)));
422 else
423 /* ??? We can't determine the variable name; print VLA unspec. */
424 pp_star (&pretty_name);
425 pp_right_bracket (&pretty_name);
426 t = TREE_TYPE (t);
428 pp_quote (&pretty_name);
430 /* Save the tree with stripped types. */
431 type = t;
433 else
434 pp_printf (&pretty_name, "'%s'", tname);
436 switch (TREE_CODE (type))
438 case BOOLEAN_TYPE:
439 case ENUMERAL_TYPE:
440 case INTEGER_TYPE:
441 tkind = 0x0000;
442 break;
443 case REAL_TYPE:
444 /* FIXME: libubsan right now only supports float, double and
445 long double type formats. */
446 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
447 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
448 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
449 tkind = 0x0001;
450 else
451 tkind = 0xffff;
452 break;
453 default:
454 tkind = 0xffff;
455 break;
457 tinfo = get_ubsan_type_info_for_type (type);
459 /* Create a new VAR_DECL of type descriptor. */
460 const char *tmp = pp_formatted_text (&pretty_name);
461 size_t len = strlen (tmp) + 1;
462 tree str = build_string (len, tmp);
463 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
464 TREE_READONLY (str) = 1;
465 TREE_STATIC (str) = 1;
467 char tmp_name[32];
468 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
469 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
470 dtype);
471 TREE_STATIC (decl) = 1;
472 TREE_PUBLIC (decl) = 0;
473 DECL_ARTIFICIAL (decl) = 1;
474 DECL_IGNORED_P (decl) = 1;
475 DECL_EXTERNAL (decl) = 0;
476 DECL_SIZE (decl)
477 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
478 DECL_SIZE_UNIT (decl)
479 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
480 TYPE_SIZE_UNIT (TREE_TYPE (str)));
482 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
483 build_int_cst (short_unsigned_type_node,
484 tkind), NULL_TREE,
485 build_int_cst (short_unsigned_type_node,
486 tinfo), NULL_TREE, str);
487 TREE_CONSTANT (ctor) = 1;
488 TREE_STATIC (ctor) = 1;
489 DECL_INITIAL (decl) = ctor;
490 varpool_node::finalize_decl (decl);
492 /* Save the VAR_DECL into the hash table. */
493 decl_for_type_insert (type, decl);
495 return build_fold_addr_expr (decl);
498 /* Create a structure for the ubsan library. NAME is a name of the new
499 structure. LOCCNT is number of locations, PLOC points to array of
500 locations. The arguments in ... are of __ubsan_type_descriptor type
501 and there are at most two of them, followed by NULL_TREE, followed
502 by optional extra arguments and another NULL_TREE. */
504 tree
505 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
507 va_list args;
508 tree ret, t;
509 tree fields[6];
510 vec<tree, va_gc> *saved_args = NULL;
511 size_t i = 0;
512 int j;
514 /* It is possible that PCH zapped table with definitions of sanitizer
515 builtins. Reinitialize them if needed. */
516 initialize_sanitizer_builtins ();
518 /* Firstly, create a pointer to type descriptor type. */
519 tree td_type = ubsan_get_type_descriptor_type ();
520 td_type = build_pointer_type (td_type);
522 /* Create the structure type. */
523 ret = make_node (RECORD_TYPE);
524 for (j = 0; j < loccnt; j++)
526 gcc_checking_assert (i < 2);
527 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
528 ubsan_get_source_location_type ());
529 DECL_CONTEXT (fields[i]) = ret;
530 if (i)
531 DECL_CHAIN (fields[i - 1]) = fields[i];
532 i++;
535 va_start (args, ploc);
536 for (t = va_arg (args, tree); t != NULL_TREE;
537 i++, t = va_arg (args, tree))
539 gcc_checking_assert (i < 4);
540 /* Save the tree arguments for later use. */
541 vec_safe_push (saved_args, t);
542 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
543 td_type);
544 DECL_CONTEXT (fields[i]) = ret;
545 if (i)
546 DECL_CHAIN (fields[i - 1]) = fields[i];
549 for (t = va_arg (args, tree); t != NULL_TREE;
550 i++, t = va_arg (args, tree))
552 gcc_checking_assert (i < 6);
553 /* Save the tree arguments for later use. */
554 vec_safe_push (saved_args, t);
555 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
556 TREE_TYPE (t));
557 DECL_CONTEXT (fields[i]) = ret;
558 if (i)
559 DECL_CHAIN (fields[i - 1]) = fields[i];
561 va_end (args);
563 tree type_decl = build_decl (input_location, TYPE_DECL,
564 get_identifier (name), ret);
565 DECL_IGNORED_P (type_decl) = 1;
566 DECL_ARTIFICIAL (type_decl) = 1;
567 TYPE_FIELDS (ret) = fields[0];
568 TYPE_NAME (ret) = type_decl;
569 TYPE_STUB_DECL (ret) = type_decl;
570 layout_type (ret);
572 /* Now, fill in the type. */
573 char tmp_name[32];
574 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
575 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
576 ret);
577 TREE_STATIC (var) = 1;
578 TREE_PUBLIC (var) = 0;
579 DECL_ARTIFICIAL (var) = 1;
580 DECL_IGNORED_P (var) = 1;
581 DECL_EXTERNAL (var) = 0;
583 vec<constructor_elt, va_gc> *v;
584 vec_alloc (v, i);
585 tree ctor = build_constructor (ret, v);
587 /* If desirable, set the __ubsan_source_location element. */
588 for (j = 0; j < loccnt; j++)
590 location_t loc = LOCATION_LOCUS (ploc[j]);
591 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
594 size_t nelts = vec_safe_length (saved_args);
595 for (i = 0; i < nelts; i++)
597 t = (*saved_args)[i];
598 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
601 TREE_CONSTANT (ctor) = 1;
602 TREE_STATIC (ctor) = 1;
603 DECL_INITIAL (var) = ctor;
604 varpool_node::finalize_decl (var);
606 return var;
609 /* Instrument the __builtin_unreachable call. We just call the libubsan
610 routine instead. */
612 bool
613 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
615 gimple *g;
616 location_t loc = gimple_location (gsi_stmt (*gsi));
618 if (flag_sanitize_undefined_trap_on_error)
619 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
620 else
622 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
623 NULL_TREE, NULL_TREE);
624 data = build_fold_addr_expr_loc (loc, data);
625 tree fn
626 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
627 g = gimple_build_call (fn, 1, data);
629 gimple_set_location (g, loc);
630 gsi_replace (gsi, g, false);
631 return false;
634 /* Return true if T is a call to a libubsan routine. */
636 bool
637 is_ubsan_builtin_p (tree t)
639 return TREE_CODE (t) == FUNCTION_DECL
640 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
641 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
642 "__builtin___ubsan_", 18) == 0;
645 /* Create a callgraph edge for statement STMT. */
647 static void
648 ubsan_create_edge (gimple *stmt)
650 gcall *call_stmt = dyn_cast <gcall *> (stmt);
651 basic_block bb = gimple_bb (stmt);
652 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
653 cgraph_node *node = cgraph_node::get (current_function_decl);
654 tree decl = gimple_call_fndecl (call_stmt);
655 if (decl)
656 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
657 freq);
660 /* Expand the UBSAN_BOUNDS special builtin function. */
662 bool
663 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
665 gimple *stmt = gsi_stmt (*gsi);
666 location_t loc = gimple_location (stmt);
667 gcc_assert (gimple_call_num_args (stmt) == 3);
669 /* Pick up the arguments of the UBSAN_BOUNDS call. */
670 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
671 tree index = gimple_call_arg (stmt, 1);
672 tree orig_index_type = TREE_TYPE (index);
673 tree bound = gimple_call_arg (stmt, 2);
675 gimple_stmt_iterator gsi_orig = *gsi;
677 /* Create condition "if (index > bound)". */
678 basic_block then_bb, fallthru_bb;
679 gimple_stmt_iterator cond_insert_point
680 = create_cond_insert_point (gsi, false, false, true,
681 &then_bb, &fallthru_bb);
682 index = fold_convert (TREE_TYPE (bound), index);
683 index = force_gimple_operand_gsi (&cond_insert_point, index,
684 true, NULL_TREE,
685 false, GSI_NEW_STMT);
686 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
687 gimple_set_location (g, loc);
688 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
690 /* Generate __ubsan_handle_out_of_bounds call. */
691 *gsi = gsi_after_labels (then_bb);
692 if (flag_sanitize_undefined_trap_on_error)
693 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
694 else
696 tree data
697 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
698 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
699 ubsan_type_descriptor (orig_index_type),
700 NULL_TREE, NULL_TREE);
701 data = build_fold_addr_expr_loc (loc, data);
702 enum built_in_function bcode
703 = (flag_sanitize_recover & SANITIZE_BOUNDS)
704 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
705 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
706 tree fn = builtin_decl_explicit (bcode);
707 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
708 true, NULL_TREE, true,
709 GSI_SAME_STMT);
710 g = gimple_build_call (fn, 2, data, val);
712 gimple_set_location (g, loc);
713 gsi_insert_before (gsi, g, GSI_SAME_STMT);
715 /* Get rid of the UBSAN_BOUNDS call from the IR. */
716 unlink_stmt_vdef (stmt);
717 gsi_remove (&gsi_orig, true);
719 /* Point GSI to next logical statement. */
720 *gsi = gsi_start_bb (fallthru_bb);
721 return true;
724 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
725 argument which is a constant, because the middle-end treats pointer
726 conversions as useless and therefore the type of the first argument
727 could be changed to any other pointer type. */
729 bool
730 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
732 gimple_stmt_iterator gsi = *gsip;
733 gimple *stmt = gsi_stmt (gsi);
734 location_t loc = gimple_location (stmt);
735 gcc_assert (gimple_call_num_args (stmt) == 3);
736 tree ptr = gimple_call_arg (stmt, 0);
737 tree ckind = gimple_call_arg (stmt, 1);
738 tree align = gimple_call_arg (stmt, 2);
739 tree check_align = NULL_TREE;
740 bool check_null;
742 basic_block cur_bb = gsi_bb (gsi);
744 gimple *g;
745 if (!integer_zerop (align))
747 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
748 if (compare_tree_int (align, ptralign) == 1)
750 check_align = make_ssa_name (pointer_sized_int_node);
751 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
752 gimple_set_location (g, loc);
753 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
756 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
758 if (check_align == NULL_TREE && !check_null)
760 gsi_remove (gsip, true);
761 /* Unlink the UBSAN_NULLs vops before replacing it. */
762 unlink_stmt_vdef (stmt);
763 return true;
766 /* Split the original block holding the pointer dereference. */
767 edge e = split_block (cur_bb, stmt);
769 /* Get a hold on the 'condition block', the 'then block' and the
770 'else block'. */
771 basic_block cond_bb = e->src;
772 basic_block fallthru_bb = e->dest;
773 basic_block then_bb = create_empty_bb (cond_bb);
774 add_bb_to_loop (then_bb, cond_bb->loop_father);
775 loops_state_set (LOOPS_NEED_FIXUP);
777 /* Make an edge coming from the 'cond block' into the 'then block';
778 this edge is unlikely taken, so set up the probability accordingly. */
779 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
780 e->probability = PROB_VERY_UNLIKELY;
782 /* Connect 'then block' with the 'else block'. This is needed
783 as the ubsan routines we call in the 'then block' are not noreturn.
784 The 'then block' only has one outcoming edge. */
785 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
787 /* Set up the fallthrough basic block. */
788 e = find_edge (cond_bb, fallthru_bb);
789 e->flags = EDGE_FALSE_VALUE;
790 e->count = cond_bb->count;
791 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
793 /* Update dominance info for the newly created then_bb; note that
794 fallthru_bb's dominance info has already been updated by
795 split_block. */
796 if (dom_info_available_p (CDI_DOMINATORS))
797 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
799 /* Put the ubsan builtin call into the newly created BB. */
800 if (flag_sanitize_undefined_trap_on_error)
801 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
802 else
804 enum built_in_function bcode
805 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
806 | (check_null ? SANITIZE_NULL : 0)))
807 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
808 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
809 tree fn = builtin_decl_implicit (bcode);
810 tree data
811 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
812 ubsan_type_descriptor (TREE_TYPE (ckind),
813 UBSAN_PRINT_POINTER),
814 NULL_TREE,
815 align,
816 fold_convert (unsigned_char_type_node, ckind),
817 NULL_TREE);
818 data = build_fold_addr_expr_loc (loc, data);
819 g = gimple_build_call (fn, 2, data,
820 check_align ? check_align
821 : build_zero_cst (pointer_sized_int_node));
823 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
824 gimple_set_location (g, loc);
825 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
827 /* Unlink the UBSAN_NULLs vops before replacing it. */
828 unlink_stmt_vdef (stmt);
830 if (check_null)
832 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
833 NULL_TREE, NULL_TREE);
834 gimple_set_location (g, loc);
836 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
837 gsi_replace (&gsi, g, false);
838 stmt = g;
841 if (check_align)
843 if (check_null)
845 /* Split the block with the condition again. */
846 e = split_block (cond_bb, stmt);
847 basic_block cond1_bb = e->src;
848 basic_block cond2_bb = e->dest;
850 /* Make an edge coming from the 'cond1 block' into the 'then block';
851 this edge is unlikely taken, so set up the probability
852 accordingly. */
853 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
854 e->probability = PROB_VERY_UNLIKELY;
856 /* Set up the fallthrough basic block. */
857 e = find_edge (cond1_bb, cond2_bb);
858 e->flags = EDGE_FALSE_VALUE;
859 e->count = cond1_bb->count;
860 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
862 /* Update dominance info. */
863 if (dom_info_available_p (CDI_DOMINATORS))
865 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
866 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
869 gsi2 = gsi_start_bb (cond2_bb);
872 tree mask = build_int_cst (pointer_sized_int_node,
873 tree_to_uhwi (align) - 1);
874 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
875 BIT_AND_EXPR, check_align, mask);
876 gimple_set_location (g, loc);
877 if (check_null)
878 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
879 else
880 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
882 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
883 build_int_cst (pointer_sized_int_node, 0),
884 NULL_TREE, NULL_TREE);
885 gimple_set_location (g, loc);
886 if (check_null)
887 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
888 else
889 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
890 gsi_replace (&gsi, g, false);
892 return false;
895 #define OBJSZ_MAX_OFFSET (1024 * 16)
897 /* Expand UBSAN_OBJECT_SIZE internal call. */
899 bool
900 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
902 gimple *stmt = gsi_stmt (*gsi);
903 location_t loc = gimple_location (stmt);
904 gcc_assert (gimple_call_num_args (stmt) == 4);
906 tree ptr = gimple_call_arg (stmt, 0);
907 tree offset = gimple_call_arg (stmt, 1);
908 tree size = gimple_call_arg (stmt, 2);
909 tree ckind = gimple_call_arg (stmt, 3);
910 gimple_stmt_iterator gsi_orig = *gsi;
911 gimple *g;
913 /* See if we can discard the check. */
914 if (TREE_CODE (size) != INTEGER_CST
915 || integer_all_onesp (size))
916 /* Yes, __builtin_object_size couldn't determine the
917 object size. */;
918 else if (TREE_CODE (offset) == INTEGER_CST
919 && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
920 && wi::to_widest (offset) <= -1)
921 /* The offset is in range [-16K, -1]. */;
922 else
924 /* if (offset > objsize) */
925 basic_block then_bb, fallthru_bb;
926 gimple_stmt_iterator cond_insert_point
927 = create_cond_insert_point (gsi, false, false, true,
928 &then_bb, &fallthru_bb);
929 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
930 gimple_set_location (g, loc);
931 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
933 /* If the offset is small enough, we don't need the second
934 run-time check. */
935 if (TREE_CODE (offset) == INTEGER_CST
936 && wi::to_widest (offset) >= 0
937 && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
938 *gsi = gsi_after_labels (then_bb);
939 else
941 /* Don't issue run-time error if (ptr > ptr + offset). That
942 may happen when computing a POINTER_PLUS_EXPR. */
943 basic_block then2_bb, fallthru2_bb;
945 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
946 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
947 true, &then2_bb,
948 &fallthru2_bb);
949 /* Convert the pointer to an integer type. */
950 tree p = make_ssa_name (pointer_sized_int_node);
951 g = gimple_build_assign (p, NOP_EXPR, ptr);
952 gimple_set_location (g, loc);
953 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
954 p = gimple_assign_lhs (g);
955 /* Compute ptr + offset. */
956 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
957 PLUS_EXPR, p, offset);
958 gimple_set_location (g, loc);
959 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
960 /* Now build the conditional and put it into the IR. */
961 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
962 NULL_TREE, NULL_TREE);
963 gimple_set_location (g, loc);
964 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
965 *gsi = gsi_after_labels (then2_bb);
968 /* Generate __ubsan_handle_type_mismatch call. */
969 if (flag_sanitize_undefined_trap_on_error)
970 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
971 else
973 tree data
974 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
975 ubsan_type_descriptor (TREE_TYPE (ptr),
976 UBSAN_PRINT_POINTER),
977 NULL_TREE,
978 build_zero_cst (pointer_sized_int_node),
979 ckind,
980 NULL_TREE);
981 data = build_fold_addr_expr_loc (loc, data);
982 enum built_in_function bcode
983 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
984 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
985 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
986 tree p = make_ssa_name (pointer_sized_int_node);
987 g = gimple_build_assign (p, NOP_EXPR, ptr);
988 gimple_set_location (g, loc);
989 gsi_insert_before (gsi, g, GSI_SAME_STMT);
990 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
992 gimple_set_location (g, loc);
993 gsi_insert_before (gsi, g, GSI_SAME_STMT);
995 /* Point GSI to next logical statement. */
996 *gsi = gsi_start_bb (fallthru_bb);
998 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
999 unlink_stmt_vdef (stmt);
1000 gsi_remove (&gsi_orig, true);
1001 return true;
1004 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1005 unlink_stmt_vdef (stmt);
1006 gsi_remove (gsi, true);
1007 return true;
1010 /* Cached __ubsan_vptr_type_cache decl. */
1011 static GTY(()) tree ubsan_vptr_type_cache_decl;
1013 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1014 argument which is a constant, because the middle-end treats pointer
1015 conversions as useless and therefore the type of the first argument
1016 could be changed to any other pointer type. */
1018 bool
1019 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1021 gimple_stmt_iterator gsi = *gsip;
1022 gimple *stmt = gsi_stmt (gsi);
1023 location_t loc = gimple_location (stmt);
1024 gcc_assert (gimple_call_num_args (stmt) == 5);
1025 tree op = gimple_call_arg (stmt, 0);
1026 tree vptr = gimple_call_arg (stmt, 1);
1027 tree str_hash = gimple_call_arg (stmt, 2);
1028 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1029 tree ckind_tree = gimple_call_arg (stmt, 4);
1030 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1031 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1032 gimple *g;
1033 basic_block fallthru_bb = NULL;
1035 if (ckind == UBSAN_DOWNCAST_POINTER)
1037 /* Guard everything with if (op != NULL) { ... }. */
1038 basic_block then_bb;
1039 gimple_stmt_iterator cond_insert_point
1040 = create_cond_insert_point (gsip, false, false, true,
1041 &then_bb, &fallthru_bb);
1042 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1043 NULL_TREE, NULL_TREE);
1044 gimple_set_location (g, loc);
1045 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1046 *gsip = gsi_after_labels (then_bb);
1047 gsi_remove (&gsi, false);
1048 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1049 gsi = *gsip;
1052 tree htype = TREE_TYPE (str_hash);
1053 tree cst = wide_int_to_tree (htype,
1054 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1055 | 0xeb382d69, 64));
1056 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1057 vptr, str_hash);
1058 gimple_set_location (g, loc);
1059 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1060 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1061 gimple_assign_lhs (g), cst);
1062 gimple_set_location (g, loc);
1063 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1064 tree t1 = gimple_assign_lhs (g);
1065 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1066 t1, build_int_cst (integer_type_node, 47));
1067 gimple_set_location (g, loc);
1068 tree t2 = gimple_assign_lhs (g);
1069 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1070 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1071 vptr, t1);
1072 gimple_set_location (g, loc);
1073 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1074 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1075 t2, gimple_assign_lhs (g));
1076 gimple_set_location (g, loc);
1077 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1078 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1079 gimple_assign_lhs (g), cst);
1080 gimple_set_location (g, loc);
1081 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1082 tree t3 = gimple_assign_lhs (g);
1083 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1084 t3, build_int_cst (integer_type_node, 47));
1085 gimple_set_location (g, loc);
1086 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1087 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1088 t3, gimple_assign_lhs (g));
1089 gimple_set_location (g, loc);
1090 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1091 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1092 gimple_assign_lhs (g), cst);
1093 gimple_set_location (g, loc);
1094 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1095 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1097 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1098 NOP_EXPR, gimple_assign_lhs (g));
1099 gimple_set_location (g, loc);
1100 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1102 tree hash = gimple_assign_lhs (g);
1104 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1106 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1107 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1108 get_identifier ("__ubsan_vptr_type_cache"),
1109 atype);
1110 DECL_ARTIFICIAL (array) = 1;
1111 DECL_IGNORED_P (array) = 1;
1112 TREE_PUBLIC (array) = 1;
1113 TREE_STATIC (array) = 1;
1114 DECL_EXTERNAL (array) = 1;
1115 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1116 DECL_VISIBILITY_SPECIFIED (array) = 1;
1117 varpool_node::finalize_decl (array);
1118 ubsan_vptr_type_cache_decl = array;
1121 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1122 BIT_AND_EXPR, hash,
1123 build_int_cst (pointer_sized_int_node, 127));
1124 gimple_set_location (g, loc);
1125 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1127 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1128 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1129 NULL_TREE, NULL_TREE);
1130 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1131 ARRAY_REF, c);
1132 gimple_set_location (g, loc);
1133 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1135 basic_block then_bb, fallthru2_bb;
1136 gimple_stmt_iterator cond_insert_point
1137 = create_cond_insert_point (gsip, false, false, true,
1138 &then_bb, &fallthru2_bb);
1139 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1140 NULL_TREE, NULL_TREE);
1141 gimple_set_location (g, loc);
1142 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1143 *gsip = gsi_after_labels (then_bb);
1144 if (fallthru_bb == NULL)
1145 fallthru_bb = fallthru2_bb;
1147 tree data
1148 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1149 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1150 build_int_cst (unsigned_char_type_node, ckind),
1151 NULL_TREE);
1152 data = build_fold_addr_expr_loc (loc, data);
1153 enum built_in_function bcode
1154 = (flag_sanitize_recover & SANITIZE_VPTR)
1155 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1156 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1158 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1159 gimple_set_location (g, loc);
1160 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1162 /* Point GSI to next logical statement. */
1163 *gsip = gsi_start_bb (fallthru_bb);
1165 /* Get rid of the UBSAN_VPTR call from the IR. */
1166 unlink_stmt_vdef (stmt);
1167 gsi_remove (&gsi, true);
1168 return true;
1171 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1172 whether the pointer is on the left hand side of the assignment. */
1174 static void
1175 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1176 bool is_lhs)
1178 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1179 unsigned int align = 0;
1180 if (flag_sanitize & SANITIZE_ALIGNMENT)
1182 align = min_align_of_type (TREE_TYPE (base));
1183 if (align <= 1)
1184 align = 0;
1186 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1187 return;
1188 tree t = TREE_OPERAND (base, 0);
1189 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1190 return;
1191 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1192 ikind = UBSAN_MEMBER_ACCESS;
1193 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1194 tree alignt = build_int_cst (pointer_sized_int_node, align);
1195 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1196 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1197 gsi_insert_before (iter, g, GSI_SAME_STMT);
1200 /* Perform the pointer instrumentation. */
1202 static void
1203 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1205 gimple *stmt = gsi_stmt (gsi);
1206 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1207 tree base = get_base_address (t);
1208 const enum tree_code code = TREE_CODE (base);
1209 if (code == MEM_REF
1210 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1211 instrument_mem_ref (t, base, &gsi, is_lhs);
1214 /* Build an ubsan builtin call for the signed-integer-overflow
1215 sanitization. CODE says what kind of builtin are we building,
1216 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1217 are operands of the binary operation. */
1219 tree
1220 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1221 tree op0, tree op1)
1223 if (flag_sanitize_undefined_trap_on_error)
1224 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1226 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1227 ubsan_type_descriptor (lhstype), NULL_TREE,
1228 NULL_TREE);
1229 enum built_in_function fn_code;
1231 switch (code)
1233 case PLUS_EXPR:
1234 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1235 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1236 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1237 break;
1238 case MINUS_EXPR:
1239 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1240 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1241 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1242 break;
1243 case MULT_EXPR:
1244 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1245 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1246 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1247 break;
1248 case NEGATE_EXPR:
1249 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1250 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1251 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1252 break;
1253 default:
1254 gcc_unreachable ();
1256 tree fn = builtin_decl_explicit (fn_code);
1257 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1258 build_fold_addr_expr_loc (loc, data),
1259 ubsan_encode_value (op0, true),
1260 op1 ? ubsan_encode_value (op1, true)
1261 : NULL_TREE);
1264 /* Perform the signed integer instrumentation. GSI is the iterator
1265 pointing at statement we are trying to instrument. */
1267 static void
1268 instrument_si_overflow (gimple_stmt_iterator gsi)
1270 gimple *stmt = gsi_stmt (gsi);
1271 tree_code code = gimple_assign_rhs_code (stmt);
1272 tree lhs = gimple_assign_lhs (stmt);
1273 tree lhstype = TREE_TYPE (lhs);
1274 tree a, b;
1275 gimple *g;
1277 /* If this is not a signed operation, don't instrument anything here.
1278 Also punt on bit-fields. */
1279 if (!INTEGRAL_TYPE_P (lhstype)
1280 || TYPE_OVERFLOW_WRAPS (lhstype)
1281 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1282 return;
1284 switch (code)
1286 case MINUS_EXPR:
1287 case PLUS_EXPR:
1288 case MULT_EXPR:
1289 /* Transform
1290 i = u {+,-,*} 5;
1291 into
1292 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1293 a = gimple_assign_rhs1 (stmt);
1294 b = gimple_assign_rhs2 (stmt);
1295 g = gimple_build_call_internal (code == PLUS_EXPR
1296 ? IFN_UBSAN_CHECK_ADD
1297 : code == MINUS_EXPR
1298 ? IFN_UBSAN_CHECK_SUB
1299 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1300 gimple_call_set_lhs (g, lhs);
1301 gsi_replace (&gsi, g, true);
1302 break;
1303 case NEGATE_EXPR:
1304 /* Represent i = -u;
1306 i = UBSAN_CHECK_SUB (0, u); */
1307 a = build_int_cst (lhstype, 0);
1308 b = gimple_assign_rhs1 (stmt);
1309 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1310 gimple_call_set_lhs (g, lhs);
1311 gsi_replace (&gsi, g, true);
1312 break;
1313 case ABS_EXPR:
1314 /* Transform i = ABS_EXPR<u>;
1315 into
1316 _N = UBSAN_CHECK_SUB (0, u);
1317 i = ABS_EXPR<_N>; */
1318 a = build_int_cst (lhstype, 0);
1319 b = gimple_assign_rhs1 (stmt);
1320 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1321 a = make_ssa_name (lhstype);
1322 gimple_call_set_lhs (g, a);
1323 gimple_set_location (g, gimple_location (stmt));
1324 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1325 gimple_assign_set_rhs1 (stmt, a);
1326 update_stmt (stmt);
1327 break;
1328 default:
1329 break;
1333 /* Instrument loads from (non-bitfield) bool and C++ enum values
1334 to check if the memory value is outside of the range of the valid
1335 type values. */
1337 static void
1338 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1340 gimple *stmt = gsi_stmt (*gsi);
1341 tree rhs = gimple_assign_rhs1 (stmt);
1342 tree type = TREE_TYPE (rhs);
1343 tree minv = NULL_TREE, maxv = NULL_TREE;
1345 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1347 minv = boolean_false_node;
1348 maxv = boolean_true_node;
1350 else if (TREE_CODE (type) == ENUMERAL_TYPE
1351 && (flag_sanitize & SANITIZE_ENUM)
1352 && TREE_TYPE (type) != NULL_TREE
1353 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1354 && (TYPE_PRECISION (TREE_TYPE (type))
1355 < GET_MODE_PRECISION (TYPE_MODE (type))))
1357 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1358 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1360 else
1361 return;
1363 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1364 HOST_WIDE_INT bitsize, bitpos;
1365 tree offset;
1366 machine_mode mode;
1367 int volatilep = 0, reversep, unsignedp = 0;
1368 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1369 &unsignedp, &reversep, &volatilep);
1370 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1372 if ((VAR_P (base) && DECL_HARD_REGISTER (base))
1373 || (bitpos % modebitsize) != 0
1374 || bitsize != modebitsize
1375 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1376 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1377 return;
1379 bool ends_bb = stmt_ends_bb_p (stmt);
1380 location_t loc = gimple_location (stmt);
1381 tree lhs = gimple_assign_lhs (stmt);
1382 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1383 tree atype = reference_alias_ptr_type (rhs);
1384 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1385 build_fold_addr_expr (rhs));
1386 gimple_set_location (g, loc);
1387 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1388 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1389 build_int_cst (atype, 0));
1390 tree urhs = make_ssa_name (utype);
1391 if (ends_bb)
1393 gimple_assign_set_lhs (stmt, urhs);
1394 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1395 gimple_set_location (g, loc);
1396 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1397 gsi_insert_on_edge_immediate (e, g);
1398 gimple_assign_set_rhs_from_tree (gsi, mem);
1399 update_stmt (stmt);
1400 *gsi = gsi_for_stmt (g);
1401 g = stmt;
1403 else
1405 g = gimple_build_assign (urhs, mem);
1406 gimple_set_location (g, loc);
1407 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1409 minv = fold_convert (utype, minv);
1410 maxv = fold_convert (utype, maxv);
1411 if (!integer_zerop (minv))
1413 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1414 gimple_set_location (g, loc);
1415 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1418 gimple_stmt_iterator gsi2 = *gsi;
1419 basic_block then_bb, fallthru_bb;
1420 *gsi = create_cond_insert_point (gsi, true, false, true,
1421 &then_bb, &fallthru_bb);
1422 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1423 int_const_binop (MINUS_EXPR, maxv, minv),
1424 NULL_TREE, NULL_TREE);
1425 gimple_set_location (g, loc);
1426 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1428 if (!ends_bb)
1430 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1431 update_stmt (stmt);
1434 gsi2 = gsi_after_labels (then_bb);
1435 if (flag_sanitize_undefined_trap_on_error)
1436 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1437 else
1439 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1440 ubsan_type_descriptor (type), NULL_TREE,
1441 NULL_TREE);
1442 data = build_fold_addr_expr_loc (loc, data);
1443 enum built_in_function bcode
1444 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1445 ? SANITIZE_BOOL : SANITIZE_ENUM))
1446 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1447 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1448 tree fn = builtin_decl_explicit (bcode);
1450 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1451 true, NULL_TREE, true,
1452 GSI_SAME_STMT);
1453 g = gimple_build_call (fn, 2, data, val);
1455 gimple_set_location (g, loc);
1456 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1457 ubsan_create_edge (g);
1458 *gsi = gsi_for_stmt (stmt);
1461 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1462 new style handlers. Libubsan uses heuristics to destinguish between old and
1463 new styles and relies on these properties for filename:
1465 a) Location's filename must not be NULL.
1466 b) Location's filename must not be equal to "".
1467 c) Location's filename must not be equal to "\1".
1468 d) First two bytes of filename must not contain '\xff' symbol. */
1470 static bool
1471 ubsan_use_new_style_p (location_t loc)
1473 if (loc == UNKNOWN_LOCATION)
1474 return false;
1476 expanded_location xloc = expand_location (loc);
1477 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1478 || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1479 || xloc.file[1] == '\xff')
1480 return false;
1482 return true;
1485 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1486 destination, EXPR is floating-point expression. */
1488 tree
1489 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1491 tree expr_type = TREE_TYPE (expr);
1492 tree t, tt, fn, min, max;
1493 machine_mode mode = TYPE_MODE (expr_type);
1494 int prec = TYPE_PRECISION (type);
1495 bool uns_p = TYPE_UNSIGNED (type);
1496 if (loc == UNKNOWN_LOCATION)
1497 loc = input_location;
1499 /* Float to integer conversion first truncates toward zero, so
1500 even signed char c = 127.875f; is not problematic.
1501 Therefore, we should complain only if EXPR is unordered or smaller
1502 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1503 TYPE_MAX_VALUE + 1.0. */
1504 if (REAL_MODE_FORMAT (mode)->b == 2)
1506 /* For maximum, TYPE_MAX_VALUE might not be representable
1507 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1508 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1509 either representable or infinity. */
1510 REAL_VALUE_TYPE maxval = dconst1;
1511 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1512 real_convert (&maxval, mode, &maxval);
1513 max = build_real (expr_type, maxval);
1515 /* For unsigned, assume -1.0 is always representable. */
1516 if (uns_p)
1517 min = build_minus_one_cst (expr_type);
1518 else
1520 /* TYPE_MIN_VALUE is generally representable (or -inf),
1521 but TYPE_MIN_VALUE - 1.0 might not be. */
1522 REAL_VALUE_TYPE minval = dconstm1, minval2;
1523 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1524 real_convert (&minval, mode, &minval);
1525 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1526 real_convert (&minval2, mode, &minval2);
1527 if (real_compare (EQ_EXPR, &minval, &minval2)
1528 && !real_isinf (&minval))
1530 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1531 rounds to TYPE_MIN_VALUE, we need to subtract
1532 more. As REAL_MODE_FORMAT (mode)->p is the number
1533 of base digits, we want to subtract a number that
1534 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1535 times smaller than minval. */
1536 minval2 = dconst1;
1537 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1538 SET_REAL_EXP (&minval2,
1539 REAL_EXP (&minval2) + prec - 1
1540 - REAL_MODE_FORMAT (mode)->p + 1);
1541 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1542 real_convert (&minval2, mode, &minval2);
1544 min = build_real (expr_type, minval2);
1547 else if (REAL_MODE_FORMAT (mode)->b == 10)
1549 /* For _Decimal128 up to 34 decimal digits, - sign,
1550 dot, e, exponent. */
1551 char buf[64];
1552 mpfr_t m;
1553 int p = REAL_MODE_FORMAT (mode)->p;
1554 REAL_VALUE_TYPE maxval, minval;
1556 /* Use mpfr_snprintf rounding to compute the smallest
1557 representable decimal number greater or equal than
1558 1 << (prec - !uns_p). */
1559 mpfr_init2 (m, prec + 2);
1560 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1561 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1562 decimal_real_from_string (&maxval, buf);
1563 max = build_real (expr_type, maxval);
1565 /* For unsigned, assume -1.0 is always representable. */
1566 if (uns_p)
1567 min = build_minus_one_cst (expr_type);
1568 else
1570 /* Use mpfr_snprintf rounding to compute the largest
1571 representable decimal number less or equal than
1572 (-1 << (prec - 1)) - 1. */
1573 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1574 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1575 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1576 decimal_real_from_string (&minval, buf);
1577 min = build_real (expr_type, minval);
1579 mpfr_clear (m);
1581 else
1582 return NULL_TREE;
1584 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1585 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1586 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1587 if (integer_zerop (t))
1588 return NULL_TREE;
1590 if (flag_sanitize_undefined_trap_on_error)
1591 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1592 else
1594 location_t *loc_ptr = NULL;
1595 unsigned num_locations = 0;
1596 /* Figure out if we can propagate location to ubsan_data and use new
1597 style handlers in libubsan. */
1598 if (ubsan_use_new_style_p (loc))
1600 loc_ptr = &loc;
1601 num_locations = 1;
1603 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1604 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1605 num_locations, loc_ptr,
1606 ubsan_type_descriptor (expr_type),
1607 ubsan_type_descriptor (type), NULL_TREE,
1608 NULL_TREE);
1609 enum built_in_function bcode
1610 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1611 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1612 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1613 fn = builtin_decl_explicit (bcode);
1614 fn = build_call_expr_loc (loc, fn, 2,
1615 build_fold_addr_expr_loc (loc, data),
1616 ubsan_encode_value (expr, false));
1619 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1622 /* Instrument values passed to function arguments with nonnull attribute. */
1624 static void
1625 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1627 gimple *stmt = gsi_stmt (*gsi);
1628 location_t loc[2];
1629 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1630 while for nonnull sanitization it is clear. */
1631 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1632 flag_delete_null_pointer_checks = 1;
1633 loc[0] = gimple_location (stmt);
1634 loc[1] = UNKNOWN_LOCATION;
1635 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1637 tree arg = gimple_call_arg (stmt, i);
1638 if (POINTER_TYPE_P (TREE_TYPE (arg))
1639 && infer_nonnull_range_by_attribute (stmt, arg))
1641 gimple *g;
1642 if (!is_gimple_val (arg))
1644 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1645 gimple_set_location (g, loc[0]);
1646 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1647 arg = gimple_assign_lhs (g);
1650 basic_block then_bb, fallthru_bb;
1651 *gsi = create_cond_insert_point (gsi, true, false, true,
1652 &then_bb, &fallthru_bb);
1653 g = gimple_build_cond (EQ_EXPR, arg,
1654 build_zero_cst (TREE_TYPE (arg)),
1655 NULL_TREE, NULL_TREE);
1656 gimple_set_location (g, loc[0]);
1657 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1659 *gsi = gsi_after_labels (then_bb);
1660 if (flag_sanitize_undefined_trap_on_error)
1661 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1662 else
1664 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1665 2, loc, NULL_TREE,
1666 build_int_cst (integer_type_node,
1667 i + 1),
1668 NULL_TREE);
1669 data = build_fold_addr_expr_loc (loc[0], data);
1670 enum built_in_function bcode
1671 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1672 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1673 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1674 tree fn = builtin_decl_explicit (bcode);
1676 g = gimple_build_call (fn, 1, data);
1678 gimple_set_location (g, loc[0]);
1679 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1680 ubsan_create_edge (g);
1682 *gsi = gsi_for_stmt (stmt);
1684 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1687 /* Instrument returns in functions with returns_nonnull attribute. */
1689 static void
1690 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1692 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1693 location_t loc[2];
1694 tree arg = gimple_return_retval (stmt);
1695 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1696 while for nonnull return sanitization it is clear. */
1697 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1698 flag_delete_null_pointer_checks = 1;
1699 loc[0] = gimple_location (stmt);
1700 loc[1] = UNKNOWN_LOCATION;
1701 if (arg
1702 && POINTER_TYPE_P (TREE_TYPE (arg))
1703 && is_gimple_val (arg)
1704 && infer_nonnull_range_by_attribute (stmt, arg))
1706 basic_block then_bb, fallthru_bb;
1707 *gsi = create_cond_insert_point (gsi, true, false, true,
1708 &then_bb, &fallthru_bb);
1709 gimple *g = gimple_build_cond (EQ_EXPR, arg,
1710 build_zero_cst (TREE_TYPE (arg)),
1711 NULL_TREE, NULL_TREE);
1712 gimple_set_location (g, loc[0]);
1713 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1715 *gsi = gsi_after_labels (then_bb);
1716 if (flag_sanitize_undefined_trap_on_error)
1717 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1718 else
1720 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1721 2, loc, NULL_TREE, NULL_TREE);
1722 data = build_fold_addr_expr_loc (loc[0], data);
1723 enum built_in_function bcode
1724 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1725 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1726 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1727 tree fn = builtin_decl_explicit (bcode);
1729 g = gimple_build_call (fn, 1, data);
1731 gimple_set_location (g, loc[0]);
1732 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1733 ubsan_create_edge (g);
1734 *gsi = gsi_for_stmt (stmt);
1736 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1739 /* Instrument memory references. Here we check whether the pointer
1740 points to an out-of-bounds location. */
1742 static void
1743 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1745 gimple *stmt = gsi_stmt (*gsi);
1746 location_t loc = gimple_location (stmt);
1747 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1748 tree type;
1749 tree index = NULL_TREE;
1750 HOST_WIDE_INT size_in_bytes;
1752 type = TREE_TYPE (t);
1753 if (VOID_TYPE_P (type))
1754 return;
1756 switch (TREE_CODE (t))
1758 case COMPONENT_REF:
1759 if (TREE_CODE (t) == COMPONENT_REF
1760 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1762 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1763 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1764 repr, NULL_TREE);
1766 break;
1767 case ARRAY_REF:
1768 index = TREE_OPERAND (t, 1);
1769 break;
1770 case INDIRECT_REF:
1771 case MEM_REF:
1772 case VAR_DECL:
1773 case PARM_DECL:
1774 case RESULT_DECL:
1775 break;
1776 default:
1777 return;
1780 size_in_bytes = int_size_in_bytes (type);
1781 if (size_in_bytes <= 0)
1782 return;
1784 HOST_WIDE_INT bitsize, bitpos;
1785 tree offset;
1786 machine_mode mode;
1787 int volatilep = 0, reversep, unsignedp = 0;
1788 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1789 &unsignedp, &reversep, &volatilep);
1791 if (bitpos % BITS_PER_UNIT != 0
1792 || bitsize != size_in_bytes * BITS_PER_UNIT)
1793 return;
1795 bool decl_p = DECL_P (inner);
1796 tree base;
1797 if (decl_p)
1798 base = inner;
1799 else if (TREE_CODE (inner) == MEM_REF)
1800 base = TREE_OPERAND (inner, 0);
1801 else
1802 return;
1803 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1805 while (TREE_CODE (base) == SSA_NAME)
1807 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
1808 if (gimple_assign_ssa_name_copy_p (def_stmt)
1809 || (gimple_assign_cast_p (def_stmt)
1810 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1811 || (is_gimple_assign (def_stmt)
1812 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1814 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1815 if (TREE_CODE (rhs1) == SSA_NAME
1816 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1817 break;
1818 else
1819 base = rhs1;
1821 else
1822 break;
1825 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1826 return;
1828 tree sizet;
1829 tree base_addr = base;
1830 gimple *bos_stmt = NULL;
1831 if (decl_p)
1832 base_addr = build1 (ADDR_EXPR,
1833 build_pointer_type (TREE_TYPE (base)), base);
1834 unsigned HOST_WIDE_INT size;
1835 if (compute_builtin_object_size (base_addr, 0, &size))
1836 sizet = build_int_cst (sizetype, size);
1837 else if (optimize)
1839 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1840 loc = input_location;
1841 /* Generate __builtin_object_size call. */
1842 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1843 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1844 integer_zero_node);
1845 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1846 GSI_SAME_STMT);
1847 /* If the call above didn't end up being an integer constant, go one
1848 statement back and get the __builtin_object_size stmt. Save it,
1849 we might need it later. */
1850 if (SSA_VAR_P (sizet))
1852 gsi_prev (gsi);
1853 bos_stmt = gsi_stmt (*gsi);
1855 /* Move on to where we were. */
1856 gsi_next (gsi);
1859 else
1860 return;
1862 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1863 call. */
1864 /* ptr + sizeof (*ptr) - base */
1865 t = fold_build2 (MINUS_EXPR, sizetype,
1866 fold_convert (pointer_sized_int_node, ptr),
1867 fold_convert (pointer_sized_int_node, base_addr));
1868 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1870 /* Perhaps we can omit the check. */
1871 if (TREE_CODE (t) == INTEGER_CST
1872 && TREE_CODE (sizet) == INTEGER_CST
1873 && tree_int_cst_le (t, sizet))
1874 return;
1876 if (index != NULL_TREE
1877 && TREE_CODE (index) == SSA_NAME
1878 && TREE_CODE (sizet) == INTEGER_CST)
1880 gimple *def = SSA_NAME_DEF_STMT (index);
1881 if (is_gimple_assign (def)
1882 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1883 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1885 tree cst = gimple_assign_rhs2 (def);
1886 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1887 TYPE_SIZE_UNIT (type));
1888 if (tree_int_cst_sgn (cst) >= 0
1889 && tree_int_cst_lt (cst, sz))
1890 return;
1894 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1895 ubsan_create_edge (bos_stmt);
1897 /* We have to emit the check. */
1898 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1899 GSI_SAME_STMT);
1900 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1901 GSI_SAME_STMT);
1902 tree ckind = build_int_cst (unsigned_char_type_node,
1903 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1904 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1905 ptr, t, sizet, ckind);
1906 gimple_set_location (g, loc);
1907 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1910 /* True if we want to play UBSan games in the current function. */
1912 bool
1913 do_ubsan_in_current_function ()
1915 return (current_function_decl != NULL_TREE
1916 && !lookup_attribute ("no_sanitize_undefined",
1917 DECL_ATTRIBUTES (current_function_decl)));
1920 namespace {
1922 const pass_data pass_data_ubsan =
1924 GIMPLE_PASS, /* type */
1925 "ubsan", /* name */
1926 OPTGROUP_NONE, /* optinfo_flags */
1927 TV_TREE_UBSAN, /* tv_id */
1928 ( PROP_cfg | PROP_ssa ), /* properties_required */
1929 0, /* properties_provided */
1930 0, /* properties_destroyed */
1931 0, /* todo_flags_start */
1932 TODO_update_ssa, /* todo_flags_finish */
1935 class pass_ubsan : public gimple_opt_pass
1937 public:
1938 pass_ubsan (gcc::context *ctxt)
1939 : gimple_opt_pass (pass_data_ubsan, ctxt)
1942 /* opt_pass methods: */
1943 virtual bool gate (function *)
1945 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1946 | SANITIZE_BOOL | SANITIZE_ENUM
1947 | SANITIZE_ALIGNMENT
1948 | SANITIZE_NONNULL_ATTRIBUTE
1949 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1950 | SANITIZE_OBJECT_SIZE)
1951 && do_ubsan_in_current_function ();
1954 virtual unsigned int execute (function *);
1956 }; // class pass_ubsan
1958 unsigned int
1959 pass_ubsan::execute (function *fun)
1961 basic_block bb;
1962 gimple_stmt_iterator gsi;
1963 unsigned int ret = 0;
1965 initialize_sanitizer_builtins ();
1967 FOR_EACH_BB_FN (bb, fun)
1969 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1971 gimple *stmt = gsi_stmt (gsi);
1972 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1974 gsi_next (&gsi);
1975 continue;
1978 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1979 && is_gimple_assign (stmt))
1980 instrument_si_overflow (gsi);
1982 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1984 if (gimple_store_p (stmt))
1985 instrument_null (gsi, true);
1986 if (gimple_assign_load_p (stmt))
1987 instrument_null (gsi, false);
1990 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1991 && gimple_assign_load_p (stmt))
1993 instrument_bool_enum_load (&gsi);
1994 bb = gimple_bb (stmt);
1997 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1998 && is_gimple_call (stmt)
1999 && !gimple_call_internal_p (stmt))
2001 instrument_nonnull_arg (&gsi);
2002 bb = gimple_bb (stmt);
2005 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2006 && gimple_code (stmt) == GIMPLE_RETURN)
2008 instrument_nonnull_return (&gsi);
2009 bb = gimple_bb (stmt);
2012 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2014 if (gimple_store_p (stmt))
2015 instrument_object_size (&gsi, true);
2016 if (gimple_assign_load_p (stmt))
2017 instrument_object_size (&gsi, false);
2020 gsi_next (&gsi);
2022 if (gimple_purge_dead_eh_edges (bb))
2023 ret = TODO_cleanup_cfg;
2025 return ret;
2028 } // anon namespace
2030 gimple_opt_pass *
2031 make_pass_ubsan (gcc::context *ctxt)
2033 return new pass_ubsan (ctxt);
2036 #include "gt-ubsan.h"