Daily bump.
[official-gcc.git] / gcc / ubsan.c
blob56637d8f0a9e009a0046344d5820fed508b0320b
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 /* Firstly, create a pointer to type descriptor type. */
515 tree td_type = ubsan_get_type_descriptor_type ();
516 td_type = build_pointer_type (td_type);
518 /* Create the structure type. */
519 ret = make_node (RECORD_TYPE);
520 for (j = 0; j < loccnt; j++)
522 gcc_checking_assert (i < 2);
523 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
524 ubsan_get_source_location_type ());
525 DECL_CONTEXT (fields[i]) = ret;
526 if (i)
527 DECL_CHAIN (fields[i - 1]) = fields[i];
528 i++;
531 va_start (args, ploc);
532 for (t = va_arg (args, tree); t != NULL_TREE;
533 i++, t = va_arg (args, tree))
535 gcc_checking_assert (i < 4);
536 /* Save the tree arguments for later use. */
537 vec_safe_push (saved_args, t);
538 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
539 td_type);
540 DECL_CONTEXT (fields[i]) = ret;
541 if (i)
542 DECL_CHAIN (fields[i - 1]) = fields[i];
545 for (t = va_arg (args, tree); t != NULL_TREE;
546 i++, t = va_arg (args, tree))
548 gcc_checking_assert (i < 6);
549 /* Save the tree arguments for later use. */
550 vec_safe_push (saved_args, t);
551 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
552 TREE_TYPE (t));
553 DECL_CONTEXT (fields[i]) = ret;
554 if (i)
555 DECL_CHAIN (fields[i - 1]) = fields[i];
557 va_end (args);
559 tree type_decl = build_decl (input_location, TYPE_DECL,
560 get_identifier (name), ret);
561 DECL_IGNORED_P (type_decl) = 1;
562 DECL_ARTIFICIAL (type_decl) = 1;
563 TYPE_FIELDS (ret) = fields[0];
564 TYPE_NAME (ret) = type_decl;
565 TYPE_STUB_DECL (ret) = type_decl;
566 layout_type (ret);
568 /* Now, fill in the type. */
569 char tmp_name[32];
570 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
571 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
572 ret);
573 TREE_STATIC (var) = 1;
574 TREE_PUBLIC (var) = 0;
575 DECL_ARTIFICIAL (var) = 1;
576 DECL_IGNORED_P (var) = 1;
577 DECL_EXTERNAL (var) = 0;
579 vec<constructor_elt, va_gc> *v;
580 vec_alloc (v, i);
581 tree ctor = build_constructor (ret, v);
583 /* If desirable, set the __ubsan_source_location element. */
584 for (j = 0; j < loccnt; j++)
586 location_t loc = LOCATION_LOCUS (ploc[j]);
587 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
590 size_t nelts = vec_safe_length (saved_args);
591 for (i = 0; i < nelts; i++)
593 t = (*saved_args)[i];
594 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
597 TREE_CONSTANT (ctor) = 1;
598 TREE_STATIC (ctor) = 1;
599 DECL_INITIAL (var) = ctor;
600 varpool_node::finalize_decl (var);
602 return var;
605 /* Instrument the __builtin_unreachable call. We just call the libubsan
606 routine instead. */
608 bool
609 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
611 gimple *g;
612 location_t loc = gimple_location (gsi_stmt (*gsi));
614 if (flag_sanitize_undefined_trap_on_error)
615 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
616 else
618 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
619 NULL_TREE, NULL_TREE);
620 data = build_fold_addr_expr_loc (loc, data);
621 tree fn
622 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
623 g = gimple_build_call (fn, 1, data);
625 gimple_set_location (g, loc);
626 gsi_replace (gsi, g, false);
627 return false;
630 /* Return true if T is a call to a libubsan routine. */
632 bool
633 is_ubsan_builtin_p (tree t)
635 return TREE_CODE (t) == FUNCTION_DECL
636 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
637 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
638 "__builtin___ubsan_", 18) == 0;
641 /* Create a callgraph edge for statement STMT. */
643 static void
644 ubsan_create_edge (gimple *stmt)
646 gcall *call_stmt = dyn_cast <gcall *> (stmt);
647 basic_block bb = gimple_bb (stmt);
648 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
649 cgraph_node *node = cgraph_node::get (current_function_decl);
650 tree decl = gimple_call_fndecl (call_stmt);
651 if (decl)
652 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
653 freq);
656 /* Expand the UBSAN_BOUNDS special builtin function. */
658 bool
659 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
661 gimple *stmt = gsi_stmt (*gsi);
662 location_t loc = gimple_location (stmt);
663 gcc_assert (gimple_call_num_args (stmt) == 3);
665 /* Pick up the arguments of the UBSAN_BOUNDS call. */
666 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
667 tree index = gimple_call_arg (stmt, 1);
668 tree orig_index_type = TREE_TYPE (index);
669 tree bound = gimple_call_arg (stmt, 2);
671 gimple_stmt_iterator gsi_orig = *gsi;
673 /* Create condition "if (index > bound)". */
674 basic_block then_bb, fallthru_bb;
675 gimple_stmt_iterator cond_insert_point
676 = create_cond_insert_point (gsi, false, false, true,
677 &then_bb, &fallthru_bb);
678 index = fold_convert (TREE_TYPE (bound), index);
679 index = force_gimple_operand_gsi (&cond_insert_point, index,
680 true, NULL_TREE,
681 false, GSI_NEW_STMT);
682 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
683 gimple_set_location (g, loc);
684 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
686 /* Generate __ubsan_handle_out_of_bounds call. */
687 *gsi = gsi_after_labels (then_bb);
688 if (flag_sanitize_undefined_trap_on_error)
689 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
690 else
692 tree data
693 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
694 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
695 ubsan_type_descriptor (orig_index_type),
696 NULL_TREE, NULL_TREE);
697 data = build_fold_addr_expr_loc (loc, data);
698 enum built_in_function bcode
699 = (flag_sanitize_recover & SANITIZE_BOUNDS)
700 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
701 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
702 tree fn = builtin_decl_explicit (bcode);
703 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
704 true, NULL_TREE, true,
705 GSI_SAME_STMT);
706 g = gimple_build_call (fn, 2, data, val);
708 gimple_set_location (g, loc);
709 gsi_insert_before (gsi, g, GSI_SAME_STMT);
711 /* Get rid of the UBSAN_BOUNDS call from the IR. */
712 unlink_stmt_vdef (stmt);
713 gsi_remove (&gsi_orig, true);
715 /* Point GSI to next logical statement. */
716 *gsi = gsi_start_bb (fallthru_bb);
717 return true;
720 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
721 argument which is a constant, because the middle-end treats pointer
722 conversions as useless and therefore the type of the first argument
723 could be changed to any other pointer type. */
725 bool
726 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
728 gimple_stmt_iterator gsi = *gsip;
729 gimple *stmt = gsi_stmt (gsi);
730 location_t loc = gimple_location (stmt);
731 gcc_assert (gimple_call_num_args (stmt) == 3);
732 tree ptr = gimple_call_arg (stmt, 0);
733 tree ckind = gimple_call_arg (stmt, 1);
734 tree align = gimple_call_arg (stmt, 2);
735 tree check_align = NULL_TREE;
736 bool check_null;
738 basic_block cur_bb = gsi_bb (gsi);
740 gimple *g;
741 if (!integer_zerop (align))
743 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
744 if (compare_tree_int (align, ptralign) == 1)
746 check_align = make_ssa_name (pointer_sized_int_node);
747 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
748 gimple_set_location (g, loc);
749 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
752 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
754 if (check_align == NULL_TREE && !check_null)
756 gsi_remove (gsip, true);
757 /* Unlink the UBSAN_NULLs vops before replacing it. */
758 unlink_stmt_vdef (stmt);
759 return true;
762 /* Split the original block holding the pointer dereference. */
763 edge e = split_block (cur_bb, stmt);
765 /* Get a hold on the 'condition block', the 'then block' and the
766 'else block'. */
767 basic_block cond_bb = e->src;
768 basic_block fallthru_bb = e->dest;
769 basic_block then_bb = create_empty_bb (cond_bb);
770 add_bb_to_loop (then_bb, cond_bb->loop_father);
771 loops_state_set (LOOPS_NEED_FIXUP);
773 /* Make an edge coming from the 'cond block' into the 'then block';
774 this edge is unlikely taken, so set up the probability accordingly. */
775 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
776 e->probability = PROB_VERY_UNLIKELY;
778 /* Connect 'then block' with the 'else block'. This is needed
779 as the ubsan routines we call in the 'then block' are not noreturn.
780 The 'then block' only has one outcoming edge. */
781 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
783 /* Set up the fallthrough basic block. */
784 e = find_edge (cond_bb, fallthru_bb);
785 e->flags = EDGE_FALSE_VALUE;
786 e->count = cond_bb->count;
787 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
789 /* Update dominance info for the newly created then_bb; note that
790 fallthru_bb's dominance info has already been updated by
791 split_block. */
792 if (dom_info_available_p (CDI_DOMINATORS))
793 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
795 /* Put the ubsan builtin call into the newly created BB. */
796 if (flag_sanitize_undefined_trap_on_error)
797 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
798 else
800 enum built_in_function bcode
801 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
802 | (check_null ? SANITIZE_NULL : 0)))
803 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
804 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
805 tree fn = builtin_decl_implicit (bcode);
806 tree data
807 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
808 ubsan_type_descriptor (TREE_TYPE (ckind),
809 UBSAN_PRINT_POINTER),
810 NULL_TREE,
811 align,
812 fold_convert (unsigned_char_type_node, ckind),
813 NULL_TREE);
814 data = build_fold_addr_expr_loc (loc, data);
815 g = gimple_build_call (fn, 2, data,
816 check_align ? check_align
817 : build_zero_cst (pointer_sized_int_node));
819 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
820 gimple_set_location (g, loc);
821 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
823 /* Unlink the UBSAN_NULLs vops before replacing it. */
824 unlink_stmt_vdef (stmt);
826 if (check_null)
828 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
829 NULL_TREE, NULL_TREE);
830 gimple_set_location (g, loc);
832 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
833 gsi_replace (&gsi, g, false);
834 stmt = g;
837 if (check_align)
839 if (check_null)
841 /* Split the block with the condition again. */
842 e = split_block (cond_bb, stmt);
843 basic_block cond1_bb = e->src;
844 basic_block cond2_bb = e->dest;
846 /* Make an edge coming from the 'cond1 block' into the 'then block';
847 this edge is unlikely taken, so set up the probability
848 accordingly. */
849 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
850 e->probability = PROB_VERY_UNLIKELY;
852 /* Set up the fallthrough basic block. */
853 e = find_edge (cond1_bb, cond2_bb);
854 e->flags = EDGE_FALSE_VALUE;
855 e->count = cond1_bb->count;
856 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
858 /* Update dominance info. */
859 if (dom_info_available_p (CDI_DOMINATORS))
861 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
862 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
865 gsi2 = gsi_start_bb (cond2_bb);
868 tree mask = build_int_cst (pointer_sized_int_node,
869 tree_to_uhwi (align) - 1);
870 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
871 BIT_AND_EXPR, check_align, mask);
872 gimple_set_location (g, loc);
873 if (check_null)
874 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
875 else
876 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
878 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
879 build_int_cst (pointer_sized_int_node, 0),
880 NULL_TREE, NULL_TREE);
881 gimple_set_location (g, loc);
882 if (check_null)
883 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
884 else
885 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
886 gsi_replace (&gsi, g, false);
888 return false;
891 #define OBJSZ_MAX_OFFSET (1024 * 16)
893 /* Expand UBSAN_OBJECT_SIZE internal call. */
895 bool
896 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
898 gimple *stmt = gsi_stmt (*gsi);
899 location_t loc = gimple_location (stmt);
900 gcc_assert (gimple_call_num_args (stmt) == 4);
902 tree ptr = gimple_call_arg (stmt, 0);
903 tree offset = gimple_call_arg (stmt, 1);
904 tree size = gimple_call_arg (stmt, 2);
905 tree ckind = gimple_call_arg (stmt, 3);
906 gimple_stmt_iterator gsi_orig = *gsi;
907 gimple *g;
909 /* See if we can discard the check. */
910 if (TREE_CODE (size) != INTEGER_CST
911 || integer_all_onesp (size))
912 /* Yes, __builtin_object_size couldn't determine the
913 object size. */;
914 else if (TREE_CODE (offset) == INTEGER_CST
915 && wi::ges_p (wi::to_widest (offset), -OBJSZ_MAX_OFFSET)
916 && wi::les_p (wi::to_widest (offset), -1))
917 /* The offset is in range [-16K, -1]. */;
918 else
920 /* if (offset > objsize) */
921 basic_block then_bb, fallthru_bb;
922 gimple_stmt_iterator cond_insert_point
923 = create_cond_insert_point (gsi, false, false, true,
924 &then_bb, &fallthru_bb);
925 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
926 gimple_set_location (g, loc);
927 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
929 /* If the offset is small enough, we don't need the second
930 run-time check. */
931 if (TREE_CODE (offset) == INTEGER_CST
932 && wi::ges_p (wi::to_widest (offset), 0)
933 && wi::les_p (wi::to_widest (offset), OBJSZ_MAX_OFFSET))
934 *gsi = gsi_after_labels (then_bb);
935 else
937 /* Don't issue run-time error if (ptr > ptr + offset). That
938 may happen when computing a POINTER_PLUS_EXPR. */
939 basic_block then2_bb, fallthru2_bb;
941 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
942 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
943 true, &then2_bb,
944 &fallthru2_bb);
945 /* Convert the pointer to an integer type. */
946 tree p = make_ssa_name (pointer_sized_int_node);
947 g = gimple_build_assign (p, NOP_EXPR, ptr);
948 gimple_set_location (g, loc);
949 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
950 p = gimple_assign_lhs (g);
951 /* Compute ptr + offset. */
952 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
953 PLUS_EXPR, p, offset);
954 gimple_set_location (g, loc);
955 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
956 /* Now build the conditional and put it into the IR. */
957 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
958 NULL_TREE, NULL_TREE);
959 gimple_set_location (g, loc);
960 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
961 *gsi = gsi_after_labels (then2_bb);
964 /* Generate __ubsan_handle_type_mismatch call. */
965 if (flag_sanitize_undefined_trap_on_error)
966 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
967 else
969 tree data
970 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
971 ubsan_type_descriptor (TREE_TYPE (ptr),
972 UBSAN_PRINT_POINTER),
973 NULL_TREE,
974 build_zero_cst (pointer_sized_int_node),
975 ckind,
976 NULL_TREE);
977 data = build_fold_addr_expr_loc (loc, data);
978 enum built_in_function bcode
979 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
980 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
981 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
982 tree p = make_ssa_name (pointer_sized_int_node);
983 g = gimple_build_assign (p, NOP_EXPR, ptr);
984 gimple_set_location (g, loc);
985 gsi_insert_before (gsi, g, GSI_SAME_STMT);
986 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
988 gimple_set_location (g, loc);
989 gsi_insert_before (gsi, g, GSI_SAME_STMT);
991 /* Point GSI to next logical statement. */
992 *gsi = gsi_start_bb (fallthru_bb);
994 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
995 unlink_stmt_vdef (stmt);
996 gsi_remove (&gsi_orig, true);
997 return true;
1000 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1001 unlink_stmt_vdef (stmt);
1002 gsi_remove (gsi, true);
1003 return true;
1006 /* Cached __ubsan_vptr_type_cache decl. */
1007 static GTY(()) tree ubsan_vptr_type_cache_decl;
1009 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1010 argument which is a constant, because the middle-end treats pointer
1011 conversions as useless and therefore the type of the first argument
1012 could be changed to any other pointer type. */
1014 bool
1015 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1017 gimple_stmt_iterator gsi = *gsip;
1018 gimple *stmt = gsi_stmt (gsi);
1019 location_t loc = gimple_location (stmt);
1020 gcc_assert (gimple_call_num_args (stmt) == 5);
1021 tree op = gimple_call_arg (stmt, 0);
1022 tree vptr = gimple_call_arg (stmt, 1);
1023 tree str_hash = gimple_call_arg (stmt, 2);
1024 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1025 tree ckind_tree = gimple_call_arg (stmt, 4);
1026 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1027 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1028 gimple *g;
1029 basic_block fallthru_bb = NULL;
1031 if (ckind == UBSAN_DOWNCAST_POINTER)
1033 /* Guard everything with if (op != NULL) { ... }. */
1034 basic_block then_bb;
1035 gimple_stmt_iterator cond_insert_point
1036 = create_cond_insert_point (gsip, false, false, true,
1037 &then_bb, &fallthru_bb);
1038 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1039 NULL_TREE, NULL_TREE);
1040 gimple_set_location (g, loc);
1041 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1042 *gsip = gsi_after_labels (then_bb);
1043 gsi_remove (&gsi, false);
1044 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1045 gsi = *gsip;
1048 tree htype = TREE_TYPE (str_hash);
1049 tree cst = wide_int_to_tree (htype,
1050 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1051 | 0xeb382d69, 64));
1052 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1053 vptr, str_hash);
1054 gimple_set_location (g, loc);
1055 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1056 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1057 gimple_assign_lhs (g), cst);
1058 gimple_set_location (g, loc);
1059 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1060 tree t1 = gimple_assign_lhs (g);
1061 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1062 t1, build_int_cst (integer_type_node, 47));
1063 gimple_set_location (g, loc);
1064 tree t2 = gimple_assign_lhs (g);
1065 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1066 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1067 vptr, t1);
1068 gimple_set_location (g, loc);
1069 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1070 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1071 t2, gimple_assign_lhs (g));
1072 gimple_set_location (g, loc);
1073 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1074 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1075 gimple_assign_lhs (g), cst);
1076 gimple_set_location (g, loc);
1077 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1078 tree t3 = gimple_assign_lhs (g);
1079 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1080 t3, build_int_cst (integer_type_node, 47));
1081 gimple_set_location (g, loc);
1082 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1083 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1084 t3, gimple_assign_lhs (g));
1085 gimple_set_location (g, loc);
1086 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1087 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1088 gimple_assign_lhs (g), cst);
1089 gimple_set_location (g, loc);
1090 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1091 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1093 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1094 NOP_EXPR, gimple_assign_lhs (g));
1095 gimple_set_location (g, loc);
1096 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1098 tree hash = gimple_assign_lhs (g);
1100 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1102 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1103 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1104 get_identifier ("__ubsan_vptr_type_cache"),
1105 atype);
1106 DECL_ARTIFICIAL (array) = 1;
1107 DECL_IGNORED_P (array) = 1;
1108 TREE_PUBLIC (array) = 1;
1109 TREE_STATIC (array) = 1;
1110 DECL_EXTERNAL (array) = 1;
1111 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1112 DECL_VISIBILITY_SPECIFIED (array) = 1;
1113 varpool_node::finalize_decl (array);
1114 ubsan_vptr_type_cache_decl = array;
1117 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1118 BIT_AND_EXPR, hash,
1119 build_int_cst (pointer_sized_int_node, 127));
1120 gimple_set_location (g, loc);
1121 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1123 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1124 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1125 NULL_TREE, NULL_TREE);
1126 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1127 ARRAY_REF, c);
1128 gimple_set_location (g, loc);
1129 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1131 basic_block then_bb, fallthru2_bb;
1132 gimple_stmt_iterator cond_insert_point
1133 = create_cond_insert_point (gsip, false, false, true,
1134 &then_bb, &fallthru2_bb);
1135 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1136 NULL_TREE, NULL_TREE);
1137 gimple_set_location (g, loc);
1138 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1139 *gsip = gsi_after_labels (then_bb);
1140 if (fallthru_bb == NULL)
1141 fallthru_bb = fallthru2_bb;
1143 tree data
1144 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1145 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1146 build_int_cst (unsigned_char_type_node, ckind),
1147 NULL_TREE);
1148 data = build_fold_addr_expr_loc (loc, data);
1149 enum built_in_function bcode
1150 = (flag_sanitize_recover & SANITIZE_VPTR)
1151 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1152 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1154 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1155 gimple_set_location (g, loc);
1156 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1158 /* Point GSI to next logical statement. */
1159 *gsip = gsi_start_bb (fallthru_bb);
1161 /* Get rid of the UBSAN_VPTR call from the IR. */
1162 unlink_stmt_vdef (stmt);
1163 gsi_remove (&gsi, true);
1164 return true;
1167 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1168 whether the pointer is on the left hand side of the assignment. */
1170 static void
1171 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1172 bool is_lhs)
1174 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1175 unsigned int align = 0;
1176 if (flag_sanitize & SANITIZE_ALIGNMENT)
1178 align = min_align_of_type (TREE_TYPE (base));
1179 if (align <= 1)
1180 align = 0;
1182 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1183 return;
1184 tree t = TREE_OPERAND (base, 0);
1185 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1186 return;
1187 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1188 ikind = UBSAN_MEMBER_ACCESS;
1189 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1190 tree alignt = build_int_cst (pointer_sized_int_node, align);
1191 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1192 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1193 gsi_insert_before (iter, g, GSI_SAME_STMT);
1196 /* Perform the pointer instrumentation. */
1198 static void
1199 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1201 gimple *stmt = gsi_stmt (gsi);
1202 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1203 tree base = get_base_address (t);
1204 const enum tree_code code = TREE_CODE (base);
1205 if (code == MEM_REF
1206 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1207 instrument_mem_ref (t, base, &gsi, is_lhs);
1210 /* Build an ubsan builtin call for the signed-integer-overflow
1211 sanitization. CODE says what kind of builtin are we building,
1212 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1213 are operands of the binary operation. */
1215 tree
1216 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1217 tree op0, tree op1)
1219 if (flag_sanitize_undefined_trap_on_error)
1220 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1222 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1223 ubsan_type_descriptor (lhstype), NULL_TREE,
1224 NULL_TREE);
1225 enum built_in_function fn_code;
1227 switch (code)
1229 case PLUS_EXPR:
1230 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1231 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1232 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1233 break;
1234 case MINUS_EXPR:
1235 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1236 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1237 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1238 break;
1239 case MULT_EXPR:
1240 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1241 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1242 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1243 break;
1244 case NEGATE_EXPR:
1245 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1246 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1247 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1248 break;
1249 default:
1250 gcc_unreachable ();
1252 tree fn = builtin_decl_explicit (fn_code);
1253 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1254 build_fold_addr_expr_loc (loc, data),
1255 ubsan_encode_value (op0, true),
1256 op1 ? ubsan_encode_value (op1, true)
1257 : NULL_TREE);
1260 /* Perform the signed integer instrumentation. GSI is the iterator
1261 pointing at statement we are trying to instrument. */
1263 static void
1264 instrument_si_overflow (gimple_stmt_iterator gsi)
1266 gimple *stmt = gsi_stmt (gsi);
1267 tree_code code = gimple_assign_rhs_code (stmt);
1268 tree lhs = gimple_assign_lhs (stmt);
1269 tree lhstype = TREE_TYPE (lhs);
1270 tree a, b;
1271 gimple *g;
1273 /* If this is not a signed operation, don't instrument anything here.
1274 Also punt on bit-fields. */
1275 if (!INTEGRAL_TYPE_P (lhstype)
1276 || TYPE_OVERFLOW_WRAPS (lhstype)
1277 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1278 return;
1280 switch (code)
1282 case MINUS_EXPR:
1283 case PLUS_EXPR:
1284 case MULT_EXPR:
1285 /* Transform
1286 i = u {+,-,*} 5;
1287 into
1288 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1289 a = gimple_assign_rhs1 (stmt);
1290 b = gimple_assign_rhs2 (stmt);
1291 g = gimple_build_call_internal (code == PLUS_EXPR
1292 ? IFN_UBSAN_CHECK_ADD
1293 : code == MINUS_EXPR
1294 ? IFN_UBSAN_CHECK_SUB
1295 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1296 gimple_call_set_lhs (g, lhs);
1297 gsi_replace (&gsi, g, true);
1298 break;
1299 case NEGATE_EXPR:
1300 /* Represent i = -u;
1302 i = UBSAN_CHECK_SUB (0, u); */
1303 a = build_int_cst (lhstype, 0);
1304 b = gimple_assign_rhs1 (stmt);
1305 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1306 gimple_call_set_lhs (g, lhs);
1307 gsi_replace (&gsi, g, true);
1308 break;
1309 case ABS_EXPR:
1310 /* Transform i = ABS_EXPR<u>;
1311 into
1312 _N = UBSAN_CHECK_SUB (0, u);
1313 i = ABS_EXPR<_N>; */
1314 a = build_int_cst (lhstype, 0);
1315 b = gimple_assign_rhs1 (stmt);
1316 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1317 a = make_ssa_name (lhstype);
1318 gimple_call_set_lhs (g, a);
1319 gimple_set_location (g, gimple_location (stmt));
1320 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1321 gimple_assign_set_rhs1 (stmt, a);
1322 update_stmt (stmt);
1323 break;
1324 default:
1325 break;
1329 /* Instrument loads from (non-bitfield) bool and C++ enum values
1330 to check if the memory value is outside of the range of the valid
1331 type values. */
1333 static void
1334 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1336 gimple *stmt = gsi_stmt (*gsi);
1337 tree rhs = gimple_assign_rhs1 (stmt);
1338 tree type = TREE_TYPE (rhs);
1339 tree minv = NULL_TREE, maxv = NULL_TREE;
1341 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1343 minv = boolean_false_node;
1344 maxv = boolean_true_node;
1346 else if (TREE_CODE (type) == ENUMERAL_TYPE
1347 && (flag_sanitize & SANITIZE_ENUM)
1348 && TREE_TYPE (type) != NULL_TREE
1349 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1350 && (TYPE_PRECISION (TREE_TYPE (type))
1351 < GET_MODE_PRECISION (TYPE_MODE (type))))
1353 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1354 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1356 else
1357 return;
1359 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1360 HOST_WIDE_INT bitsize, bitpos;
1361 tree offset;
1362 machine_mode mode;
1363 int volatilep = 0, reversep, unsignedp = 0;
1364 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1365 &unsignedp, &reversep, &volatilep, false);
1366 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1368 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1369 || (bitpos % modebitsize) != 0
1370 || bitsize != modebitsize
1371 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1372 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1373 return;
1375 bool ends_bb = stmt_ends_bb_p (stmt);
1376 location_t loc = gimple_location (stmt);
1377 tree lhs = gimple_assign_lhs (stmt);
1378 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1379 tree atype = reference_alias_ptr_type (rhs);
1380 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1381 build_fold_addr_expr (rhs));
1382 gimple_set_location (g, loc);
1383 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1384 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1385 build_int_cst (atype, 0));
1386 tree urhs = make_ssa_name (utype);
1387 if (ends_bb)
1389 gimple_assign_set_lhs (stmt, urhs);
1390 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1391 gimple_set_location (g, loc);
1392 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1393 gsi_insert_on_edge_immediate (e, g);
1394 gimple_assign_set_rhs_from_tree (gsi, mem);
1395 update_stmt (stmt);
1396 *gsi = gsi_for_stmt (g);
1397 g = stmt;
1399 else
1401 g = gimple_build_assign (urhs, mem);
1402 gimple_set_location (g, loc);
1403 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1405 minv = fold_convert (utype, minv);
1406 maxv = fold_convert (utype, maxv);
1407 if (!integer_zerop (minv))
1409 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1410 gimple_set_location (g, loc);
1411 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1414 gimple_stmt_iterator gsi2 = *gsi;
1415 basic_block then_bb, fallthru_bb;
1416 *gsi = create_cond_insert_point (gsi, true, false, true,
1417 &then_bb, &fallthru_bb);
1418 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1419 int_const_binop (MINUS_EXPR, maxv, minv),
1420 NULL_TREE, NULL_TREE);
1421 gimple_set_location (g, loc);
1422 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1424 if (!ends_bb)
1426 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1427 update_stmt (stmt);
1430 gsi2 = gsi_after_labels (then_bb);
1431 if (flag_sanitize_undefined_trap_on_error)
1432 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1433 else
1435 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1436 ubsan_type_descriptor (type), NULL_TREE,
1437 NULL_TREE);
1438 data = build_fold_addr_expr_loc (loc, data);
1439 enum built_in_function bcode
1440 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1441 ? SANITIZE_BOOL : SANITIZE_ENUM))
1442 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1443 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1444 tree fn = builtin_decl_explicit (bcode);
1446 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1447 true, NULL_TREE, true,
1448 GSI_SAME_STMT);
1449 g = gimple_build_call (fn, 2, data, val);
1451 gimple_set_location (g, loc);
1452 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1453 ubsan_create_edge (g);
1454 *gsi = gsi_for_stmt (stmt);
1457 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1458 new style handlers. Libubsan uses heuristics to destinguish between old and
1459 new styles and relies on these properties for filename:
1461 a) Location's filename must not be NULL.
1462 b) Location's filename must not be equal to "".
1463 c) Location's filename must not be equal to "\1".
1464 d) First two bytes of filename must not contain '\xff' symbol. */
1466 static bool
1467 ubsan_use_new_style_p (location_t loc)
1469 if (loc == UNKNOWN_LOCATION)
1470 return false;
1472 expanded_location xloc = expand_location (loc);
1473 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1474 || xloc.file == '\0' || xloc.file[0] == '\xff'
1475 || xloc.file[1] == '\xff')
1476 return false;
1478 return true;
1481 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1482 destination, EXPR is floating-point expression. */
1484 tree
1485 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1487 tree expr_type = TREE_TYPE (expr);
1488 tree t, tt, fn, min, max;
1489 machine_mode mode = TYPE_MODE (expr_type);
1490 int prec = TYPE_PRECISION (type);
1491 bool uns_p = TYPE_UNSIGNED (type);
1492 if (loc == UNKNOWN_LOCATION)
1493 loc = input_location;
1495 /* Float to integer conversion first truncates toward zero, so
1496 even signed char c = 127.875f; is not problematic.
1497 Therefore, we should complain only if EXPR is unordered or smaller
1498 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1499 TYPE_MAX_VALUE + 1.0. */
1500 if (REAL_MODE_FORMAT (mode)->b == 2)
1502 /* For maximum, TYPE_MAX_VALUE might not be representable
1503 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1504 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1505 either representable or infinity. */
1506 REAL_VALUE_TYPE maxval = dconst1;
1507 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1508 real_convert (&maxval, mode, &maxval);
1509 max = build_real (expr_type, maxval);
1511 /* For unsigned, assume -1.0 is always representable. */
1512 if (uns_p)
1513 min = build_minus_one_cst (expr_type);
1514 else
1516 /* TYPE_MIN_VALUE is generally representable (or -inf),
1517 but TYPE_MIN_VALUE - 1.0 might not be. */
1518 REAL_VALUE_TYPE minval = dconstm1, minval2;
1519 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1520 real_convert (&minval, mode, &minval);
1521 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1522 real_convert (&minval2, mode, &minval2);
1523 if (real_compare (EQ_EXPR, &minval, &minval2)
1524 && !real_isinf (&minval))
1526 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1527 rounds to TYPE_MIN_VALUE, we need to subtract
1528 more. As REAL_MODE_FORMAT (mode)->p is the number
1529 of base digits, we want to subtract a number that
1530 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1531 times smaller than minval. */
1532 minval2 = dconst1;
1533 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1534 SET_REAL_EXP (&minval2,
1535 REAL_EXP (&minval2) + prec - 1
1536 - REAL_MODE_FORMAT (mode)->p + 1);
1537 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1538 real_convert (&minval2, mode, &minval2);
1540 min = build_real (expr_type, minval2);
1543 else if (REAL_MODE_FORMAT (mode)->b == 10)
1545 /* For _Decimal128 up to 34 decimal digits, - sign,
1546 dot, e, exponent. */
1547 char buf[64];
1548 mpfr_t m;
1549 int p = REAL_MODE_FORMAT (mode)->p;
1550 REAL_VALUE_TYPE maxval, minval;
1552 /* Use mpfr_snprintf rounding to compute the smallest
1553 representable decimal number greater or equal than
1554 1 << (prec - !uns_p). */
1555 mpfr_init2 (m, prec + 2);
1556 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1557 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1558 decimal_real_from_string (&maxval, buf);
1559 max = build_real (expr_type, maxval);
1561 /* For unsigned, assume -1.0 is always representable. */
1562 if (uns_p)
1563 min = build_minus_one_cst (expr_type);
1564 else
1566 /* Use mpfr_snprintf rounding to compute the largest
1567 representable decimal number less or equal than
1568 (-1 << (prec - 1)) - 1. */
1569 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1570 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1571 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1572 decimal_real_from_string (&minval, buf);
1573 min = build_real (expr_type, minval);
1575 mpfr_clear (m);
1577 else
1578 return NULL_TREE;
1580 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1581 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1582 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1583 if (integer_zerop (t))
1584 return NULL_TREE;
1586 if (flag_sanitize_undefined_trap_on_error)
1587 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1588 else
1590 location_t *loc_ptr = NULL;
1591 unsigned num_locations = 0;
1592 initialize_sanitizer_builtins ();
1593 /* Figure out if we can propagate location to ubsan_data and use new
1594 style handlers in libubsan. */
1595 if (ubsan_use_new_style_p (loc))
1597 loc_ptr = &loc;
1598 num_locations = 1;
1600 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1601 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1602 num_locations, loc_ptr,
1603 ubsan_type_descriptor (expr_type),
1604 ubsan_type_descriptor (type), NULL_TREE,
1605 NULL_TREE);
1606 enum built_in_function bcode
1607 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1608 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1609 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1610 fn = builtin_decl_explicit (bcode);
1611 fn = build_call_expr_loc (loc, fn, 2,
1612 build_fold_addr_expr_loc (loc, data),
1613 ubsan_encode_value (expr, false));
1616 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1619 /* Instrument values passed to function arguments with nonnull attribute. */
1621 static void
1622 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1624 gimple *stmt = gsi_stmt (*gsi);
1625 location_t loc[2];
1626 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1627 while for nonnull sanitization it is clear. */
1628 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1629 flag_delete_null_pointer_checks = 1;
1630 loc[0] = gimple_location (stmt);
1631 loc[1] = UNKNOWN_LOCATION;
1632 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1634 tree arg = gimple_call_arg (stmt, i);
1635 if (POINTER_TYPE_P (TREE_TYPE (arg))
1636 && infer_nonnull_range_by_attribute (stmt, arg))
1638 gimple *g;
1639 if (!is_gimple_val (arg))
1641 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1642 gimple_set_location (g, loc[0]);
1643 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1644 arg = gimple_assign_lhs (g);
1647 basic_block then_bb, fallthru_bb;
1648 *gsi = create_cond_insert_point (gsi, true, false, true,
1649 &then_bb, &fallthru_bb);
1650 g = gimple_build_cond (EQ_EXPR, arg,
1651 build_zero_cst (TREE_TYPE (arg)),
1652 NULL_TREE, NULL_TREE);
1653 gimple_set_location (g, loc[0]);
1654 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1656 *gsi = gsi_after_labels (then_bb);
1657 if (flag_sanitize_undefined_trap_on_error)
1658 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1659 else
1661 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1662 2, loc, NULL_TREE,
1663 build_int_cst (integer_type_node,
1664 i + 1),
1665 NULL_TREE);
1666 data = build_fold_addr_expr_loc (loc[0], data);
1667 enum built_in_function bcode
1668 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1669 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1670 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1671 tree fn = builtin_decl_explicit (bcode);
1673 g = gimple_build_call (fn, 1, data);
1675 gimple_set_location (g, loc[0]);
1676 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1677 ubsan_create_edge (g);
1679 *gsi = gsi_for_stmt (stmt);
1681 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1684 /* Instrument returns in functions with returns_nonnull attribute. */
1686 static void
1687 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1689 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1690 location_t loc[2];
1691 tree arg = gimple_return_retval (stmt);
1692 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1693 while for nonnull return sanitization it is clear. */
1694 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1695 flag_delete_null_pointer_checks = 1;
1696 loc[0] = gimple_location (stmt);
1697 loc[1] = UNKNOWN_LOCATION;
1698 if (arg
1699 && POINTER_TYPE_P (TREE_TYPE (arg))
1700 && is_gimple_val (arg)
1701 && infer_nonnull_range_by_attribute (stmt, arg))
1703 basic_block then_bb, fallthru_bb;
1704 *gsi = create_cond_insert_point (gsi, true, false, true,
1705 &then_bb, &fallthru_bb);
1706 gimple *g = gimple_build_cond (EQ_EXPR, arg,
1707 build_zero_cst (TREE_TYPE (arg)),
1708 NULL_TREE, NULL_TREE);
1709 gimple_set_location (g, loc[0]);
1710 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1712 *gsi = gsi_after_labels (then_bb);
1713 if (flag_sanitize_undefined_trap_on_error)
1714 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1715 else
1717 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1718 2, loc, NULL_TREE, NULL_TREE);
1719 data = build_fold_addr_expr_loc (loc[0], data);
1720 enum built_in_function bcode
1721 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1722 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1723 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1724 tree fn = builtin_decl_explicit (bcode);
1726 g = gimple_build_call (fn, 1, data);
1728 gimple_set_location (g, loc[0]);
1729 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1730 ubsan_create_edge (g);
1731 *gsi = gsi_for_stmt (stmt);
1733 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1736 /* Instrument memory references. Here we check whether the pointer
1737 points to an out-of-bounds location. */
1739 static void
1740 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1742 gimple *stmt = gsi_stmt (*gsi);
1743 location_t loc = gimple_location (stmt);
1744 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1745 tree type;
1746 tree index = NULL_TREE;
1747 HOST_WIDE_INT size_in_bytes;
1749 type = TREE_TYPE (t);
1750 if (VOID_TYPE_P (type))
1751 return;
1753 switch (TREE_CODE (t))
1755 case COMPONENT_REF:
1756 if (TREE_CODE (t) == COMPONENT_REF
1757 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1759 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1760 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1761 repr, NULL_TREE);
1763 break;
1764 case ARRAY_REF:
1765 index = TREE_OPERAND (t, 1);
1766 break;
1767 case INDIRECT_REF:
1768 case MEM_REF:
1769 case VAR_DECL:
1770 case PARM_DECL:
1771 case RESULT_DECL:
1772 break;
1773 default:
1774 return;
1777 size_in_bytes = int_size_in_bytes (type);
1778 if (size_in_bytes <= 0)
1779 return;
1781 HOST_WIDE_INT bitsize, bitpos;
1782 tree offset;
1783 machine_mode mode;
1784 int volatilep = 0, reversep, unsignedp = 0;
1785 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1786 &unsignedp, &reversep, &volatilep, false);
1788 if (bitpos % BITS_PER_UNIT != 0
1789 || bitsize != size_in_bytes * BITS_PER_UNIT)
1790 return;
1792 bool decl_p = DECL_P (inner);
1793 tree base;
1794 if (decl_p)
1795 base = inner;
1796 else if (TREE_CODE (inner) == MEM_REF)
1797 base = TREE_OPERAND (inner, 0);
1798 else
1799 return;
1800 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1802 while (TREE_CODE (base) == SSA_NAME)
1804 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
1805 if (gimple_assign_ssa_name_copy_p (def_stmt)
1806 || (gimple_assign_cast_p (def_stmt)
1807 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1808 || (is_gimple_assign (def_stmt)
1809 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1811 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1812 if (TREE_CODE (rhs1) == SSA_NAME
1813 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1814 break;
1815 else
1816 base = rhs1;
1818 else
1819 break;
1822 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1823 return;
1825 tree sizet;
1826 tree base_addr = base;
1827 gimple *bos_stmt = NULL;
1828 if (decl_p)
1829 base_addr = build1 (ADDR_EXPR,
1830 build_pointer_type (TREE_TYPE (base)), base);
1831 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1832 if (size != (unsigned HOST_WIDE_INT) -1)
1833 sizet = build_int_cst (sizetype, size);
1834 else if (optimize)
1836 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1837 loc = input_location;
1838 /* Generate __builtin_object_size call. */
1839 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1840 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1841 integer_zero_node);
1842 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1843 GSI_SAME_STMT);
1844 /* If the call above didn't end up being an integer constant, go one
1845 statement back and get the __builtin_object_size stmt. Save it,
1846 we might need it later. */
1847 if (SSA_VAR_P (sizet))
1849 gsi_prev (gsi);
1850 bos_stmt = gsi_stmt (*gsi);
1852 /* Move on to where we were. */
1853 gsi_next (gsi);
1856 else
1857 return;
1859 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1860 call. */
1861 /* ptr + sizeof (*ptr) - base */
1862 t = fold_build2 (MINUS_EXPR, sizetype,
1863 fold_convert (pointer_sized_int_node, ptr),
1864 fold_convert (pointer_sized_int_node, base_addr));
1865 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1867 /* Perhaps we can omit the check. */
1868 if (TREE_CODE (t) == INTEGER_CST
1869 && TREE_CODE (sizet) == INTEGER_CST
1870 && tree_int_cst_le (t, sizet))
1871 return;
1873 if (index != NULL_TREE
1874 && TREE_CODE (index) == SSA_NAME
1875 && TREE_CODE (sizet) == INTEGER_CST)
1877 gimple *def = SSA_NAME_DEF_STMT (index);
1878 if (is_gimple_assign (def)
1879 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1880 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1882 tree cst = gimple_assign_rhs2 (def);
1883 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1884 TYPE_SIZE_UNIT (type));
1885 if (tree_int_cst_sgn (cst) >= 0
1886 && tree_int_cst_lt (cst, sz))
1887 return;
1891 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1892 ubsan_create_edge (bos_stmt);
1894 /* We have to emit the check. */
1895 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1896 GSI_SAME_STMT);
1897 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1898 GSI_SAME_STMT);
1899 tree ckind = build_int_cst (unsigned_char_type_node,
1900 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1901 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1902 ptr, t, sizet, ckind);
1903 gimple_set_location (g, loc);
1904 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1907 /* True if we want to play UBSan games in the current function. */
1909 bool
1910 do_ubsan_in_current_function ()
1912 return (current_function_decl != NULL_TREE
1913 && !lookup_attribute ("no_sanitize_undefined",
1914 DECL_ATTRIBUTES (current_function_decl)));
1917 namespace {
1919 const pass_data pass_data_ubsan =
1921 GIMPLE_PASS, /* type */
1922 "ubsan", /* name */
1923 OPTGROUP_NONE, /* optinfo_flags */
1924 TV_TREE_UBSAN, /* tv_id */
1925 ( PROP_cfg | PROP_ssa ), /* properties_required */
1926 0, /* properties_provided */
1927 0, /* properties_destroyed */
1928 0, /* todo_flags_start */
1929 TODO_update_ssa, /* todo_flags_finish */
1932 class pass_ubsan : public gimple_opt_pass
1934 public:
1935 pass_ubsan (gcc::context *ctxt)
1936 : gimple_opt_pass (pass_data_ubsan, ctxt)
1939 /* opt_pass methods: */
1940 virtual bool gate (function *)
1942 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1943 | SANITIZE_BOOL | SANITIZE_ENUM
1944 | SANITIZE_ALIGNMENT
1945 | SANITIZE_NONNULL_ATTRIBUTE
1946 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1947 | SANITIZE_OBJECT_SIZE)
1948 && do_ubsan_in_current_function ();
1951 virtual unsigned int execute (function *);
1953 }; // class pass_ubsan
1955 unsigned int
1956 pass_ubsan::execute (function *fun)
1958 basic_block bb;
1959 gimple_stmt_iterator gsi;
1960 unsigned int ret = 0;
1962 initialize_sanitizer_builtins ();
1964 FOR_EACH_BB_FN (bb, fun)
1966 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1968 gimple *stmt = gsi_stmt (gsi);
1969 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1971 gsi_next (&gsi);
1972 continue;
1975 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1976 && is_gimple_assign (stmt))
1977 instrument_si_overflow (gsi);
1979 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1981 if (gimple_store_p (stmt))
1982 instrument_null (gsi, true);
1983 if (gimple_assign_load_p (stmt))
1984 instrument_null (gsi, false);
1987 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1988 && gimple_assign_load_p (stmt))
1990 instrument_bool_enum_load (&gsi);
1991 bb = gimple_bb (stmt);
1994 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1995 && is_gimple_call (stmt)
1996 && !gimple_call_internal_p (stmt))
1998 instrument_nonnull_arg (&gsi);
1999 bb = gimple_bb (stmt);
2002 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2003 && gimple_code (stmt) == GIMPLE_RETURN)
2005 instrument_nonnull_return (&gsi);
2006 bb = gimple_bb (stmt);
2009 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2011 if (gimple_store_p (stmt))
2012 instrument_object_size (&gsi, true);
2013 if (gimple_assign_load_p (stmt))
2014 instrument_object_size (&gsi, false);
2017 gsi_next (&gsi);
2019 if (gimple_purge_dead_eh_edges (bb))
2020 ret = TODO_cleanup_cfg;
2022 return ret;
2025 } // anon namespace
2027 gimple_opt_pass *
2028 make_pass_ubsan (gcc::context *ctxt)
2030 return new pass_ubsan (ctxt);
2033 #include "gt-ubsan.h"