[gcc]
[official-gcc.git] / gcc / ubsan.c
blobbd0588b89baa07a4ae336d701af124336e74df2f
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 if (pstyle == UBSAN_PRINT_POINTER)
405 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
406 TYPE_VOLATILE (type2) ? "volatile " : "",
407 TYPE_READONLY (type2) ? "const " : "",
408 TYPE_RESTRICT (type2) ? "restrict " : "",
409 TYPE_ATOMIC (type2) ? "_Atomic " : "",
410 TREE_CODE (type2) == RECORD_TYPE
411 ? "struct "
412 : TREE_CODE (type2) == UNION_TYPE
413 ? "union " : "", tname,
414 deref_depth == 0 ? "" : " ");
415 while (deref_depth-- > 0)
416 pp_star (&pretty_name);
417 pp_quote (&pretty_name);
419 else if (pstyle == UBSAN_PRINT_ARRAY)
421 /* Pretty print the array dimensions. */
422 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
423 tree t = type;
424 pp_printf (&pretty_name, "'%s ", tname);
425 while (deref_depth-- > 0)
426 pp_star (&pretty_name);
427 while (TREE_CODE (t) == ARRAY_TYPE)
429 pp_left_bracket (&pretty_name);
430 tree dom = TYPE_DOMAIN (t);
431 if (dom != NULL_TREE
432 && TYPE_MAX_VALUE (dom) != NULL_TREE
433 && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
435 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
436 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
437 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
438 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
439 else
440 pp_wide_int (&pretty_name,
441 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
442 TYPE_SIGN (TREE_TYPE (dom)));
444 else
445 /* ??? We can't determine the variable name; print VLA unspec. */
446 pp_star (&pretty_name);
447 pp_right_bracket (&pretty_name);
448 t = TREE_TYPE (t);
450 pp_quote (&pretty_name);
452 /* Save the tree with stripped types. */
453 type = t;
455 else
456 pp_printf (&pretty_name, "'%s'", tname);
458 switch (TREE_CODE (type))
460 case BOOLEAN_TYPE:
461 case ENUMERAL_TYPE:
462 case INTEGER_TYPE:
463 tkind = 0x0000;
464 break;
465 case REAL_TYPE:
466 /* FIXME: libubsan right now only supports float, double and
467 long double type formats. */
468 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
469 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
470 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
471 tkind = 0x0001;
472 else
473 tkind = 0xffff;
474 break;
475 default:
476 tkind = 0xffff;
477 break;
479 tinfo = get_ubsan_type_info_for_type (type);
481 /* Create a new VAR_DECL of type descriptor. */
482 const char *tmp = pp_formatted_text (&pretty_name);
483 size_t len = strlen (tmp) + 1;
484 tree str = build_string (len, tmp);
485 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
486 TREE_READONLY (str) = 1;
487 TREE_STATIC (str) = 1;
489 char tmp_name[32];
490 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
491 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
492 dtype);
493 TREE_STATIC (decl) = 1;
494 TREE_PUBLIC (decl) = 0;
495 DECL_ARTIFICIAL (decl) = 1;
496 DECL_IGNORED_P (decl) = 1;
497 DECL_EXTERNAL (decl) = 0;
498 DECL_SIZE (decl)
499 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
500 DECL_SIZE_UNIT (decl)
501 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
502 TYPE_SIZE_UNIT (TREE_TYPE (str)));
504 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
505 build_int_cst (short_unsigned_type_node,
506 tkind), NULL_TREE,
507 build_int_cst (short_unsigned_type_node,
508 tinfo), NULL_TREE, str);
509 TREE_CONSTANT (ctor) = 1;
510 TREE_STATIC (ctor) = 1;
511 DECL_INITIAL (decl) = ctor;
512 varpool_node::finalize_decl (decl);
514 /* Save the VAR_DECL into the hash table. */
515 decl_for_type_insert (type, decl);
517 return build_fold_addr_expr (decl);
520 /* Create a structure for the ubsan library. NAME is a name of the new
521 structure. LOCCNT is number of locations, PLOC points to array of
522 locations. The arguments in ... are of __ubsan_type_descriptor type
523 and there are at most two of them, followed by NULL_TREE, followed
524 by optional extra arguments and another NULL_TREE. */
526 tree
527 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
529 va_list args;
530 tree ret, t;
531 tree fields[6];
532 vec<tree, va_gc> *saved_args = NULL;
533 size_t i = 0;
534 int j;
536 /* It is possible that PCH zapped table with definitions of sanitizer
537 builtins. Reinitialize them if needed. */
538 initialize_sanitizer_builtins ();
540 /* Firstly, create a pointer to type descriptor type. */
541 tree td_type = ubsan_get_type_descriptor_type ();
542 td_type = build_pointer_type (td_type);
544 /* Create the structure type. */
545 ret = make_node (RECORD_TYPE);
546 for (j = 0; j < loccnt; j++)
548 gcc_checking_assert (i < 2);
549 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
550 ubsan_get_source_location_type ());
551 DECL_CONTEXT (fields[i]) = ret;
552 if (i)
553 DECL_CHAIN (fields[i - 1]) = fields[i];
554 i++;
557 va_start (args, ploc);
558 for (t = va_arg (args, tree); t != NULL_TREE;
559 i++, t = va_arg (args, tree))
561 gcc_checking_assert (i < 4);
562 /* Save the tree arguments for later use. */
563 vec_safe_push (saved_args, t);
564 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
565 td_type);
566 DECL_CONTEXT (fields[i]) = ret;
567 if (i)
568 DECL_CHAIN (fields[i - 1]) = fields[i];
571 for (t = va_arg (args, tree); t != NULL_TREE;
572 i++, t = va_arg (args, tree))
574 gcc_checking_assert (i < 6);
575 /* Save the tree arguments for later use. */
576 vec_safe_push (saved_args, t);
577 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
578 TREE_TYPE (t));
579 DECL_CONTEXT (fields[i]) = ret;
580 if (i)
581 DECL_CHAIN (fields[i - 1]) = fields[i];
583 va_end (args);
585 tree type_decl = build_decl (input_location, TYPE_DECL,
586 get_identifier (name), ret);
587 DECL_IGNORED_P (type_decl) = 1;
588 DECL_ARTIFICIAL (type_decl) = 1;
589 TYPE_FIELDS (ret) = fields[0];
590 TYPE_NAME (ret) = type_decl;
591 TYPE_STUB_DECL (ret) = type_decl;
592 layout_type (ret);
594 /* Now, fill in the type. */
595 char tmp_name[32];
596 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
597 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
598 ret);
599 TREE_STATIC (var) = 1;
600 TREE_PUBLIC (var) = 0;
601 DECL_ARTIFICIAL (var) = 1;
602 DECL_IGNORED_P (var) = 1;
603 DECL_EXTERNAL (var) = 0;
605 vec<constructor_elt, va_gc> *v;
606 vec_alloc (v, i);
607 tree ctor = build_constructor (ret, v);
609 /* If desirable, set the __ubsan_source_location element. */
610 for (j = 0; j < loccnt; j++)
612 location_t loc = LOCATION_LOCUS (ploc[j]);
613 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
616 size_t nelts = vec_safe_length (saved_args);
617 for (i = 0; i < nelts; i++)
619 t = (*saved_args)[i];
620 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
623 TREE_CONSTANT (ctor) = 1;
624 TREE_STATIC (ctor) = 1;
625 DECL_INITIAL (var) = ctor;
626 varpool_node::finalize_decl (var);
628 return var;
631 /* Instrument the __builtin_unreachable call. We just call the libubsan
632 routine instead. */
634 bool
635 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
637 gimple *g;
638 location_t loc = gimple_location (gsi_stmt (*gsi));
640 if (flag_sanitize_undefined_trap_on_error)
641 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
642 else
644 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
645 NULL_TREE, NULL_TREE);
646 data = build_fold_addr_expr_loc (loc, data);
647 tree fn
648 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
649 g = gimple_build_call (fn, 1, data);
651 gimple_set_location (g, loc);
652 gsi_replace (gsi, g, false);
653 return false;
656 /* Return true if T is a call to a libubsan routine. */
658 bool
659 is_ubsan_builtin_p (tree t)
661 return TREE_CODE (t) == FUNCTION_DECL
662 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
663 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
664 "__builtin___ubsan_", 18) == 0;
667 /* Create a callgraph edge for statement STMT. */
669 static void
670 ubsan_create_edge (gimple *stmt)
672 gcall *call_stmt = dyn_cast <gcall *> (stmt);
673 basic_block bb = gimple_bb (stmt);
674 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
675 cgraph_node *node = cgraph_node::get (current_function_decl);
676 tree decl = gimple_call_fndecl (call_stmt);
677 if (decl)
678 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
679 freq);
682 /* Expand the UBSAN_BOUNDS special builtin function. */
684 bool
685 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
687 gimple *stmt = gsi_stmt (*gsi);
688 location_t loc = gimple_location (stmt);
689 gcc_assert (gimple_call_num_args (stmt) == 3);
691 /* Pick up the arguments of the UBSAN_BOUNDS call. */
692 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
693 tree index = gimple_call_arg (stmt, 1);
694 tree orig_index = index;
695 tree bound = gimple_call_arg (stmt, 2);
697 gimple_stmt_iterator gsi_orig = *gsi;
699 /* Create condition "if (index > bound)". */
700 basic_block then_bb, fallthru_bb;
701 gimple_stmt_iterator cond_insert_point
702 = create_cond_insert_point (gsi, false, false, true,
703 &then_bb, &fallthru_bb);
704 index = fold_convert (TREE_TYPE (bound), index);
705 index = force_gimple_operand_gsi (&cond_insert_point, index,
706 true, NULL_TREE,
707 false, GSI_NEW_STMT);
708 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
709 gimple_set_location (g, loc);
710 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
712 /* Generate __ubsan_handle_out_of_bounds call. */
713 *gsi = gsi_after_labels (then_bb);
714 if (flag_sanitize_undefined_trap_on_error)
715 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
716 else
718 tree data
719 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
720 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
721 ubsan_type_descriptor (TREE_TYPE (orig_index)),
722 NULL_TREE, NULL_TREE);
723 data = build_fold_addr_expr_loc (loc, data);
724 enum built_in_function bcode
725 = (flag_sanitize_recover & SANITIZE_BOUNDS)
726 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
727 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
728 tree fn = builtin_decl_explicit (bcode);
729 tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE);
730 val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true,
731 GSI_SAME_STMT);
732 g = gimple_build_call (fn, 2, data, val);
734 gimple_set_location (g, loc);
735 gsi_insert_before (gsi, g, GSI_SAME_STMT);
737 /* Get rid of the UBSAN_BOUNDS call from the IR. */
738 unlink_stmt_vdef (stmt);
739 gsi_remove (&gsi_orig, true);
741 /* Point GSI to next logical statement. */
742 *gsi = gsi_start_bb (fallthru_bb);
743 return true;
746 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
747 argument which is a constant, because the middle-end treats pointer
748 conversions as useless and therefore the type of the first argument
749 could be changed to any other pointer type. */
751 bool
752 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
754 gimple_stmt_iterator gsi = *gsip;
755 gimple *stmt = gsi_stmt (gsi);
756 location_t loc = gimple_location (stmt);
757 gcc_assert (gimple_call_num_args (stmt) == 3);
758 tree ptr = gimple_call_arg (stmt, 0);
759 tree ckind = gimple_call_arg (stmt, 1);
760 tree align = gimple_call_arg (stmt, 2);
761 tree check_align = NULL_TREE;
762 bool check_null;
764 basic_block cur_bb = gsi_bb (gsi);
766 gimple *g;
767 if (!integer_zerop (align))
769 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
770 if (compare_tree_int (align, ptralign) == 1)
772 check_align = make_ssa_name (pointer_sized_int_node);
773 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
774 gimple_set_location (g, loc);
775 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
778 check_null = sanitize_flags_p (SANITIZE_NULL);
780 if (check_align == NULL_TREE && !check_null)
782 gsi_remove (gsip, true);
783 /* Unlink the UBSAN_NULLs vops before replacing it. */
784 unlink_stmt_vdef (stmt);
785 return true;
788 /* Split the original block holding the pointer dereference. */
789 edge e = split_block (cur_bb, stmt);
791 /* Get a hold on the 'condition block', the 'then block' and the
792 'else block'. */
793 basic_block cond_bb = e->src;
794 basic_block fallthru_bb = e->dest;
795 basic_block then_bb = create_empty_bb (cond_bb);
796 add_bb_to_loop (then_bb, cond_bb->loop_father);
797 loops_state_set (LOOPS_NEED_FIXUP);
799 /* Make an edge coming from the 'cond block' into the 'then block';
800 this edge is unlikely taken, so set up the probability accordingly. */
801 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
802 e->probability = PROB_VERY_UNLIKELY;
804 /* Connect 'then block' with the 'else block'. This is needed
805 as the ubsan routines we call in the 'then block' are not noreturn.
806 The 'then block' only has one outcoming edge. */
807 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
809 /* Set up the fallthrough basic block. */
810 e = find_edge (cond_bb, fallthru_bb);
811 e->flags = EDGE_FALSE_VALUE;
812 e->count = cond_bb->count;
813 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
815 /* Update dominance info for the newly created then_bb; note that
816 fallthru_bb's dominance info has already been updated by
817 split_block. */
818 if (dom_info_available_p (CDI_DOMINATORS))
819 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
821 /* Put the ubsan builtin call into the newly created BB. */
822 if (flag_sanitize_undefined_trap_on_error)
823 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
824 else
826 enum built_in_function bcode
827 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
828 | (check_null ? SANITIZE_NULL : 0)))
829 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
830 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
831 tree fn = builtin_decl_implicit (bcode);
832 tree data
833 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
834 ubsan_type_descriptor (TREE_TYPE (ckind),
835 UBSAN_PRINT_POINTER),
836 NULL_TREE,
837 align,
838 fold_convert (unsigned_char_type_node, ckind),
839 NULL_TREE);
840 data = build_fold_addr_expr_loc (loc, data);
841 g = gimple_build_call (fn, 2, data,
842 check_align ? check_align
843 : build_zero_cst (pointer_sized_int_node));
845 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
846 gimple_set_location (g, loc);
847 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
849 /* Unlink the UBSAN_NULLs vops before replacing it. */
850 unlink_stmt_vdef (stmt);
852 if (check_null)
854 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
855 NULL_TREE, NULL_TREE);
856 gimple_set_location (g, loc);
858 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
859 gsi_replace (&gsi, g, false);
860 stmt = g;
863 if (check_align)
865 if (check_null)
867 /* Split the block with the condition again. */
868 e = split_block (cond_bb, stmt);
869 basic_block cond1_bb = e->src;
870 basic_block cond2_bb = e->dest;
872 /* Make an edge coming from the 'cond1 block' into the 'then block';
873 this edge is unlikely taken, so set up the probability
874 accordingly. */
875 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
876 e->probability = PROB_VERY_UNLIKELY;
878 /* Set up the fallthrough basic block. */
879 e = find_edge (cond1_bb, cond2_bb);
880 e->flags = EDGE_FALSE_VALUE;
881 e->count = cond1_bb->count;
882 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
884 /* Update dominance info. */
885 if (dom_info_available_p (CDI_DOMINATORS))
887 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
888 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
891 gsi2 = gsi_start_bb (cond2_bb);
894 tree mask = build_int_cst (pointer_sized_int_node,
895 tree_to_uhwi (align) - 1);
896 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
897 BIT_AND_EXPR, check_align, mask);
898 gimple_set_location (g, loc);
899 if (check_null)
900 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
901 else
902 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
904 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
905 build_int_cst (pointer_sized_int_node, 0),
906 NULL_TREE, NULL_TREE);
907 gimple_set_location (g, loc);
908 if (check_null)
909 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
910 else
911 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
912 gsi_replace (&gsi, g, false);
914 return false;
917 #define OBJSZ_MAX_OFFSET (1024 * 16)
919 /* Expand UBSAN_OBJECT_SIZE internal call. */
921 bool
922 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
924 gimple *stmt = gsi_stmt (*gsi);
925 location_t loc = gimple_location (stmt);
926 gcc_assert (gimple_call_num_args (stmt) == 4);
928 tree ptr = gimple_call_arg (stmt, 0);
929 tree offset = gimple_call_arg (stmt, 1);
930 tree size = gimple_call_arg (stmt, 2);
931 tree ckind = gimple_call_arg (stmt, 3);
932 gimple_stmt_iterator gsi_orig = *gsi;
933 gimple *g;
935 /* See if we can discard the check. */
936 if (TREE_CODE (size) != INTEGER_CST
937 || integer_all_onesp (size))
938 /* Yes, __builtin_object_size couldn't determine the
939 object size. */;
940 else if (TREE_CODE (offset) == INTEGER_CST
941 && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
942 && wi::to_widest (offset) <= -1)
943 /* The offset is in range [-16K, -1]. */;
944 else
946 /* if (offset > objsize) */
947 basic_block then_bb, fallthru_bb;
948 gimple_stmt_iterator cond_insert_point
949 = create_cond_insert_point (gsi, false, false, true,
950 &then_bb, &fallthru_bb);
951 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
952 gimple_set_location (g, loc);
953 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
955 /* If the offset is small enough, we don't need the second
956 run-time check. */
957 if (TREE_CODE (offset) == INTEGER_CST
958 && wi::to_widest (offset) >= 0
959 && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
960 *gsi = gsi_after_labels (then_bb);
961 else
963 /* Don't issue run-time error if (ptr > ptr + offset). That
964 may happen when computing a POINTER_PLUS_EXPR. */
965 basic_block then2_bb, fallthru2_bb;
967 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
968 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
969 true, &then2_bb,
970 &fallthru2_bb);
971 /* Convert the pointer to an integer type. */
972 tree p = make_ssa_name (pointer_sized_int_node);
973 g = gimple_build_assign (p, NOP_EXPR, ptr);
974 gimple_set_location (g, loc);
975 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
976 p = gimple_assign_lhs (g);
977 /* Compute ptr + offset. */
978 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
979 PLUS_EXPR, p, offset);
980 gimple_set_location (g, loc);
981 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
982 /* Now build the conditional and put it into the IR. */
983 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
984 NULL_TREE, NULL_TREE);
985 gimple_set_location (g, loc);
986 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
987 *gsi = gsi_after_labels (then2_bb);
990 /* Generate __ubsan_handle_type_mismatch call. */
991 if (flag_sanitize_undefined_trap_on_error)
992 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
993 else
995 tree data
996 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
997 ubsan_type_descriptor (TREE_TYPE (ptr),
998 UBSAN_PRINT_POINTER),
999 NULL_TREE,
1000 build_zero_cst (pointer_sized_int_node),
1001 ckind,
1002 NULL_TREE);
1003 data = build_fold_addr_expr_loc (loc, data);
1004 enum built_in_function bcode
1005 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1006 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1007 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
1008 tree p = make_ssa_name (pointer_sized_int_node);
1009 g = gimple_build_assign (p, NOP_EXPR, ptr);
1010 gimple_set_location (g, loc);
1011 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1012 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1014 gimple_set_location (g, loc);
1015 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1017 /* Point GSI to next logical statement. */
1018 *gsi = gsi_start_bb (fallthru_bb);
1020 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1021 unlink_stmt_vdef (stmt);
1022 gsi_remove (&gsi_orig, true);
1023 return true;
1026 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1027 unlink_stmt_vdef (stmt);
1028 gsi_remove (gsi, true);
1029 return true;
1032 /* Cached __ubsan_vptr_type_cache decl. */
1033 static GTY(()) tree ubsan_vptr_type_cache_decl;
1035 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1036 argument which is a constant, because the middle-end treats pointer
1037 conversions as useless and therefore the type of the first argument
1038 could be changed to any other pointer type. */
1040 bool
1041 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1043 gimple_stmt_iterator gsi = *gsip;
1044 gimple *stmt = gsi_stmt (gsi);
1045 location_t loc = gimple_location (stmt);
1046 gcc_assert (gimple_call_num_args (stmt) == 5);
1047 tree op = gimple_call_arg (stmt, 0);
1048 tree vptr = gimple_call_arg (stmt, 1);
1049 tree str_hash = gimple_call_arg (stmt, 2);
1050 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1051 tree ckind_tree = gimple_call_arg (stmt, 4);
1052 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1053 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1054 gimple *g;
1055 basic_block fallthru_bb = NULL;
1057 if (ckind == UBSAN_DOWNCAST_POINTER)
1059 /* Guard everything with if (op != NULL) { ... }. */
1060 basic_block then_bb;
1061 gimple_stmt_iterator cond_insert_point
1062 = create_cond_insert_point (gsip, false, false, true,
1063 &then_bb, &fallthru_bb);
1064 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1065 NULL_TREE, NULL_TREE);
1066 gimple_set_location (g, loc);
1067 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1068 *gsip = gsi_after_labels (then_bb);
1069 gsi_remove (&gsi, false);
1070 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1071 gsi = *gsip;
1074 tree htype = TREE_TYPE (str_hash);
1075 tree cst = wide_int_to_tree (htype,
1076 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1077 | 0xeb382d69, 64));
1078 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1079 vptr, str_hash);
1080 gimple_set_location (g, loc);
1081 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1082 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1083 gimple_assign_lhs (g), cst);
1084 gimple_set_location (g, loc);
1085 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1086 tree t1 = gimple_assign_lhs (g);
1087 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1088 t1, build_int_cst (integer_type_node, 47));
1089 gimple_set_location (g, loc);
1090 tree t2 = gimple_assign_lhs (g);
1091 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1092 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1093 vptr, t1);
1094 gimple_set_location (g, loc);
1095 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1096 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1097 t2, gimple_assign_lhs (g));
1098 gimple_set_location (g, loc);
1099 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1100 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1101 gimple_assign_lhs (g), cst);
1102 gimple_set_location (g, loc);
1103 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1104 tree t3 = gimple_assign_lhs (g);
1105 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1106 t3, build_int_cst (integer_type_node, 47));
1107 gimple_set_location (g, loc);
1108 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1109 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1110 t3, gimple_assign_lhs (g));
1111 gimple_set_location (g, loc);
1112 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1113 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1114 gimple_assign_lhs (g), cst);
1115 gimple_set_location (g, loc);
1116 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1117 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1119 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1120 NOP_EXPR, gimple_assign_lhs (g));
1121 gimple_set_location (g, loc);
1122 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1124 tree hash = gimple_assign_lhs (g);
1126 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1128 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1129 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1130 get_identifier ("__ubsan_vptr_type_cache"),
1131 atype);
1132 DECL_ARTIFICIAL (array) = 1;
1133 DECL_IGNORED_P (array) = 1;
1134 TREE_PUBLIC (array) = 1;
1135 TREE_STATIC (array) = 1;
1136 DECL_EXTERNAL (array) = 1;
1137 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1138 DECL_VISIBILITY_SPECIFIED (array) = 1;
1139 varpool_node::finalize_decl (array);
1140 ubsan_vptr_type_cache_decl = array;
1143 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1144 BIT_AND_EXPR, hash,
1145 build_int_cst (pointer_sized_int_node, 127));
1146 gimple_set_location (g, loc);
1147 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1149 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1150 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1151 NULL_TREE, NULL_TREE);
1152 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1153 ARRAY_REF, c);
1154 gimple_set_location (g, loc);
1155 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1157 basic_block then_bb, fallthru2_bb;
1158 gimple_stmt_iterator cond_insert_point
1159 = create_cond_insert_point (gsip, false, false, true,
1160 &then_bb, &fallthru2_bb);
1161 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1162 NULL_TREE, NULL_TREE);
1163 gimple_set_location (g, loc);
1164 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1165 *gsip = gsi_after_labels (then_bb);
1166 if (fallthru_bb == NULL)
1167 fallthru_bb = fallthru2_bb;
1169 tree data
1170 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1171 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1172 build_int_cst (unsigned_char_type_node, ckind),
1173 NULL_TREE);
1174 data = build_fold_addr_expr_loc (loc, data);
1175 enum built_in_function bcode
1176 = (flag_sanitize_recover & SANITIZE_VPTR)
1177 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1178 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1180 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1181 gimple_set_location (g, loc);
1182 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1184 /* Point GSI to next logical statement. */
1185 *gsip = gsi_start_bb (fallthru_bb);
1187 /* Get rid of the UBSAN_VPTR call from the IR. */
1188 unlink_stmt_vdef (stmt);
1189 gsi_remove (&gsi, true);
1190 return true;
1193 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1194 whether the pointer is on the left hand side of the assignment. */
1196 static void
1197 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1198 bool is_lhs)
1200 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1201 unsigned int align = 0;
1202 if (sanitize_flags_p (SANITIZE_ALIGNMENT))
1204 align = min_align_of_type (TREE_TYPE (base));
1205 if (align <= 1)
1206 align = 0;
1208 if (align == 0 && !sanitize_flags_p (SANITIZE_NULL))
1209 return;
1210 tree t = TREE_OPERAND (base, 0);
1211 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1212 return;
1213 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1214 ikind = UBSAN_MEMBER_ACCESS;
1215 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1216 tree alignt = build_int_cst (pointer_sized_int_node, align);
1217 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1218 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1219 gsi_insert_before (iter, g, GSI_SAME_STMT);
1222 /* Perform the pointer instrumentation. */
1224 static void
1225 instrument_null (gimple_stmt_iterator gsi, tree t, bool is_lhs)
1227 /* Handle also e.g. &s->i. */
1228 if (TREE_CODE (t) == ADDR_EXPR)
1229 t = TREE_OPERAND (t, 0);
1230 tree base = get_base_address (t);
1231 if (base != NULL_TREE
1232 && TREE_CODE (base) == 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
1378 && sanitize_flags_p (SANITIZE_BOOL))
1380 minv = boolean_false_node;
1381 maxv = boolean_true_node;
1383 else if (TREE_CODE (type) == ENUMERAL_TYPE
1384 && sanitize_flags_p (SANITIZE_ENUM)
1385 && TREE_TYPE (type) != NULL_TREE
1386 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1387 && (TYPE_PRECISION (TREE_TYPE (type))
1388 < GET_MODE_PRECISION (TYPE_MODE (type))))
1390 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1391 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1393 else
1394 return;
1396 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1397 HOST_WIDE_INT bitsize, bitpos;
1398 tree offset;
1399 machine_mode mode;
1400 int volatilep = 0, reversep, unsignedp = 0;
1401 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1402 &unsignedp, &reversep, &volatilep);
1403 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1405 if ((VAR_P (base) && DECL_HARD_REGISTER (base))
1406 || (bitpos % modebitsize) != 0
1407 || bitsize != modebitsize
1408 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1409 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1410 return;
1412 bool ends_bb = stmt_ends_bb_p (stmt);
1413 location_t loc = gimple_location (stmt);
1414 tree lhs = gimple_assign_lhs (stmt);
1415 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1416 tree atype = reference_alias_ptr_type (rhs);
1417 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1418 build_fold_addr_expr (rhs));
1419 gimple_set_location (g, loc);
1420 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1421 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1422 build_int_cst (atype, 0));
1423 tree urhs = make_ssa_name (utype);
1424 if (ends_bb)
1426 gimple_assign_set_lhs (stmt, urhs);
1427 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1428 gimple_set_location (g, loc);
1429 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1430 gsi_insert_on_edge_immediate (e, g);
1431 gimple_assign_set_rhs_from_tree (gsi, mem);
1432 update_stmt (stmt);
1433 *gsi = gsi_for_stmt (g);
1434 g = stmt;
1436 else
1438 g = gimple_build_assign (urhs, mem);
1439 gimple_set_location (g, loc);
1440 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1442 minv = fold_convert (utype, minv);
1443 maxv = fold_convert (utype, maxv);
1444 if (!integer_zerop (minv))
1446 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1447 gimple_set_location (g, loc);
1448 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1451 gimple_stmt_iterator gsi2 = *gsi;
1452 basic_block then_bb, fallthru_bb;
1453 *gsi = create_cond_insert_point (gsi, true, false, true,
1454 &then_bb, &fallthru_bb);
1455 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1456 int_const_binop (MINUS_EXPR, maxv, minv),
1457 NULL_TREE, NULL_TREE);
1458 gimple_set_location (g, loc);
1459 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1461 if (!ends_bb)
1463 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1464 update_stmt (stmt);
1467 gsi2 = gsi_after_labels (then_bb);
1468 if (flag_sanitize_undefined_trap_on_error)
1469 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1470 else
1472 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1473 ubsan_type_descriptor (type), NULL_TREE,
1474 NULL_TREE);
1475 data = build_fold_addr_expr_loc (loc, data);
1476 enum built_in_function bcode
1477 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1478 ? SANITIZE_BOOL : SANITIZE_ENUM))
1479 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1480 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1481 tree fn = builtin_decl_explicit (bcode);
1483 tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE);
1484 val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true,
1485 GSI_SAME_STMT);
1486 g = gimple_build_call (fn, 2, data, val);
1488 gimple_set_location (g, loc);
1489 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1490 ubsan_create_edge (g);
1491 *gsi = gsi_for_stmt (stmt);
1494 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1495 new style handlers. Libubsan uses heuristics to destinguish between old and
1496 new styles and relies on these properties for filename:
1498 a) Location's filename must not be NULL.
1499 b) Location's filename must not be equal to "".
1500 c) Location's filename must not be equal to "\1".
1501 d) First two bytes of filename must not contain '\xff' symbol. */
1503 static bool
1504 ubsan_use_new_style_p (location_t loc)
1506 if (loc == UNKNOWN_LOCATION)
1507 return false;
1509 expanded_location xloc = expand_location (loc);
1510 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1511 || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1512 || xloc.file[1] == '\xff')
1513 return false;
1515 return true;
1518 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1519 destination, EXPR is floating-point expression. */
1521 tree
1522 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1524 tree expr_type = TREE_TYPE (expr);
1525 tree t, tt, fn, min, max;
1526 machine_mode mode = TYPE_MODE (expr_type);
1527 int prec = TYPE_PRECISION (type);
1528 bool uns_p = TYPE_UNSIGNED (type);
1529 if (loc == UNKNOWN_LOCATION)
1530 loc = input_location;
1532 /* Float to integer conversion first truncates toward zero, so
1533 even signed char c = 127.875f; is not problematic.
1534 Therefore, we should complain only if EXPR is unordered or smaller
1535 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1536 TYPE_MAX_VALUE + 1.0. */
1537 if (REAL_MODE_FORMAT (mode)->b == 2)
1539 /* For maximum, TYPE_MAX_VALUE might not be representable
1540 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1541 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1542 either representable or infinity. */
1543 REAL_VALUE_TYPE maxval = dconst1;
1544 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1545 real_convert (&maxval, mode, &maxval);
1546 max = build_real (expr_type, maxval);
1548 /* For unsigned, assume -1.0 is always representable. */
1549 if (uns_p)
1550 min = build_minus_one_cst (expr_type);
1551 else
1553 /* TYPE_MIN_VALUE is generally representable (or -inf),
1554 but TYPE_MIN_VALUE - 1.0 might not be. */
1555 REAL_VALUE_TYPE minval = dconstm1, minval2;
1556 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1557 real_convert (&minval, mode, &minval);
1558 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1559 real_convert (&minval2, mode, &minval2);
1560 if (real_compare (EQ_EXPR, &minval, &minval2)
1561 && !real_isinf (&minval))
1563 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1564 rounds to TYPE_MIN_VALUE, we need to subtract
1565 more. As REAL_MODE_FORMAT (mode)->p is the number
1566 of base digits, we want to subtract a number that
1567 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1568 times smaller than minval. */
1569 minval2 = dconst1;
1570 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1571 SET_REAL_EXP (&minval2,
1572 REAL_EXP (&minval2) + prec - 1
1573 - REAL_MODE_FORMAT (mode)->p + 1);
1574 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1575 real_convert (&minval2, mode, &minval2);
1577 min = build_real (expr_type, minval2);
1580 else if (REAL_MODE_FORMAT (mode)->b == 10)
1582 /* For _Decimal128 up to 34 decimal digits, - sign,
1583 dot, e, exponent. */
1584 char buf[64];
1585 mpfr_t m;
1586 int p = REAL_MODE_FORMAT (mode)->p;
1587 REAL_VALUE_TYPE maxval, minval;
1589 /* Use mpfr_snprintf rounding to compute the smallest
1590 representable decimal number greater or equal than
1591 1 << (prec - !uns_p). */
1592 mpfr_init2 (m, prec + 2);
1593 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1594 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1595 decimal_real_from_string (&maxval, buf);
1596 max = build_real (expr_type, maxval);
1598 /* For unsigned, assume -1.0 is always representable. */
1599 if (uns_p)
1600 min = build_minus_one_cst (expr_type);
1601 else
1603 /* Use mpfr_snprintf rounding to compute the largest
1604 representable decimal number less or equal than
1605 (-1 << (prec - 1)) - 1. */
1606 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1607 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1608 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1609 decimal_real_from_string (&minval, buf);
1610 min = build_real (expr_type, minval);
1612 mpfr_clear (m);
1614 else
1615 return NULL_TREE;
1617 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1618 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1619 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1620 if (integer_zerop (t))
1621 return NULL_TREE;
1623 if (flag_sanitize_undefined_trap_on_error)
1624 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1625 else
1627 location_t *loc_ptr = NULL;
1628 unsigned num_locations = 0;
1629 /* Figure out if we can propagate location to ubsan_data and use new
1630 style handlers in libubsan. */
1631 if (ubsan_use_new_style_p (loc))
1633 loc_ptr = &loc;
1634 num_locations = 1;
1636 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1637 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1638 num_locations, loc_ptr,
1639 ubsan_type_descriptor (expr_type),
1640 ubsan_type_descriptor (type), NULL_TREE,
1641 NULL_TREE);
1642 enum built_in_function bcode
1643 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1644 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1645 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1646 fn = builtin_decl_explicit (bcode);
1647 fn = build_call_expr_loc (loc, fn, 2,
1648 build_fold_addr_expr_loc (loc, data),
1649 ubsan_encode_value (expr));
1652 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1655 /* Instrument values passed to function arguments with nonnull attribute. */
1657 static void
1658 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1660 gimple *stmt = gsi_stmt (*gsi);
1661 location_t loc[2];
1662 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1663 while for nonnull sanitization it is clear. */
1664 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1665 flag_delete_null_pointer_checks = 1;
1666 loc[0] = gimple_location (stmt);
1667 loc[1] = UNKNOWN_LOCATION;
1668 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1670 tree arg = gimple_call_arg (stmt, i);
1671 if (POINTER_TYPE_P (TREE_TYPE (arg))
1672 && infer_nonnull_range_by_attribute (stmt, arg))
1674 gimple *g;
1675 if (!is_gimple_val (arg))
1677 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1678 gimple_set_location (g, loc[0]);
1679 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1680 arg = gimple_assign_lhs (g);
1683 basic_block then_bb, fallthru_bb;
1684 *gsi = create_cond_insert_point (gsi, true, false, true,
1685 &then_bb, &fallthru_bb);
1686 g = gimple_build_cond (EQ_EXPR, arg,
1687 build_zero_cst (TREE_TYPE (arg)),
1688 NULL_TREE, NULL_TREE);
1689 gimple_set_location (g, loc[0]);
1690 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1692 *gsi = gsi_after_labels (then_bb);
1693 if (flag_sanitize_undefined_trap_on_error)
1694 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1695 else
1697 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1698 2, loc, NULL_TREE,
1699 build_int_cst (integer_type_node,
1700 i + 1),
1701 NULL_TREE);
1702 data = build_fold_addr_expr_loc (loc[0], data);
1703 enum built_in_function bcode
1704 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1705 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1706 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1707 tree fn = builtin_decl_explicit (bcode);
1709 g = gimple_build_call (fn, 1, data);
1711 gimple_set_location (g, loc[0]);
1712 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1713 ubsan_create_edge (g);
1715 *gsi = gsi_for_stmt (stmt);
1717 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1720 /* Instrument returns in functions with returns_nonnull attribute. */
1722 static void
1723 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1725 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1726 location_t loc[2];
1727 tree arg = gimple_return_retval (stmt);
1728 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1729 while for nonnull return sanitization it is clear. */
1730 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1731 flag_delete_null_pointer_checks = 1;
1732 loc[0] = gimple_location (stmt);
1733 loc[1] = UNKNOWN_LOCATION;
1734 if (arg
1735 && POINTER_TYPE_P (TREE_TYPE (arg))
1736 && is_gimple_val (arg)
1737 && infer_nonnull_range_by_attribute (stmt, arg))
1739 basic_block then_bb, fallthru_bb;
1740 *gsi = create_cond_insert_point (gsi, true, false, true,
1741 &then_bb, &fallthru_bb);
1742 gimple *g = gimple_build_cond (EQ_EXPR, arg,
1743 build_zero_cst (TREE_TYPE (arg)),
1744 NULL_TREE, NULL_TREE);
1745 gimple_set_location (g, loc[0]);
1746 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1748 *gsi = gsi_after_labels (then_bb);
1749 if (flag_sanitize_undefined_trap_on_error)
1750 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1751 else
1753 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1754 2, loc, NULL_TREE, NULL_TREE);
1755 data = build_fold_addr_expr_loc (loc[0], data);
1756 enum built_in_function bcode
1757 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1758 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1759 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1760 tree fn = builtin_decl_explicit (bcode);
1762 g = gimple_build_call (fn, 1, data);
1764 gimple_set_location (g, loc[0]);
1765 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1766 ubsan_create_edge (g);
1767 *gsi = gsi_for_stmt (stmt);
1769 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1772 /* Instrument memory references. Here we check whether the pointer
1773 points to an out-of-bounds location. */
1775 static void
1776 instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
1778 gimple *stmt = gsi_stmt (*gsi);
1779 location_t loc = gimple_location (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 namespace {
1948 const pass_data pass_data_ubsan =
1950 GIMPLE_PASS, /* type */
1951 "ubsan", /* name */
1952 OPTGROUP_NONE, /* optinfo_flags */
1953 TV_TREE_UBSAN, /* tv_id */
1954 ( PROP_cfg | PROP_ssa ), /* properties_required */
1955 0, /* properties_provided */
1956 0, /* properties_destroyed */
1957 0, /* todo_flags_start */
1958 TODO_update_ssa, /* todo_flags_finish */
1961 class pass_ubsan : public gimple_opt_pass
1963 public:
1964 pass_ubsan (gcc::context *ctxt)
1965 : gimple_opt_pass (pass_data_ubsan, ctxt)
1968 /* opt_pass methods: */
1969 virtual bool gate (function *)
1971 return sanitize_flags_p ((SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1972 | SANITIZE_BOOL | SANITIZE_ENUM
1973 | SANITIZE_ALIGNMENT
1974 | SANITIZE_NONNULL_ATTRIBUTE
1975 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1976 | SANITIZE_OBJECT_SIZE));
1979 virtual unsigned int execute (function *);
1981 }; // class pass_ubsan
1983 unsigned int
1984 pass_ubsan::execute (function *fun)
1986 basic_block bb;
1987 gimple_stmt_iterator gsi;
1988 unsigned int ret = 0;
1990 initialize_sanitizer_builtins ();
1992 FOR_EACH_BB_FN (bb, fun)
1994 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1996 gimple *stmt = gsi_stmt (gsi);
1997 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1999 gsi_next (&gsi);
2000 continue;
2003 if ((sanitize_flags_p (SANITIZE_SI_OVERFLOW, fun->decl))
2004 && is_gimple_assign (stmt))
2005 instrument_si_overflow (gsi);
2007 if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT, fun->decl))
2009 if (gimple_store_p (stmt))
2010 instrument_null (gsi, gimple_get_lhs (stmt), true);
2011 if (gimple_assign_single_p (stmt))
2012 instrument_null (gsi, gimple_assign_rhs1 (stmt), false);
2013 if (is_gimple_call (stmt))
2015 unsigned args_num = gimple_call_num_args (stmt);
2016 for (unsigned i = 0; i < args_num; ++i)
2018 tree arg = gimple_call_arg (stmt, i);
2019 if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2020 continue;
2021 instrument_null (gsi, arg, false);
2026 if (sanitize_flags_p (SANITIZE_BOOL | SANITIZE_ENUM, fun->decl)
2027 && gimple_assign_load_p (stmt))
2029 instrument_bool_enum_load (&gsi);
2030 bb = gimple_bb (stmt);
2033 if (sanitize_flags_p (SANITIZE_NONNULL_ATTRIBUTE, fun->decl)
2034 && is_gimple_call (stmt)
2035 && !gimple_call_internal_p (stmt))
2037 instrument_nonnull_arg (&gsi);
2038 bb = gimple_bb (stmt);
2041 if (sanitize_flags_p (SANITIZE_RETURNS_NONNULL_ATTRIBUTE, fun->decl)
2042 && gimple_code (stmt) == GIMPLE_RETURN)
2044 instrument_nonnull_return (&gsi);
2045 bb = gimple_bb (stmt);
2048 if (sanitize_flags_p (SANITIZE_OBJECT_SIZE, fun->decl))
2050 if (gimple_store_p (stmt))
2051 instrument_object_size (&gsi, gimple_get_lhs (stmt), true);
2052 if (gimple_assign_load_p (stmt))
2053 instrument_object_size (&gsi, gimple_assign_rhs1 (stmt),
2054 false);
2055 if (is_gimple_call (stmt))
2057 unsigned args_num = gimple_call_num_args (stmt);
2058 for (unsigned i = 0; i < args_num; ++i)
2060 tree arg = gimple_call_arg (stmt, i);
2061 if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2062 continue;
2063 instrument_object_size (&gsi, arg, false);
2068 gsi_next (&gsi);
2070 if (gimple_purge_dead_eh_edges (bb))
2071 ret = TODO_cleanup_cfg;
2073 return ret;
2076 } // anon namespace
2078 gimple_opt_pass *
2079 make_pass_ubsan (gcc::context *ctxt)
2081 return new pass_ubsan (ctxt);
2084 #include "gt-ubsan.h"