2017-11-15 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / ubsan.c
blobdaee6975a646913fa746ef795225ac352f13d690
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2017 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "rtl.h"
26 #include "c-family/c-common.h"
27 #include "gimple.h"
28 #include "cfghooks.h"
29 #include "tree-pass.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "ssa.h"
33 #include "cgraph.h"
34 #include "tree-pretty-print.h"
35 #include "stor-layout.h"
36 #include "cfganal.h"
37 #include "gimple-iterator.h"
38 #include "output.h"
39 #include "cfgloop.h"
40 #include "ubsan.h"
41 #include "expr.h"
42 #include "asan.h"
43 #include "gimplify-me.h"
44 #include "dfp.h"
45 #include "builtins.h"
46 #include "tree-object-size.h"
47 #include "tree-cfg.h"
49 /* Map from a tree to a VAR_DECL tree. */
51 struct GTY((for_user)) tree_type_map {
52 struct tree_map_base type;
53 tree decl;
56 struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
58 static inline hashval_t
59 hash (tree_type_map *t)
61 return TYPE_UID (t->type.from);
64 static inline bool
65 equal (tree_type_map *a, tree_type_map *b)
67 return a->type.from == b->type.from;
70 static int
71 keep_cache_entry (tree_type_map *&m)
73 return ggc_marked_p (m->type.from);
77 static GTY ((cache))
78 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
80 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
82 static tree
83 decl_for_type_lookup (tree type)
85 /* If the hash table is not initialized yet, create it now. */
86 if (decl_tree_for_type == NULL)
88 decl_tree_for_type
89 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
90 /* That also means we don't have to bother with the lookup. */
91 return NULL_TREE;
94 struct tree_type_map *h, in;
95 in.type.from = type;
97 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
98 return h ? h->decl : NULL_TREE;
101 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
103 static void
104 decl_for_type_insert (tree type, tree decl)
106 struct tree_type_map *h;
108 h = ggc_alloc<tree_type_map> ();
109 h->type.from = type;
110 h->decl = decl;
111 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
114 /* Helper routine, which encodes a value in the pointer_sized_int_node.
115 Arguments with precision <= POINTER_SIZE are passed directly,
116 the rest is passed by reference. T is a value we are to encode.
117 PHASE determines when this function is called. */
119 tree
120 ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase)
122 tree type = TREE_TYPE (t);
123 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
124 if (bitsize <= POINTER_SIZE)
125 switch (TREE_CODE (type))
127 case BOOLEAN_TYPE:
128 case ENUMERAL_TYPE:
129 case INTEGER_TYPE:
130 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
131 case REAL_TYPE:
133 tree itype = build_nonstandard_integer_type (bitsize, true);
134 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
135 return fold_convert (pointer_sized_int_node, t);
137 default:
138 gcc_unreachable ();
140 else
142 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
144 /* The reason for this is that we don't want to pessimize
145 code by making vars unnecessarily addressable. */
146 tree var;
147 if (phase != UBSAN_ENCODE_VALUE_GENERIC)
149 var = create_tmp_var (type);
150 mark_addressable (var);
152 else
154 var = create_tmp_var_raw (type);
155 TREE_ADDRESSABLE (var) = 1;
156 DECL_CONTEXT (var) = current_function_decl;
158 if (phase == UBSAN_ENCODE_VALUE_RTL)
160 rtx mem
161 = assign_stack_temp_for_type (TYPE_MODE (type),
162 GET_MODE_SIZE (TYPE_MODE (type)),
163 type);
164 SET_DECL_RTL (var, mem);
165 expand_assignment (var, t, false);
166 return build_fold_addr_expr (var);
168 if (phase != UBSAN_ENCODE_VALUE_GENERIC)
170 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
171 t = build_fold_addr_expr (var);
172 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
174 else
176 var = build4 (TARGET_EXPR, type, var, t, NULL_TREE, NULL_TREE);
177 return build_fold_addr_expr (var);
180 else
181 return build_fold_addr_expr (t);
185 /* Cached ubsan_get_type_descriptor_type () return value. */
186 static GTY(()) tree ubsan_type_descriptor_type;
188 /* Build
189 struct __ubsan_type_descriptor
191 unsigned short __typekind;
192 unsigned short __typeinfo;
193 char __typename[];
195 type. */
197 static tree
198 ubsan_get_type_descriptor_type (void)
200 static const char *field_names[3]
201 = { "__typekind", "__typeinfo", "__typename" };
202 tree fields[3], ret;
204 if (ubsan_type_descriptor_type)
205 return ubsan_type_descriptor_type;
207 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
208 tree flex_arr_type = build_array_type (char_type_node, itype);
210 ret = make_node (RECORD_TYPE);
211 for (int i = 0; i < 3; i++)
213 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
214 get_identifier (field_names[i]),
215 (i == 2) ? flex_arr_type
216 : short_unsigned_type_node);
217 DECL_CONTEXT (fields[i]) = ret;
218 if (i)
219 DECL_CHAIN (fields[i - 1]) = fields[i];
221 tree type_decl = build_decl (input_location, TYPE_DECL,
222 get_identifier ("__ubsan_type_descriptor"),
223 ret);
224 DECL_IGNORED_P (type_decl) = 1;
225 DECL_ARTIFICIAL (type_decl) = 1;
226 TYPE_FIELDS (ret) = fields[0];
227 TYPE_NAME (ret) = type_decl;
228 TYPE_STUB_DECL (ret) = type_decl;
229 layout_type (ret);
230 ubsan_type_descriptor_type = ret;
231 return ret;
234 /* Cached ubsan_get_source_location_type () return value. */
235 static GTY(()) tree ubsan_source_location_type;
237 /* Build
238 struct __ubsan_source_location
240 const char *__filename;
241 unsigned int __line;
242 unsigned int __column;
244 type. */
246 tree
247 ubsan_get_source_location_type (void)
249 static const char *field_names[3]
250 = { "__filename", "__line", "__column" };
251 tree fields[3], ret;
252 if (ubsan_source_location_type)
253 return ubsan_source_location_type;
255 tree const_char_type = build_qualified_type (char_type_node,
256 TYPE_QUAL_CONST);
258 ret = make_node (RECORD_TYPE);
259 for (int i = 0; i < 3; i++)
261 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
262 get_identifier (field_names[i]),
263 (i == 0) ? build_pointer_type (const_char_type)
264 : unsigned_type_node);
265 DECL_CONTEXT (fields[i]) = ret;
266 if (i)
267 DECL_CHAIN (fields[i - 1]) = fields[i];
269 tree type_decl = build_decl (input_location, TYPE_DECL,
270 get_identifier ("__ubsan_source_location"),
271 ret);
272 DECL_IGNORED_P (type_decl) = 1;
273 DECL_ARTIFICIAL (type_decl) = 1;
274 TYPE_FIELDS (ret) = fields[0];
275 TYPE_NAME (ret) = type_decl;
276 TYPE_STUB_DECL (ret) = type_decl;
277 layout_type (ret);
278 ubsan_source_location_type = ret;
279 return ret;
282 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
283 type with its fields filled from a location_t LOC. */
285 static tree
286 ubsan_source_location (location_t loc)
288 expanded_location xloc;
289 tree type = ubsan_get_source_location_type ();
291 xloc = expand_location (loc);
292 tree str;
293 if (xloc.file == NULL)
295 str = build_int_cst (ptr_type_node, 0);
296 xloc.line = 0;
297 xloc.column = 0;
299 else
301 /* Fill in the values from LOC. */
302 size_t len = strlen (xloc.file) + 1;
303 str = build_string (len, xloc.file);
304 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
305 TREE_READONLY (str) = 1;
306 TREE_STATIC (str) = 1;
307 str = build_fold_addr_expr (str);
309 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
310 build_int_cst (unsigned_type_node,
311 xloc.line), NULL_TREE,
312 build_int_cst (unsigned_type_node,
313 xloc.column));
314 TREE_CONSTANT (ctor) = 1;
315 TREE_STATIC (ctor) = 1;
317 return ctor;
320 /* This routine returns a magic number for TYPE. */
322 static unsigned short
323 get_ubsan_type_info_for_type (tree type)
325 if (TREE_CODE (type) == REAL_TYPE)
326 return tree_to_uhwi (TYPE_SIZE (type));
327 else if (INTEGRAL_TYPE_P (type))
329 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
330 gcc_assert (prec != -1);
331 return (prec << 1) | !TYPE_UNSIGNED (type);
333 else
334 return 0;
337 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
338 ubsan_ids[1] for Lubsan_data labels. */
339 static GTY(()) unsigned int ubsan_ids[2];
341 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
342 descriptor. It first looks into the hash table; if not found,
343 create the VAR_DECL, put it into the hash table and return the
344 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
345 an enum controlling how we want to print the type. */
347 tree
348 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
350 /* See through any typedefs. */
351 type = TYPE_MAIN_VARIANT (type);
353 tree decl = decl_for_type_lookup (type);
354 /* It is possible that some of the earlier created DECLs were found
355 unused, in that case they weren't emitted and varpool_node::get
356 returns NULL node on them. But now we really need them. Thus,
357 renew them here. */
358 if (decl != NULL_TREE && varpool_node::get (decl))
359 return build_fold_addr_expr (decl);
361 tree dtype = ubsan_get_type_descriptor_type ();
362 tree type2 = type;
363 const char *tname = NULL;
364 pretty_printer pretty_name;
365 unsigned char deref_depth = 0;
366 unsigned short tkind, tinfo;
368 /* Get the name of the type, or the name of the pointer type. */
369 if (pstyle == UBSAN_PRINT_POINTER)
371 gcc_assert (POINTER_TYPE_P (type));
372 type2 = TREE_TYPE (type);
374 /* Remove any '*' operators from TYPE. */
375 while (POINTER_TYPE_P (type2))
376 deref_depth++, type2 = TREE_TYPE (type2);
378 if (TREE_CODE (type2) == METHOD_TYPE)
379 type2 = TYPE_METHOD_BASETYPE (type2);
382 /* If an array, get its type. */
383 type2 = strip_array_types (type2);
385 if (pstyle == UBSAN_PRINT_ARRAY)
387 while (POINTER_TYPE_P (type2))
388 deref_depth++, type2 = TREE_TYPE (type2);
391 if (TYPE_NAME (type2) != NULL)
393 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
394 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
395 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
396 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
399 if (tname == NULL)
400 /* We weren't able to determine the type name. */
401 tname = "<unknown>";
403 tree eltype = type;
404 if (pstyle == UBSAN_PRINT_POINTER)
406 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
407 TYPE_VOLATILE (type2) ? "volatile " : "",
408 TYPE_READONLY (type2) ? "const " : "",
409 TYPE_RESTRICT (type2) ? "restrict " : "",
410 TYPE_ATOMIC (type2) ? "_Atomic " : "",
411 TREE_CODE (type2) == RECORD_TYPE
412 ? "struct "
413 : TREE_CODE (type2) == UNION_TYPE
414 ? "union " : "", tname,
415 deref_depth == 0 ? "" : " ");
416 while (deref_depth-- > 0)
417 pp_star (&pretty_name);
418 pp_quote (&pretty_name);
420 else if (pstyle == UBSAN_PRINT_ARRAY)
422 /* Pretty print the array dimensions. */
423 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
424 tree t = type;
425 pp_printf (&pretty_name, "'%s ", tname);
426 while (deref_depth-- > 0)
427 pp_star (&pretty_name);
428 while (TREE_CODE (t) == ARRAY_TYPE)
430 pp_left_bracket (&pretty_name);
431 tree dom = TYPE_DOMAIN (t);
432 if (dom != NULL_TREE
433 && TYPE_MAX_VALUE (dom) != NULL_TREE
434 && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
436 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
437 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
438 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
439 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
440 else
441 pp_wide_int (&pretty_name,
442 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
443 TYPE_SIGN (TREE_TYPE (dom)));
445 else
446 /* ??? We can't determine the variable name; print VLA unspec. */
447 pp_star (&pretty_name);
448 pp_right_bracket (&pretty_name);
449 t = TREE_TYPE (t);
451 pp_quote (&pretty_name);
453 /* Save the tree with stripped types. */
454 eltype = t;
456 else
457 pp_printf (&pretty_name, "'%s'", tname);
459 switch (TREE_CODE (eltype))
461 case BOOLEAN_TYPE:
462 case ENUMERAL_TYPE:
463 case INTEGER_TYPE:
464 tkind = 0x0000;
465 break;
466 case REAL_TYPE:
467 /* FIXME: libubsan right now only supports float, double and
468 long double type formats. */
469 if (TYPE_MODE (eltype) == TYPE_MODE (float_type_node)
470 || TYPE_MODE (eltype) == TYPE_MODE (double_type_node)
471 || TYPE_MODE (eltype) == TYPE_MODE (long_double_type_node))
472 tkind = 0x0001;
473 else
474 tkind = 0xffff;
475 break;
476 default:
477 tkind = 0xffff;
478 break;
480 tinfo = get_ubsan_type_info_for_type (eltype);
482 /* Create a new VAR_DECL of type descriptor. */
483 const char *tmp = pp_formatted_text (&pretty_name);
484 size_t len = strlen (tmp) + 1;
485 tree str = build_string (len, tmp);
486 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
487 TREE_READONLY (str) = 1;
488 TREE_STATIC (str) = 1;
490 char tmp_name[32];
491 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
492 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
493 dtype);
494 TREE_STATIC (decl) = 1;
495 TREE_PUBLIC (decl) = 0;
496 DECL_ARTIFICIAL (decl) = 1;
497 DECL_IGNORED_P (decl) = 1;
498 DECL_EXTERNAL (decl) = 0;
499 DECL_SIZE (decl)
500 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
501 DECL_SIZE_UNIT (decl)
502 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
503 TYPE_SIZE_UNIT (TREE_TYPE (str)));
505 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
506 build_int_cst (short_unsigned_type_node,
507 tkind), NULL_TREE,
508 build_int_cst (short_unsigned_type_node,
509 tinfo), NULL_TREE, str);
510 TREE_CONSTANT (ctor) = 1;
511 TREE_STATIC (ctor) = 1;
512 DECL_INITIAL (decl) = ctor;
513 varpool_node::finalize_decl (decl);
515 /* Save the VAR_DECL into the hash table. */
516 decl_for_type_insert (type, decl);
518 return build_fold_addr_expr (decl);
521 /* Create a structure for the ubsan library. NAME is a name of the new
522 structure. LOCCNT is number of locations, PLOC points to array of
523 locations. The arguments in ... are of __ubsan_type_descriptor type
524 and there are at most two of them, followed by NULL_TREE, followed
525 by optional extra arguments and another NULL_TREE. */
527 tree
528 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
530 va_list args;
531 tree ret, t;
532 tree fields[6];
533 vec<tree, va_gc> *saved_args = NULL;
534 size_t i = 0;
535 int j;
537 /* It is possible that PCH zapped table with definitions of sanitizer
538 builtins. Reinitialize them if needed. */
539 initialize_sanitizer_builtins ();
541 /* Firstly, create a pointer to type descriptor type. */
542 tree td_type = ubsan_get_type_descriptor_type ();
543 td_type = build_pointer_type (td_type);
545 /* Create the structure type. */
546 ret = make_node (RECORD_TYPE);
547 for (j = 0; j < loccnt; j++)
549 gcc_checking_assert (i < 2);
550 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
551 ubsan_get_source_location_type ());
552 DECL_CONTEXT (fields[i]) = ret;
553 if (i)
554 DECL_CHAIN (fields[i - 1]) = fields[i];
555 i++;
558 va_start (args, ploc);
559 for (t = va_arg (args, tree); t != NULL_TREE;
560 i++, t = va_arg (args, tree))
562 gcc_checking_assert (i < 4);
563 /* Save the tree arguments for later use. */
564 vec_safe_push (saved_args, t);
565 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
566 td_type);
567 DECL_CONTEXT (fields[i]) = ret;
568 if (i)
569 DECL_CHAIN (fields[i - 1]) = fields[i];
572 for (t = va_arg (args, tree); t != NULL_TREE;
573 i++, t = va_arg (args, tree))
575 gcc_checking_assert (i < 6);
576 /* Save the tree arguments for later use. */
577 vec_safe_push (saved_args, t);
578 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
579 TREE_TYPE (t));
580 DECL_CONTEXT (fields[i]) = ret;
581 if (i)
582 DECL_CHAIN (fields[i - 1]) = fields[i];
584 va_end (args);
586 tree type_decl = build_decl (input_location, TYPE_DECL,
587 get_identifier (name), ret);
588 DECL_IGNORED_P (type_decl) = 1;
589 DECL_ARTIFICIAL (type_decl) = 1;
590 TYPE_FIELDS (ret) = fields[0];
591 TYPE_NAME (ret) = type_decl;
592 TYPE_STUB_DECL (ret) = type_decl;
593 layout_type (ret);
595 /* Now, fill in the type. */
596 char tmp_name[32];
597 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
598 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
599 ret);
600 TREE_STATIC (var) = 1;
601 TREE_PUBLIC (var) = 0;
602 DECL_ARTIFICIAL (var) = 1;
603 DECL_IGNORED_P (var) = 1;
604 DECL_EXTERNAL (var) = 0;
606 vec<constructor_elt, va_gc> *v;
607 vec_alloc (v, i);
608 tree ctor = build_constructor (ret, v);
610 /* If desirable, set the __ubsan_source_location element. */
611 for (j = 0; j < loccnt; j++)
613 location_t loc = LOCATION_LOCUS (ploc[j]);
614 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
617 size_t nelts = vec_safe_length (saved_args);
618 for (i = 0; i < nelts; i++)
620 t = (*saved_args)[i];
621 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
624 TREE_CONSTANT (ctor) = 1;
625 TREE_STATIC (ctor) = 1;
626 DECL_INITIAL (var) = ctor;
627 varpool_node::finalize_decl (var);
629 return var;
632 /* Instrument the __builtin_unreachable call. We just call the libubsan
633 routine instead. */
635 bool
636 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
638 gimple *g;
639 location_t loc = gimple_location (gsi_stmt (*gsi));
641 if (flag_sanitize_undefined_trap_on_error)
642 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
643 else
645 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
646 NULL_TREE, NULL_TREE);
647 data = build_fold_addr_expr_loc (loc, data);
648 tree fn
649 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
650 g = gimple_build_call (fn, 1, data);
652 gimple_set_location (g, loc);
653 gsi_replace (gsi, g, false);
654 return false;
657 /* Return true if T is a call to a libubsan routine. */
659 bool
660 is_ubsan_builtin_p (tree t)
662 return TREE_CODE (t) == FUNCTION_DECL
663 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
664 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
665 "__builtin___ubsan_", 18) == 0;
668 /* Create a callgraph edge for statement STMT. */
670 static void
671 ubsan_create_edge (gimple *stmt)
673 gcall *call_stmt = dyn_cast <gcall *> (stmt);
674 basic_block bb = gimple_bb (stmt);
675 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
676 cgraph_node *node = cgraph_node::get (current_function_decl);
677 tree decl = gimple_call_fndecl (call_stmt);
678 if (decl)
679 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
680 freq);
683 /* Expand the UBSAN_BOUNDS special builtin function. */
685 bool
686 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
688 gimple *stmt = gsi_stmt (*gsi);
689 location_t loc = gimple_location (stmt);
690 gcc_assert (gimple_call_num_args (stmt) == 3);
692 /* Pick up the arguments of the UBSAN_BOUNDS call. */
693 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
694 tree index = gimple_call_arg (stmt, 1);
695 tree orig_index = index;
696 tree bound = gimple_call_arg (stmt, 2);
698 gimple_stmt_iterator gsi_orig = *gsi;
700 /* Create condition "if (index > bound)". */
701 basic_block then_bb, fallthru_bb;
702 gimple_stmt_iterator cond_insert_point
703 = create_cond_insert_point (gsi, false, false, true,
704 &then_bb, &fallthru_bb);
705 index = fold_convert (TREE_TYPE (bound), index);
706 index = force_gimple_operand_gsi (&cond_insert_point, index,
707 true, NULL_TREE,
708 false, GSI_NEW_STMT);
709 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
710 gimple_set_location (g, loc);
711 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
713 /* Generate __ubsan_handle_out_of_bounds call. */
714 *gsi = gsi_after_labels (then_bb);
715 if (flag_sanitize_undefined_trap_on_error)
716 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
717 else
719 tree data
720 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
721 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
722 ubsan_type_descriptor (TREE_TYPE (orig_index)),
723 NULL_TREE, NULL_TREE);
724 data = build_fold_addr_expr_loc (loc, data);
725 enum built_in_function bcode
726 = (flag_sanitize_recover & SANITIZE_BOUNDS)
727 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
728 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
729 tree fn = builtin_decl_explicit (bcode);
730 tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE);
731 val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true,
732 GSI_SAME_STMT);
733 g = gimple_build_call (fn, 2, data, val);
735 gimple_set_location (g, loc);
736 gsi_insert_before (gsi, g, GSI_SAME_STMT);
738 /* Get rid of the UBSAN_BOUNDS call from the IR. */
739 unlink_stmt_vdef (stmt);
740 gsi_remove (&gsi_orig, true);
742 /* Point GSI to next logical statement. */
743 *gsi = gsi_start_bb (fallthru_bb);
744 return true;
747 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
748 argument which is a constant, because the middle-end treats pointer
749 conversions as useless and therefore the type of the first argument
750 could be changed to any other pointer type. */
752 bool
753 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
755 gimple_stmt_iterator gsi = *gsip;
756 gimple *stmt = gsi_stmt (gsi);
757 location_t loc = gimple_location (stmt);
758 gcc_assert (gimple_call_num_args (stmt) == 3);
759 tree ptr = gimple_call_arg (stmt, 0);
760 tree ckind = gimple_call_arg (stmt, 1);
761 tree align = gimple_call_arg (stmt, 2);
762 tree check_align = NULL_TREE;
763 bool check_null;
765 basic_block cur_bb = gsi_bb (gsi);
767 gimple *g;
768 if (!integer_zerop (align))
770 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
771 if (compare_tree_int (align, ptralign) == 1)
773 check_align = make_ssa_name (pointer_sized_int_node);
774 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
775 gimple_set_location (g, loc);
776 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
779 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
781 if (check_align == NULL_TREE && !check_null)
783 gsi_remove (gsip, true);
784 /* Unlink the UBSAN_NULLs vops before replacing it. */
785 unlink_stmt_vdef (stmt);
786 return true;
789 /* Split the original block holding the pointer dereference. */
790 edge e = split_block (cur_bb, stmt);
792 /* Get a hold on the 'condition block', the 'then block' and the
793 'else block'. */
794 basic_block cond_bb = e->src;
795 basic_block fallthru_bb = e->dest;
796 basic_block then_bb = create_empty_bb (cond_bb);
797 add_bb_to_loop (then_bb, cond_bb->loop_father);
798 loops_state_set (LOOPS_NEED_FIXUP);
800 /* Make an edge coming from the 'cond block' into the 'then block';
801 this edge is unlikely taken, so set up the probability accordingly. */
802 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
803 e->probability = PROB_VERY_UNLIKELY;
805 /* Connect 'then block' with the 'else block'. This is needed
806 as the ubsan routines we call in the 'then block' are not noreturn.
807 The 'then block' only has one outcoming edge. */
808 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
810 /* Set up the fallthrough basic block. */
811 e = find_edge (cond_bb, fallthru_bb);
812 e->flags = EDGE_FALSE_VALUE;
813 e->count = cond_bb->count;
814 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
816 /* Update dominance info for the newly created then_bb; note that
817 fallthru_bb's dominance info has already been updated by
818 split_block. */
819 if (dom_info_available_p (CDI_DOMINATORS))
820 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
822 /* Put the ubsan builtin call into the newly created BB. */
823 if (flag_sanitize_undefined_trap_on_error)
824 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
825 else
827 enum built_in_function bcode
828 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
829 | (check_null ? SANITIZE_NULL : 0)))
830 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
831 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
832 tree fn = builtin_decl_implicit (bcode);
833 tree data
834 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
835 ubsan_type_descriptor (TREE_TYPE (ckind),
836 UBSAN_PRINT_POINTER),
837 NULL_TREE,
838 align,
839 fold_convert (unsigned_char_type_node, ckind),
840 NULL_TREE);
841 data = build_fold_addr_expr_loc (loc, data);
842 g = gimple_build_call (fn, 2, data,
843 check_align ? check_align
844 : build_zero_cst (pointer_sized_int_node));
846 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
847 gimple_set_location (g, loc);
848 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
850 /* Unlink the UBSAN_NULLs vops before replacing it. */
851 unlink_stmt_vdef (stmt);
853 if (check_null)
855 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
856 NULL_TREE, NULL_TREE);
857 gimple_set_location (g, loc);
859 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
860 gsi_replace (&gsi, g, false);
861 stmt = g;
864 if (check_align)
866 if (check_null)
868 /* Split the block with the condition again. */
869 e = split_block (cond_bb, stmt);
870 basic_block cond1_bb = e->src;
871 basic_block cond2_bb = e->dest;
873 /* Make an edge coming from the 'cond1 block' into the 'then block';
874 this edge is unlikely taken, so set up the probability
875 accordingly. */
876 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
877 e->probability = PROB_VERY_UNLIKELY;
879 /* Set up the fallthrough basic block. */
880 e = find_edge (cond1_bb, cond2_bb);
881 e->flags = EDGE_FALSE_VALUE;
882 e->count = cond1_bb->count;
883 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
885 /* Update dominance info. */
886 if (dom_info_available_p (CDI_DOMINATORS))
888 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
889 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
892 gsi2 = gsi_start_bb (cond2_bb);
895 tree mask = build_int_cst (pointer_sized_int_node,
896 tree_to_uhwi (align) - 1);
897 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
898 BIT_AND_EXPR, check_align, mask);
899 gimple_set_location (g, loc);
900 if (check_null)
901 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
902 else
903 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
905 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
906 build_int_cst (pointer_sized_int_node, 0),
907 NULL_TREE, NULL_TREE);
908 gimple_set_location (g, loc);
909 if (check_null)
910 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
911 else
912 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
913 gsi_replace (&gsi, g, false);
915 return false;
918 #define OBJSZ_MAX_OFFSET (1024 * 16)
920 /* Expand UBSAN_OBJECT_SIZE internal call. */
922 bool
923 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
925 gimple *stmt = gsi_stmt (*gsi);
926 location_t loc = gimple_location (stmt);
927 gcc_assert (gimple_call_num_args (stmt) == 4);
929 tree ptr = gimple_call_arg (stmt, 0);
930 tree offset = gimple_call_arg (stmt, 1);
931 tree size = gimple_call_arg (stmt, 2);
932 tree ckind = gimple_call_arg (stmt, 3);
933 gimple_stmt_iterator gsi_orig = *gsi;
934 gimple *g;
936 /* See if we can discard the check. */
937 if (TREE_CODE (size) != INTEGER_CST
938 || integer_all_onesp (size))
939 /* Yes, __builtin_object_size couldn't determine the
940 object size. */;
941 else if (TREE_CODE (offset) == INTEGER_CST
942 && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
943 && wi::to_widest (offset) <= -1)
944 /* The offset is in range [-16K, -1]. */;
945 else
947 /* if (offset > objsize) */
948 basic_block then_bb, fallthru_bb;
949 gimple_stmt_iterator cond_insert_point
950 = create_cond_insert_point (gsi, false, false, true,
951 &then_bb, &fallthru_bb);
952 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
953 gimple_set_location (g, loc);
954 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
956 /* If the offset is small enough, we don't need the second
957 run-time check. */
958 if (TREE_CODE (offset) == INTEGER_CST
959 && wi::to_widest (offset) >= 0
960 && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
961 *gsi = gsi_after_labels (then_bb);
962 else
964 /* Don't issue run-time error if (ptr > ptr + offset). That
965 may happen when computing a POINTER_PLUS_EXPR. */
966 basic_block then2_bb, fallthru2_bb;
968 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
969 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
970 true, &then2_bb,
971 &fallthru2_bb);
972 /* Convert the pointer to an integer type. */
973 tree p = make_ssa_name (pointer_sized_int_node);
974 g = gimple_build_assign (p, NOP_EXPR, ptr);
975 gimple_set_location (g, loc);
976 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
977 p = gimple_assign_lhs (g);
978 /* Compute ptr + offset. */
979 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
980 PLUS_EXPR, p, offset);
981 gimple_set_location (g, loc);
982 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
983 /* Now build the conditional and put it into the IR. */
984 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
985 NULL_TREE, NULL_TREE);
986 gimple_set_location (g, loc);
987 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
988 *gsi = gsi_after_labels (then2_bb);
991 /* Generate __ubsan_handle_type_mismatch call. */
992 if (flag_sanitize_undefined_trap_on_error)
993 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
994 else
996 tree data
997 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
998 ubsan_type_descriptor (TREE_TYPE (ptr),
999 UBSAN_PRINT_POINTER),
1000 NULL_TREE,
1001 build_zero_cst (pointer_sized_int_node),
1002 ckind,
1003 NULL_TREE);
1004 data = build_fold_addr_expr_loc (loc, data);
1005 enum built_in_function bcode
1006 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1007 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1008 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
1009 tree p = make_ssa_name (pointer_sized_int_node);
1010 g = gimple_build_assign (p, NOP_EXPR, ptr);
1011 gimple_set_location (g, loc);
1012 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1013 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1015 gimple_set_location (g, loc);
1016 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1018 /* Point GSI to next logical statement. */
1019 *gsi = gsi_start_bb (fallthru_bb);
1021 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1022 unlink_stmt_vdef (stmt);
1023 gsi_remove (&gsi_orig, true);
1024 return true;
1027 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1028 unlink_stmt_vdef (stmt);
1029 gsi_remove (gsi, true);
1030 return true;
1033 /* Cached __ubsan_vptr_type_cache decl. */
1034 static GTY(()) tree ubsan_vptr_type_cache_decl;
1036 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1037 argument which is a constant, because the middle-end treats pointer
1038 conversions as useless and therefore the type of the first argument
1039 could be changed to any other pointer type. */
1041 bool
1042 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1044 gimple_stmt_iterator gsi = *gsip;
1045 gimple *stmt = gsi_stmt (gsi);
1046 location_t loc = gimple_location (stmt);
1047 gcc_assert (gimple_call_num_args (stmt) == 5);
1048 tree op = gimple_call_arg (stmt, 0);
1049 tree vptr = gimple_call_arg (stmt, 1);
1050 tree str_hash = gimple_call_arg (stmt, 2);
1051 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1052 tree ckind_tree = gimple_call_arg (stmt, 4);
1053 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1054 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1055 gimple *g;
1056 basic_block fallthru_bb = NULL;
1058 if (ckind == UBSAN_DOWNCAST_POINTER)
1060 /* Guard everything with if (op != NULL) { ... }. */
1061 basic_block then_bb;
1062 gimple_stmt_iterator cond_insert_point
1063 = create_cond_insert_point (gsip, false, false, true,
1064 &then_bb, &fallthru_bb);
1065 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1066 NULL_TREE, NULL_TREE);
1067 gimple_set_location (g, loc);
1068 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1069 *gsip = gsi_after_labels (then_bb);
1070 gsi_remove (&gsi, false);
1071 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1072 gsi = *gsip;
1075 tree htype = TREE_TYPE (str_hash);
1076 tree cst = wide_int_to_tree (htype,
1077 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1078 | 0xeb382d69, 64));
1079 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1080 vptr, str_hash);
1081 gimple_set_location (g, loc);
1082 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1083 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1084 gimple_assign_lhs (g), cst);
1085 gimple_set_location (g, loc);
1086 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1087 tree t1 = gimple_assign_lhs (g);
1088 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1089 t1, build_int_cst (integer_type_node, 47));
1090 gimple_set_location (g, loc);
1091 tree t2 = gimple_assign_lhs (g);
1092 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1093 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1094 vptr, t1);
1095 gimple_set_location (g, loc);
1096 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1097 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1098 t2, gimple_assign_lhs (g));
1099 gimple_set_location (g, loc);
1100 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1101 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1102 gimple_assign_lhs (g), cst);
1103 gimple_set_location (g, loc);
1104 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1105 tree t3 = gimple_assign_lhs (g);
1106 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1107 t3, build_int_cst (integer_type_node, 47));
1108 gimple_set_location (g, loc);
1109 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1110 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1111 t3, gimple_assign_lhs (g));
1112 gimple_set_location (g, loc);
1113 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1114 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1115 gimple_assign_lhs (g), cst);
1116 gimple_set_location (g, loc);
1117 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1118 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1120 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1121 NOP_EXPR, gimple_assign_lhs (g));
1122 gimple_set_location (g, loc);
1123 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1125 tree hash = gimple_assign_lhs (g);
1127 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1129 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1130 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1131 get_identifier ("__ubsan_vptr_type_cache"),
1132 atype);
1133 DECL_ARTIFICIAL (array) = 1;
1134 DECL_IGNORED_P (array) = 1;
1135 TREE_PUBLIC (array) = 1;
1136 TREE_STATIC (array) = 1;
1137 DECL_EXTERNAL (array) = 1;
1138 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1139 DECL_VISIBILITY_SPECIFIED (array) = 1;
1140 varpool_node::finalize_decl (array);
1141 ubsan_vptr_type_cache_decl = array;
1144 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1145 BIT_AND_EXPR, hash,
1146 build_int_cst (pointer_sized_int_node, 127));
1147 gimple_set_location (g, loc);
1148 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1150 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1151 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1152 NULL_TREE, NULL_TREE);
1153 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1154 ARRAY_REF, c);
1155 gimple_set_location (g, loc);
1156 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1158 basic_block then_bb, fallthru2_bb;
1159 gimple_stmt_iterator cond_insert_point
1160 = create_cond_insert_point (gsip, false, false, true,
1161 &then_bb, &fallthru2_bb);
1162 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1163 NULL_TREE, NULL_TREE);
1164 gimple_set_location (g, loc);
1165 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1166 *gsip = gsi_after_labels (then_bb);
1167 if (fallthru_bb == NULL)
1168 fallthru_bb = fallthru2_bb;
1170 tree data
1171 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1172 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1173 build_int_cst (unsigned_char_type_node, ckind),
1174 NULL_TREE);
1175 data = build_fold_addr_expr_loc (loc, data);
1176 enum built_in_function bcode
1177 = (flag_sanitize_recover & SANITIZE_VPTR)
1178 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1179 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1181 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1182 gimple_set_location (g, loc);
1183 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1185 /* Point GSI to next logical statement. */
1186 *gsip = gsi_start_bb (fallthru_bb);
1188 /* Get rid of the UBSAN_VPTR call from the IR. */
1189 unlink_stmt_vdef (stmt);
1190 gsi_remove (&gsi, true);
1191 return true;
1194 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1195 whether the pointer is on the left hand side of the assignment. */
1197 static void
1198 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1199 bool is_lhs)
1201 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1202 unsigned int align = 0;
1203 if (flag_sanitize & SANITIZE_ALIGNMENT)
1205 align = min_align_of_type (TREE_TYPE (base));
1206 if (align <= 1)
1207 align = 0;
1209 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1210 return;
1211 tree t = TREE_OPERAND (base, 0);
1212 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1213 return;
1214 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1215 ikind = UBSAN_MEMBER_ACCESS;
1216 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1217 tree alignt = build_int_cst (pointer_sized_int_node, align);
1218 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1219 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1220 gsi_insert_before (iter, g, GSI_SAME_STMT);
1223 /* Perform the pointer instrumentation. */
1225 static void
1226 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1228 gimple *stmt = gsi_stmt (gsi);
1229 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1230 tree base = get_base_address (t);
1231 const enum tree_code code = TREE_CODE (base);
1232 if (code == MEM_REF
1233 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1234 instrument_mem_ref (t, base, &gsi, is_lhs);
1237 /* Build an ubsan builtin call for the signed-integer-overflow
1238 sanitization. CODE says what kind of builtin are we building,
1239 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1240 are operands of the binary operation. */
1242 tree
1243 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1244 tree op0, tree op1, tree *datap)
1246 if (flag_sanitize_undefined_trap_on_error)
1247 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1249 tree data;
1250 if (datap && *datap)
1251 data = *datap;
1252 else
1253 data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1254 ubsan_type_descriptor (lhstype), NULL_TREE,
1255 NULL_TREE);
1256 if (datap)
1257 *datap = data;
1258 enum built_in_function fn_code;
1260 switch (code)
1262 case PLUS_EXPR:
1263 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1264 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1265 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1266 break;
1267 case MINUS_EXPR:
1268 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1269 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1270 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1271 break;
1272 case MULT_EXPR:
1273 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1274 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1275 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1276 break;
1277 case NEGATE_EXPR:
1278 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1279 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1280 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1281 break;
1282 default:
1283 gcc_unreachable ();
1285 tree fn = builtin_decl_explicit (fn_code);
1286 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1287 build_fold_addr_expr_loc (loc, data),
1288 ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL),
1290 ? ubsan_encode_value (op1,
1291 UBSAN_ENCODE_VALUE_RTL)
1292 : NULL_TREE);
1295 /* Perform the signed integer instrumentation. GSI is the iterator
1296 pointing at statement we are trying to instrument. */
1298 static void
1299 instrument_si_overflow (gimple_stmt_iterator gsi)
1301 gimple *stmt = gsi_stmt (gsi);
1302 tree_code code = gimple_assign_rhs_code (stmt);
1303 tree lhs = gimple_assign_lhs (stmt);
1304 tree lhstype = TREE_TYPE (lhs);
1305 tree lhsinner = VECTOR_TYPE_P (lhstype) ? TREE_TYPE (lhstype) : lhstype;
1306 tree a, b;
1307 gimple *g;
1309 /* If this is not a signed operation, don't instrument anything here.
1310 Also punt on bit-fields. */
1311 if (!INTEGRAL_TYPE_P (lhsinner)
1312 || TYPE_OVERFLOW_WRAPS (lhsinner)
1313 || GET_MODE_BITSIZE (TYPE_MODE (lhsinner)) != TYPE_PRECISION (lhsinner))
1314 return;
1316 switch (code)
1318 case MINUS_EXPR:
1319 case PLUS_EXPR:
1320 case MULT_EXPR:
1321 /* Transform
1322 i = u {+,-,*} 5;
1323 into
1324 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1325 a = gimple_assign_rhs1 (stmt);
1326 b = gimple_assign_rhs2 (stmt);
1327 g = gimple_build_call_internal (code == PLUS_EXPR
1328 ? IFN_UBSAN_CHECK_ADD
1329 : code == MINUS_EXPR
1330 ? IFN_UBSAN_CHECK_SUB
1331 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1332 gimple_call_set_lhs (g, lhs);
1333 gsi_replace (&gsi, g, true);
1334 break;
1335 case NEGATE_EXPR:
1336 /* Represent i = -u;
1338 i = UBSAN_CHECK_SUB (0, u); */
1339 a = build_zero_cst (lhstype);
1340 b = gimple_assign_rhs1 (stmt);
1341 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1342 gimple_call_set_lhs (g, lhs);
1343 gsi_replace (&gsi, g, true);
1344 break;
1345 case ABS_EXPR:
1346 /* Transform i = ABS_EXPR<u>;
1347 into
1348 _N = UBSAN_CHECK_SUB (0, u);
1349 i = ABS_EXPR<_N>; */
1350 a = build_zero_cst (lhstype);
1351 b = gimple_assign_rhs1 (stmt);
1352 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1353 a = make_ssa_name (lhstype);
1354 gimple_call_set_lhs (g, a);
1355 gimple_set_location (g, gimple_location (stmt));
1356 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1357 gimple_assign_set_rhs1 (stmt, a);
1358 update_stmt (stmt);
1359 break;
1360 default:
1361 break;
1365 /* Instrument loads from (non-bitfield) bool and C++ enum values
1366 to check if the memory value is outside of the range of the valid
1367 type values. */
1369 static void
1370 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1372 gimple *stmt = gsi_stmt (*gsi);
1373 tree rhs = gimple_assign_rhs1 (stmt);
1374 tree type = TREE_TYPE (rhs);
1375 tree minv = NULL_TREE, maxv = NULL_TREE;
1377 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1379 minv = boolean_false_node;
1380 maxv = boolean_true_node;
1382 else if (TREE_CODE (type) == ENUMERAL_TYPE
1383 && (flag_sanitize & SANITIZE_ENUM)
1384 && TREE_TYPE (type) != NULL_TREE
1385 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1386 && (TYPE_PRECISION (TREE_TYPE (type))
1387 < GET_MODE_PRECISION (TYPE_MODE (type))))
1389 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1390 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1392 else
1393 return;
1395 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1396 HOST_WIDE_INT bitsize, bitpos;
1397 tree offset;
1398 machine_mode mode;
1399 int volatilep = 0, reversep, unsignedp = 0;
1400 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1401 &unsignedp, &reversep, &volatilep);
1402 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1404 if ((VAR_P (base) && DECL_HARD_REGISTER (base))
1405 || (bitpos % modebitsize) != 0
1406 || bitsize != modebitsize
1407 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1408 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1409 return;
1411 bool ends_bb = stmt_ends_bb_p (stmt);
1412 location_t loc = gimple_location (stmt);
1413 tree lhs = gimple_assign_lhs (stmt);
1414 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1415 tree atype = reference_alias_ptr_type (rhs);
1416 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1417 build_fold_addr_expr (rhs));
1418 gimple_set_location (g, loc);
1419 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1420 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1421 build_int_cst (atype, 0));
1422 tree urhs = make_ssa_name (utype);
1423 if (ends_bb)
1425 gimple_assign_set_lhs (stmt, urhs);
1426 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1427 gimple_set_location (g, loc);
1428 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1429 gsi_insert_on_edge_immediate (e, g);
1430 gimple_assign_set_rhs_from_tree (gsi, mem);
1431 update_stmt (stmt);
1432 *gsi = gsi_for_stmt (g);
1433 g = stmt;
1435 else
1437 g = gimple_build_assign (urhs, mem);
1438 gimple_set_location (g, loc);
1439 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1441 minv = fold_convert (utype, minv);
1442 maxv = fold_convert (utype, maxv);
1443 if (!integer_zerop (minv))
1445 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1446 gimple_set_location (g, loc);
1447 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1450 gimple_stmt_iterator gsi2 = *gsi;
1451 basic_block then_bb, fallthru_bb;
1452 *gsi = create_cond_insert_point (gsi, true, false, true,
1453 &then_bb, &fallthru_bb);
1454 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1455 int_const_binop (MINUS_EXPR, maxv, minv),
1456 NULL_TREE, NULL_TREE);
1457 gimple_set_location (g, loc);
1458 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1460 if (!ends_bb)
1462 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1463 update_stmt (stmt);
1466 gsi2 = gsi_after_labels (then_bb);
1467 if (flag_sanitize_undefined_trap_on_error)
1468 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1469 else
1471 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1472 ubsan_type_descriptor (type), NULL_TREE,
1473 NULL_TREE);
1474 data = build_fold_addr_expr_loc (loc, data);
1475 enum built_in_function bcode
1476 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1477 ? SANITIZE_BOOL : SANITIZE_ENUM))
1478 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1479 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1480 tree fn = builtin_decl_explicit (bcode);
1482 tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE);
1483 val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true,
1484 GSI_SAME_STMT);
1485 g = gimple_build_call (fn, 2, data, val);
1487 gimple_set_location (g, loc);
1488 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1489 ubsan_create_edge (g);
1490 *gsi = gsi_for_stmt (stmt);
1493 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1494 new style handlers. Libubsan uses heuristics to destinguish between old and
1495 new styles and relies on these properties for filename:
1497 a) Location's filename must not be NULL.
1498 b) Location's filename must not be equal to "".
1499 c) Location's filename must not be equal to "\1".
1500 d) First two bytes of filename must not contain '\xff' symbol. */
1502 static bool
1503 ubsan_use_new_style_p (location_t loc)
1505 if (loc == UNKNOWN_LOCATION)
1506 return false;
1508 expanded_location xloc = expand_location (loc);
1509 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1510 || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1511 || xloc.file[1] == '\xff')
1512 return false;
1514 return true;
1517 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1518 destination, EXPR is floating-point expression. */
1520 tree
1521 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1523 tree expr_type = TREE_TYPE (expr);
1524 tree t, tt, fn, min, max;
1525 machine_mode mode = TYPE_MODE (expr_type);
1526 int prec = TYPE_PRECISION (type);
1527 bool uns_p = TYPE_UNSIGNED (type);
1528 if (loc == UNKNOWN_LOCATION)
1529 loc = input_location;
1531 /* Float to integer conversion first truncates toward zero, so
1532 even signed char c = 127.875f; is not problematic.
1533 Therefore, we should complain only if EXPR is unordered or smaller
1534 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1535 TYPE_MAX_VALUE + 1.0. */
1536 if (REAL_MODE_FORMAT (mode)->b == 2)
1538 /* For maximum, TYPE_MAX_VALUE might not be representable
1539 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1540 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1541 either representable or infinity. */
1542 REAL_VALUE_TYPE maxval = dconst1;
1543 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1544 real_convert (&maxval, mode, &maxval);
1545 max = build_real (expr_type, maxval);
1547 /* For unsigned, assume -1.0 is always representable. */
1548 if (uns_p)
1549 min = build_minus_one_cst (expr_type);
1550 else
1552 /* TYPE_MIN_VALUE is generally representable (or -inf),
1553 but TYPE_MIN_VALUE - 1.0 might not be. */
1554 REAL_VALUE_TYPE minval = dconstm1, minval2;
1555 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1556 real_convert (&minval, mode, &minval);
1557 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1558 real_convert (&minval2, mode, &minval2);
1559 if (real_compare (EQ_EXPR, &minval, &minval2)
1560 && !real_isinf (&minval))
1562 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1563 rounds to TYPE_MIN_VALUE, we need to subtract
1564 more. As REAL_MODE_FORMAT (mode)->p is the number
1565 of base digits, we want to subtract a number that
1566 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1567 times smaller than minval. */
1568 minval2 = dconst1;
1569 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1570 SET_REAL_EXP (&minval2,
1571 REAL_EXP (&minval2) + prec - 1
1572 - REAL_MODE_FORMAT (mode)->p + 1);
1573 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1574 real_convert (&minval2, mode, &minval2);
1576 min = build_real (expr_type, minval2);
1579 else if (REAL_MODE_FORMAT (mode)->b == 10)
1581 /* For _Decimal128 up to 34 decimal digits, - sign,
1582 dot, e, exponent. */
1583 char buf[64];
1584 mpfr_t m;
1585 int p = REAL_MODE_FORMAT (mode)->p;
1586 REAL_VALUE_TYPE maxval, minval;
1588 /* Use mpfr_snprintf rounding to compute the smallest
1589 representable decimal number greater or equal than
1590 1 << (prec - !uns_p). */
1591 mpfr_init2 (m, prec + 2);
1592 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1593 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1594 decimal_real_from_string (&maxval, buf);
1595 max = build_real (expr_type, maxval);
1597 /* For unsigned, assume -1.0 is always representable. */
1598 if (uns_p)
1599 min = build_minus_one_cst (expr_type);
1600 else
1602 /* Use mpfr_snprintf rounding to compute the largest
1603 representable decimal number less or equal than
1604 (-1 << (prec - 1)) - 1. */
1605 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1606 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1607 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1608 decimal_real_from_string (&minval, buf);
1609 min = build_real (expr_type, minval);
1611 mpfr_clear (m);
1613 else
1614 return NULL_TREE;
1616 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1617 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1618 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1619 if (integer_zerop (t))
1620 return NULL_TREE;
1622 if (flag_sanitize_undefined_trap_on_error)
1623 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1624 else
1626 location_t *loc_ptr = NULL;
1627 unsigned num_locations = 0;
1628 /* Figure out if we can propagate location to ubsan_data and use new
1629 style handlers in libubsan. */
1630 if (ubsan_use_new_style_p (loc))
1632 loc_ptr = &loc;
1633 num_locations = 1;
1635 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1636 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1637 num_locations, loc_ptr,
1638 ubsan_type_descriptor (expr_type),
1639 ubsan_type_descriptor (type), NULL_TREE,
1640 NULL_TREE);
1641 enum built_in_function bcode
1642 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1643 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1644 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1645 fn = builtin_decl_explicit (bcode);
1646 fn = build_call_expr_loc (loc, fn, 2,
1647 build_fold_addr_expr_loc (loc, data),
1648 ubsan_encode_value (expr));
1651 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1654 /* Instrument values passed to function arguments with nonnull attribute. */
1656 static void
1657 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1659 gimple *stmt = gsi_stmt (*gsi);
1660 location_t loc[2];
1661 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1662 while for nonnull sanitization it is clear. */
1663 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1664 flag_delete_null_pointer_checks = 1;
1665 loc[0] = gimple_location (stmt);
1666 loc[1] = UNKNOWN_LOCATION;
1667 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1669 tree arg = gimple_call_arg (stmt, i);
1670 if (POINTER_TYPE_P (TREE_TYPE (arg))
1671 && infer_nonnull_range_by_attribute (stmt, arg))
1673 gimple *g;
1674 if (!is_gimple_val (arg))
1676 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1677 gimple_set_location (g, loc[0]);
1678 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1679 arg = gimple_assign_lhs (g);
1682 basic_block then_bb, fallthru_bb;
1683 *gsi = create_cond_insert_point (gsi, true, false, true,
1684 &then_bb, &fallthru_bb);
1685 g = gimple_build_cond (EQ_EXPR, arg,
1686 build_zero_cst (TREE_TYPE (arg)),
1687 NULL_TREE, NULL_TREE);
1688 gimple_set_location (g, loc[0]);
1689 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1691 *gsi = gsi_after_labels (then_bb);
1692 if (flag_sanitize_undefined_trap_on_error)
1693 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1694 else
1696 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1697 2, loc, NULL_TREE,
1698 build_int_cst (integer_type_node,
1699 i + 1),
1700 NULL_TREE);
1701 data = build_fold_addr_expr_loc (loc[0], data);
1702 enum built_in_function bcode
1703 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1704 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1705 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1706 tree fn = builtin_decl_explicit (bcode);
1708 g = gimple_build_call (fn, 1, data);
1710 gimple_set_location (g, loc[0]);
1711 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1712 ubsan_create_edge (g);
1714 *gsi = gsi_for_stmt (stmt);
1716 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1719 /* Instrument returns in functions with returns_nonnull attribute. */
1721 static void
1722 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1724 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1725 location_t loc[2];
1726 tree arg = gimple_return_retval (stmt);
1727 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1728 while for nonnull return sanitization it is clear. */
1729 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1730 flag_delete_null_pointer_checks = 1;
1731 loc[0] = gimple_location (stmt);
1732 loc[1] = UNKNOWN_LOCATION;
1733 if (arg
1734 && POINTER_TYPE_P (TREE_TYPE (arg))
1735 && is_gimple_val (arg)
1736 && infer_nonnull_range_by_attribute (stmt, arg))
1738 basic_block then_bb, fallthru_bb;
1739 *gsi = create_cond_insert_point (gsi, true, false, true,
1740 &then_bb, &fallthru_bb);
1741 gimple *g = gimple_build_cond (EQ_EXPR, arg,
1742 build_zero_cst (TREE_TYPE (arg)),
1743 NULL_TREE, NULL_TREE);
1744 gimple_set_location (g, loc[0]);
1745 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1747 *gsi = gsi_after_labels (then_bb);
1748 if (flag_sanitize_undefined_trap_on_error)
1749 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1750 else
1752 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1753 2, loc, NULL_TREE, NULL_TREE);
1754 data = build_fold_addr_expr_loc (loc[0], data);
1755 enum built_in_function bcode
1756 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1757 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1758 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1759 tree fn = builtin_decl_explicit (bcode);
1761 g = gimple_build_call (fn, 1, data);
1763 gimple_set_location (g, loc[0]);
1764 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1765 ubsan_create_edge (g);
1766 *gsi = gsi_for_stmt (stmt);
1768 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1771 /* Instrument memory references. Here we check whether the pointer
1772 points to an out-of-bounds location. */
1774 static void
1775 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1777 gimple *stmt = gsi_stmt (*gsi);
1778 location_t loc = gimple_location (stmt);
1779 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1780 tree type;
1781 tree index = NULL_TREE;
1782 HOST_WIDE_INT size_in_bytes;
1784 type = TREE_TYPE (t);
1785 if (VOID_TYPE_P (type))
1786 return;
1788 switch (TREE_CODE (t))
1790 case COMPONENT_REF:
1791 if (TREE_CODE (t) == COMPONENT_REF
1792 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1794 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1795 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1796 repr, TREE_OPERAND (t, 2));
1798 break;
1799 case ARRAY_REF:
1800 index = TREE_OPERAND (t, 1);
1801 break;
1802 case INDIRECT_REF:
1803 case MEM_REF:
1804 case VAR_DECL:
1805 case PARM_DECL:
1806 case RESULT_DECL:
1807 break;
1808 default:
1809 return;
1812 size_in_bytes = int_size_in_bytes (type);
1813 if (size_in_bytes <= 0)
1814 return;
1816 HOST_WIDE_INT bitsize, bitpos;
1817 tree offset;
1818 machine_mode mode;
1819 int volatilep = 0, reversep, unsignedp = 0;
1820 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1821 &unsignedp, &reversep, &volatilep);
1823 if (bitpos % BITS_PER_UNIT != 0
1824 || bitsize != size_in_bytes * BITS_PER_UNIT)
1825 return;
1827 bool decl_p = DECL_P (inner);
1828 tree base;
1829 if (decl_p)
1831 if (DECL_REGISTER (inner))
1832 return;
1833 base = inner;
1835 else if (TREE_CODE (inner) == MEM_REF)
1836 base = TREE_OPERAND (inner, 0);
1837 else
1838 return;
1839 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1841 while (TREE_CODE (base) == SSA_NAME)
1843 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
1844 if (gimple_assign_ssa_name_copy_p (def_stmt)
1845 || (gimple_assign_cast_p (def_stmt)
1846 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1847 || (is_gimple_assign (def_stmt)
1848 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1850 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1851 if (TREE_CODE (rhs1) == SSA_NAME
1852 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1853 break;
1854 else
1855 base = rhs1;
1857 else
1858 break;
1861 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1862 return;
1864 tree sizet;
1865 tree base_addr = base;
1866 gimple *bos_stmt = NULL;
1867 if (decl_p)
1868 base_addr = build1 (ADDR_EXPR,
1869 build_pointer_type (TREE_TYPE (base)), base);
1870 unsigned HOST_WIDE_INT size;
1871 if (compute_builtin_object_size (base_addr, 0, &size))
1872 sizet = build_int_cst (sizetype, size);
1873 else if (optimize)
1875 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1876 loc = input_location;
1877 /* Generate __builtin_object_size call. */
1878 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1879 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1880 integer_zero_node);
1881 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1882 GSI_SAME_STMT);
1883 /* If the call above didn't end up being an integer constant, go one
1884 statement back and get the __builtin_object_size stmt. Save it,
1885 we might need it later. */
1886 if (SSA_VAR_P (sizet))
1888 gsi_prev (gsi);
1889 bos_stmt = gsi_stmt (*gsi);
1891 /* Move on to where we were. */
1892 gsi_next (gsi);
1895 else
1896 return;
1898 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1899 call. */
1900 /* ptr + sizeof (*ptr) - base */
1901 t = fold_build2 (MINUS_EXPR, sizetype,
1902 fold_convert (pointer_sized_int_node, ptr),
1903 fold_convert (pointer_sized_int_node, base_addr));
1904 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1906 /* Perhaps we can omit the check. */
1907 if (TREE_CODE (t) == INTEGER_CST
1908 && TREE_CODE (sizet) == INTEGER_CST
1909 && tree_int_cst_le (t, sizet))
1910 return;
1912 if (index != NULL_TREE
1913 && TREE_CODE (index) == SSA_NAME
1914 && TREE_CODE (sizet) == INTEGER_CST)
1916 gimple *def = SSA_NAME_DEF_STMT (index);
1917 if (is_gimple_assign (def)
1918 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1919 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1921 tree cst = gimple_assign_rhs2 (def);
1922 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1923 TYPE_SIZE_UNIT (type));
1924 if (tree_int_cst_sgn (cst) >= 0
1925 && tree_int_cst_lt (cst, sz))
1926 return;
1930 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1931 ubsan_create_edge (bos_stmt);
1933 /* We have to emit the check. */
1934 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1935 GSI_SAME_STMT);
1936 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1937 GSI_SAME_STMT);
1938 tree ckind = build_int_cst (unsigned_char_type_node,
1939 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1940 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1941 ptr, t, sizet, ckind);
1942 gimple_set_location (g, loc);
1943 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1946 /* True if we want to play UBSan games in the current function. */
1948 bool
1949 do_ubsan_in_current_function ()
1951 return (current_function_decl != NULL_TREE
1952 && !lookup_attribute ("no_sanitize_undefined",
1953 DECL_ATTRIBUTES (current_function_decl)));
1956 namespace {
1958 const pass_data pass_data_ubsan =
1960 GIMPLE_PASS, /* type */
1961 "ubsan", /* name */
1962 OPTGROUP_NONE, /* optinfo_flags */
1963 TV_TREE_UBSAN, /* tv_id */
1964 ( PROP_cfg | PROP_ssa ), /* properties_required */
1965 0, /* properties_provided */
1966 0, /* properties_destroyed */
1967 0, /* todo_flags_start */
1968 TODO_update_ssa, /* todo_flags_finish */
1971 class pass_ubsan : public gimple_opt_pass
1973 public:
1974 pass_ubsan (gcc::context *ctxt)
1975 : gimple_opt_pass (pass_data_ubsan, ctxt)
1978 /* opt_pass methods: */
1979 virtual bool gate (function *)
1981 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1982 | SANITIZE_BOOL | SANITIZE_ENUM
1983 | SANITIZE_ALIGNMENT
1984 | SANITIZE_NONNULL_ATTRIBUTE
1985 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1986 | SANITIZE_OBJECT_SIZE)
1987 && do_ubsan_in_current_function ();
1990 virtual unsigned int execute (function *);
1992 }; // class pass_ubsan
1994 unsigned int
1995 pass_ubsan::execute (function *fun)
1997 basic_block bb;
1998 gimple_stmt_iterator gsi;
1999 unsigned int ret = 0;
2001 initialize_sanitizer_builtins ();
2003 FOR_EACH_BB_FN (bb, fun)
2005 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
2007 gimple *stmt = gsi_stmt (gsi);
2008 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
2010 gsi_next (&gsi);
2011 continue;
2014 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
2015 && is_gimple_assign (stmt))
2016 instrument_si_overflow (gsi);
2018 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
2020 if (gimple_store_p (stmt))
2021 instrument_null (gsi, true);
2022 if (gimple_assign_load_p (stmt))
2023 instrument_null (gsi, false);
2026 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
2027 && gimple_assign_load_p (stmt))
2029 instrument_bool_enum_load (&gsi);
2030 bb = gimple_bb (stmt);
2033 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
2034 && is_gimple_call (stmt)
2035 && !gimple_call_internal_p (stmt))
2037 instrument_nonnull_arg (&gsi);
2038 bb = gimple_bb (stmt);
2041 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2042 && gimple_code (stmt) == GIMPLE_RETURN)
2044 instrument_nonnull_return (&gsi);
2045 bb = gimple_bb (stmt);
2048 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2050 if (gimple_store_p (stmt))
2051 instrument_object_size (&gsi, true);
2052 if (gimple_assign_load_p (stmt))
2053 instrument_object_size (&gsi, false);
2056 gsi_next (&gsi);
2058 if (gimple_purge_dead_eh_edges (bb))
2059 ret = TODO_cleanup_cfg;
2061 return ret;
2064 } // anon namespace
2066 gimple_opt_pass *
2067 make_pass_ubsan (gcc::context *ctxt)
2069 return new pass_ubsan (ctxt);
2072 #include "gt-ubsan.h"