runtime: complete defer handling in CgocallBackDone
[official-gcc.git] / gcc / ubsan.c
blob44effdd22166d0b35fa95a71dd40a0eb89990bf3
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;
157 if (phase == UBSAN_ENCODE_VALUE_RTL)
159 rtx mem
160 = assign_stack_temp_for_type (TYPE_MODE (type),
161 GET_MODE_SIZE (TYPE_MODE (type)),
162 type);
163 SET_DECL_RTL (var, mem);
164 expand_assignment (var, t, false);
165 return build_fold_addr_expr (var);
167 if (phase != UBSAN_ENCODE_VALUE_GENERIC)
169 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
170 t = build_fold_addr_expr (var);
171 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
173 else
175 var = build4 (TARGET_EXPR, type, var, t, NULL_TREE, NULL_TREE);
176 return build_fold_addr_expr (var);
179 else
180 return build_fold_addr_expr (t);
184 /* Cached ubsan_get_type_descriptor_type () return value. */
185 static GTY(()) tree ubsan_type_descriptor_type;
187 /* Build
188 struct __ubsan_type_descriptor
190 unsigned short __typekind;
191 unsigned short __typeinfo;
192 char __typename[];
194 type. */
196 static tree
197 ubsan_get_type_descriptor_type (void)
199 static const char *field_names[3]
200 = { "__typekind", "__typeinfo", "__typename" };
201 tree fields[3], ret;
203 if (ubsan_type_descriptor_type)
204 return ubsan_type_descriptor_type;
206 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
207 tree flex_arr_type = build_array_type (char_type_node, itype);
209 ret = make_node (RECORD_TYPE);
210 for (int i = 0; i < 3; i++)
212 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
213 get_identifier (field_names[i]),
214 (i == 2) ? flex_arr_type
215 : short_unsigned_type_node);
216 DECL_CONTEXT (fields[i]) = ret;
217 if (i)
218 DECL_CHAIN (fields[i - 1]) = fields[i];
220 tree type_decl = build_decl (input_location, TYPE_DECL,
221 get_identifier ("__ubsan_type_descriptor"),
222 ret);
223 DECL_IGNORED_P (type_decl) = 1;
224 DECL_ARTIFICIAL (type_decl) = 1;
225 TYPE_FIELDS (ret) = fields[0];
226 TYPE_NAME (ret) = type_decl;
227 TYPE_STUB_DECL (ret) = type_decl;
228 layout_type (ret);
229 ubsan_type_descriptor_type = ret;
230 return ret;
233 /* Cached ubsan_get_source_location_type () return value. */
234 static GTY(()) tree ubsan_source_location_type;
236 /* Build
237 struct __ubsan_source_location
239 const char *__filename;
240 unsigned int __line;
241 unsigned int __column;
243 type. */
245 tree
246 ubsan_get_source_location_type (void)
248 static const char *field_names[3]
249 = { "__filename", "__line", "__column" };
250 tree fields[3], ret;
251 if (ubsan_source_location_type)
252 return ubsan_source_location_type;
254 tree const_char_type = build_qualified_type (char_type_node,
255 TYPE_QUAL_CONST);
257 ret = make_node (RECORD_TYPE);
258 for (int i = 0; i < 3; i++)
260 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
261 get_identifier (field_names[i]),
262 (i == 0) ? build_pointer_type (const_char_type)
263 : unsigned_type_node);
264 DECL_CONTEXT (fields[i]) = ret;
265 if (i)
266 DECL_CHAIN (fields[i - 1]) = fields[i];
268 tree type_decl = build_decl (input_location, TYPE_DECL,
269 get_identifier ("__ubsan_source_location"),
270 ret);
271 DECL_IGNORED_P (type_decl) = 1;
272 DECL_ARTIFICIAL (type_decl) = 1;
273 TYPE_FIELDS (ret) = fields[0];
274 TYPE_NAME (ret) = type_decl;
275 TYPE_STUB_DECL (ret) = type_decl;
276 layout_type (ret);
277 ubsan_source_location_type = ret;
278 return ret;
281 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
282 type with its fields filled from a location_t LOC. */
284 static tree
285 ubsan_source_location (location_t loc)
287 expanded_location xloc;
288 tree type = ubsan_get_source_location_type ();
290 xloc = expand_location (loc);
291 tree str;
292 if (xloc.file == NULL)
294 str = build_int_cst (ptr_type_node, 0);
295 xloc.line = 0;
296 xloc.column = 0;
298 else
300 /* Fill in the values from LOC. */
301 size_t len = strlen (xloc.file) + 1;
302 str = build_string (len, xloc.file);
303 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
304 TREE_READONLY (str) = 1;
305 TREE_STATIC (str) = 1;
306 str = build_fold_addr_expr (str);
308 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
309 build_int_cst (unsigned_type_node,
310 xloc.line), NULL_TREE,
311 build_int_cst (unsigned_type_node,
312 xloc.column));
313 TREE_CONSTANT (ctor) = 1;
314 TREE_STATIC (ctor) = 1;
316 return ctor;
319 /* This routine returns a magic number for TYPE. */
321 static unsigned short
322 get_ubsan_type_info_for_type (tree type)
324 if (TREE_CODE (type) == REAL_TYPE)
325 return tree_to_uhwi (TYPE_SIZE (type));
326 else if (INTEGRAL_TYPE_P (type))
328 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
329 gcc_assert (prec != -1);
330 return (prec << 1) | !TYPE_UNSIGNED (type);
332 else
333 return 0;
336 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
337 ubsan_ids[1] for Lubsan_data labels. */
338 static GTY(()) unsigned int ubsan_ids[2];
340 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
341 descriptor. It first looks into the hash table; if not found,
342 create the VAR_DECL, put it into the hash table and return the
343 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
344 an enum controlling how we want to print the type. */
346 tree
347 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
349 /* See through any typedefs. */
350 type = TYPE_MAIN_VARIANT (type);
352 tree decl = decl_for_type_lookup (type);
353 /* It is possible that some of the earlier created DECLs were found
354 unused, in that case they weren't emitted and varpool_node::get
355 returns NULL node on them. But now we really need them. Thus,
356 renew them here. */
357 if (decl != NULL_TREE && varpool_node::get (decl))
358 return build_fold_addr_expr (decl);
360 tree dtype = ubsan_get_type_descriptor_type ();
361 tree type2 = type;
362 const char *tname = NULL;
363 pretty_printer pretty_name;
364 unsigned char deref_depth = 0;
365 unsigned short tkind, tinfo;
367 /* Get the name of the type, or the name of the pointer type. */
368 if (pstyle == UBSAN_PRINT_POINTER)
370 gcc_assert (POINTER_TYPE_P (type));
371 type2 = TREE_TYPE (type);
373 /* Remove any '*' operators from TYPE. */
374 while (POINTER_TYPE_P (type2))
375 deref_depth++, type2 = TREE_TYPE (type2);
377 if (TREE_CODE (type2) == METHOD_TYPE)
378 type2 = TYPE_METHOD_BASETYPE (type2);
381 /* If an array, get its type. */
382 type2 = strip_array_types (type2);
384 if (pstyle == UBSAN_PRINT_ARRAY)
386 while (POINTER_TYPE_P (type2))
387 deref_depth++, type2 = TREE_TYPE (type2);
390 if (TYPE_NAME (type2) != NULL)
392 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
393 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
394 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
395 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
398 if (tname == NULL)
399 /* We weren't able to determine the type name. */
400 tname = "<unknown>";
402 if (pstyle == UBSAN_PRINT_POINTER)
404 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
405 TYPE_VOLATILE (type2) ? "volatile " : "",
406 TYPE_READONLY (type2) ? "const " : "",
407 TYPE_RESTRICT (type2) ? "restrict " : "",
408 TYPE_ATOMIC (type2) ? "_Atomic " : "",
409 TREE_CODE (type2) == RECORD_TYPE
410 ? "struct "
411 : TREE_CODE (type2) == UNION_TYPE
412 ? "union " : "", tname,
413 deref_depth == 0 ? "" : " ");
414 while (deref_depth-- > 0)
415 pp_star (&pretty_name);
416 pp_quote (&pretty_name);
418 else if (pstyle == UBSAN_PRINT_ARRAY)
420 /* Pretty print the array dimensions. */
421 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
422 tree t = type;
423 pp_printf (&pretty_name, "'%s ", tname);
424 while (deref_depth-- > 0)
425 pp_star (&pretty_name);
426 while (TREE_CODE (t) == ARRAY_TYPE)
428 pp_left_bracket (&pretty_name);
429 tree dom = TYPE_DOMAIN (t);
430 if (dom != NULL_TREE
431 && TYPE_MAX_VALUE (dom) != NULL_TREE
432 && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
434 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
435 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
436 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
437 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
438 else
439 pp_wide_int (&pretty_name,
440 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
441 TYPE_SIGN (TREE_TYPE (dom)));
443 else
444 /* ??? We can't determine the variable name; print VLA unspec. */
445 pp_star (&pretty_name);
446 pp_right_bracket (&pretty_name);
447 t = TREE_TYPE (t);
449 pp_quote (&pretty_name);
451 /* Save the tree with stripped types. */
452 type = t;
454 else
455 pp_printf (&pretty_name, "'%s'", tname);
457 switch (TREE_CODE (type))
459 case BOOLEAN_TYPE:
460 case ENUMERAL_TYPE:
461 case INTEGER_TYPE:
462 tkind = 0x0000;
463 break;
464 case REAL_TYPE:
465 /* FIXME: libubsan right now only supports float, double and
466 long double type formats. */
467 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
468 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
469 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
470 tkind = 0x0001;
471 else
472 tkind = 0xffff;
473 break;
474 default:
475 tkind = 0xffff;
476 break;
478 tinfo = get_ubsan_type_info_for_type (type);
480 /* Create a new VAR_DECL of type descriptor. */
481 const char *tmp = pp_formatted_text (&pretty_name);
482 size_t len = strlen (tmp) + 1;
483 tree str = build_string (len, tmp);
484 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
485 TREE_READONLY (str) = 1;
486 TREE_STATIC (str) = 1;
488 char tmp_name[32];
489 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
490 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
491 dtype);
492 TREE_STATIC (decl) = 1;
493 TREE_PUBLIC (decl) = 0;
494 DECL_ARTIFICIAL (decl) = 1;
495 DECL_IGNORED_P (decl) = 1;
496 DECL_EXTERNAL (decl) = 0;
497 DECL_SIZE (decl)
498 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
499 DECL_SIZE_UNIT (decl)
500 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
501 TYPE_SIZE_UNIT (TREE_TYPE (str)));
503 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
504 build_int_cst (short_unsigned_type_node,
505 tkind), NULL_TREE,
506 build_int_cst (short_unsigned_type_node,
507 tinfo), NULL_TREE, str);
508 TREE_CONSTANT (ctor) = 1;
509 TREE_STATIC (ctor) = 1;
510 DECL_INITIAL (decl) = ctor;
511 varpool_node::finalize_decl (decl);
513 /* Save the VAR_DECL into the hash table. */
514 decl_for_type_insert (type, decl);
516 return build_fold_addr_expr (decl);
519 /* Create a structure for the ubsan library. NAME is a name of the new
520 structure. LOCCNT is number of locations, PLOC points to array of
521 locations. The arguments in ... are of __ubsan_type_descriptor type
522 and there are at most two of them, followed by NULL_TREE, followed
523 by optional extra arguments and another NULL_TREE. */
525 tree
526 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
528 va_list args;
529 tree ret, t;
530 tree fields[6];
531 vec<tree, va_gc> *saved_args = NULL;
532 size_t i = 0;
533 int j;
535 /* It is possible that PCH zapped table with definitions of sanitizer
536 builtins. Reinitialize them if needed. */
537 initialize_sanitizer_builtins ();
539 /* Firstly, create a pointer to type descriptor type. */
540 tree td_type = ubsan_get_type_descriptor_type ();
541 td_type = build_pointer_type (td_type);
543 /* Create the structure type. */
544 ret = make_node (RECORD_TYPE);
545 for (j = 0; j < loccnt; j++)
547 gcc_checking_assert (i < 2);
548 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
549 ubsan_get_source_location_type ());
550 DECL_CONTEXT (fields[i]) = ret;
551 if (i)
552 DECL_CHAIN (fields[i - 1]) = fields[i];
553 i++;
556 va_start (args, ploc);
557 for (t = va_arg (args, tree); t != NULL_TREE;
558 i++, t = va_arg (args, tree))
560 gcc_checking_assert (i < 4);
561 /* Save the tree arguments for later use. */
562 vec_safe_push (saved_args, t);
563 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
564 td_type);
565 DECL_CONTEXT (fields[i]) = ret;
566 if (i)
567 DECL_CHAIN (fields[i - 1]) = fields[i];
570 for (t = va_arg (args, tree); t != NULL_TREE;
571 i++, t = va_arg (args, tree))
573 gcc_checking_assert (i < 6);
574 /* Save the tree arguments for later use. */
575 vec_safe_push (saved_args, t);
576 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
577 TREE_TYPE (t));
578 DECL_CONTEXT (fields[i]) = ret;
579 if (i)
580 DECL_CHAIN (fields[i - 1]) = fields[i];
582 va_end (args);
584 tree type_decl = build_decl (input_location, TYPE_DECL,
585 get_identifier (name), ret);
586 DECL_IGNORED_P (type_decl) = 1;
587 DECL_ARTIFICIAL (type_decl) = 1;
588 TYPE_FIELDS (ret) = fields[0];
589 TYPE_NAME (ret) = type_decl;
590 TYPE_STUB_DECL (ret) = type_decl;
591 layout_type (ret);
593 /* Now, fill in the type. */
594 char tmp_name[32];
595 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
596 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
597 ret);
598 TREE_STATIC (var) = 1;
599 TREE_PUBLIC (var) = 0;
600 DECL_ARTIFICIAL (var) = 1;
601 DECL_IGNORED_P (var) = 1;
602 DECL_EXTERNAL (var) = 0;
604 vec<constructor_elt, va_gc> *v;
605 vec_alloc (v, i);
606 tree ctor = build_constructor (ret, v);
608 /* If desirable, set the __ubsan_source_location element. */
609 for (j = 0; j < loccnt; j++)
611 location_t loc = LOCATION_LOCUS (ploc[j]);
612 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
615 size_t nelts = vec_safe_length (saved_args);
616 for (i = 0; i < nelts; i++)
618 t = (*saved_args)[i];
619 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
622 TREE_CONSTANT (ctor) = 1;
623 TREE_STATIC (ctor) = 1;
624 DECL_INITIAL (var) = ctor;
625 varpool_node::finalize_decl (var);
627 return var;
630 /* Instrument the __builtin_unreachable call. We just call the libubsan
631 routine instead. */
633 bool
634 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
636 gimple *g;
637 location_t loc = gimple_location (gsi_stmt (*gsi));
639 if (flag_sanitize_undefined_trap_on_error)
640 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
641 else
643 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
644 NULL_TREE, NULL_TREE);
645 data = build_fold_addr_expr_loc (loc, data);
646 tree fn
647 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
648 g = gimple_build_call (fn, 1, data);
650 gimple_set_location (g, loc);
651 gsi_replace (gsi, g, false);
652 return false;
655 /* Return true if T is a call to a libubsan routine. */
657 bool
658 is_ubsan_builtin_p (tree t)
660 return TREE_CODE (t) == FUNCTION_DECL
661 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
662 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
663 "__builtin___ubsan_", 18) == 0;
666 /* Create a callgraph edge for statement STMT. */
668 static void
669 ubsan_create_edge (gimple *stmt)
671 gcall *call_stmt = dyn_cast <gcall *> (stmt);
672 basic_block bb = gimple_bb (stmt);
673 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
674 cgraph_node *node = cgraph_node::get (current_function_decl);
675 tree decl = gimple_call_fndecl (call_stmt);
676 if (decl)
677 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
678 freq);
681 /* Expand the UBSAN_BOUNDS special builtin function. */
683 bool
684 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
686 gimple *stmt = gsi_stmt (*gsi);
687 location_t loc = gimple_location (stmt);
688 gcc_assert (gimple_call_num_args (stmt) == 3);
690 /* Pick up the arguments of the UBSAN_BOUNDS call. */
691 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
692 tree index = gimple_call_arg (stmt, 1);
693 tree orig_index = index;
694 tree bound = gimple_call_arg (stmt, 2);
696 gimple_stmt_iterator gsi_orig = *gsi;
698 /* Create condition "if (index > bound)". */
699 basic_block then_bb, fallthru_bb;
700 gimple_stmt_iterator cond_insert_point
701 = create_cond_insert_point (gsi, false, false, true,
702 &then_bb, &fallthru_bb);
703 index = fold_convert (TREE_TYPE (bound), index);
704 index = force_gimple_operand_gsi (&cond_insert_point, index,
705 true, NULL_TREE,
706 false, GSI_NEW_STMT);
707 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
708 gimple_set_location (g, loc);
709 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
711 /* Generate __ubsan_handle_out_of_bounds call. */
712 *gsi = gsi_after_labels (then_bb);
713 if (flag_sanitize_undefined_trap_on_error)
714 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
715 else
717 tree data
718 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
719 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
720 ubsan_type_descriptor (TREE_TYPE (orig_index)),
721 NULL_TREE, NULL_TREE);
722 data = build_fold_addr_expr_loc (loc, data);
723 enum built_in_function bcode
724 = (flag_sanitize_recover & SANITIZE_BOUNDS)
725 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
726 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
727 tree fn = builtin_decl_explicit (bcode);
728 tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE);
729 val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true,
730 GSI_SAME_STMT);
731 g = gimple_build_call (fn, 2, data, val);
733 gimple_set_location (g, loc);
734 gsi_insert_before (gsi, g, GSI_SAME_STMT);
736 /* Get rid of the UBSAN_BOUNDS call from the IR. */
737 unlink_stmt_vdef (stmt);
738 gsi_remove (&gsi_orig, true);
740 /* Point GSI to next logical statement. */
741 *gsi = gsi_start_bb (fallthru_bb);
742 return true;
745 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
746 argument which is a constant, because the middle-end treats pointer
747 conversions as useless and therefore the type of the first argument
748 could be changed to any other pointer type. */
750 bool
751 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
753 gimple_stmt_iterator gsi = *gsip;
754 gimple *stmt = gsi_stmt (gsi);
755 location_t loc = gimple_location (stmt);
756 gcc_assert (gimple_call_num_args (stmt) == 3);
757 tree ptr = gimple_call_arg (stmt, 0);
758 tree ckind = gimple_call_arg (stmt, 1);
759 tree align = gimple_call_arg (stmt, 2);
760 tree check_align = NULL_TREE;
761 bool check_null;
763 basic_block cur_bb = gsi_bb (gsi);
765 gimple *g;
766 if (!integer_zerop (align))
768 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
769 if (compare_tree_int (align, ptralign) == 1)
771 check_align = make_ssa_name (pointer_sized_int_node);
772 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
773 gimple_set_location (g, loc);
774 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
777 check_null = sanitize_flags_p (SANITIZE_NULL);
779 if (check_align == NULL_TREE && !check_null)
781 gsi_remove (gsip, true);
782 /* Unlink the UBSAN_NULLs vops before replacing it. */
783 unlink_stmt_vdef (stmt);
784 return true;
787 /* Split the original block holding the pointer dereference. */
788 edge e = split_block (cur_bb, stmt);
790 /* Get a hold on the 'condition block', the 'then block' and the
791 'else block'. */
792 basic_block cond_bb = e->src;
793 basic_block fallthru_bb = e->dest;
794 basic_block then_bb = create_empty_bb (cond_bb);
795 add_bb_to_loop (then_bb, cond_bb->loop_father);
796 loops_state_set (LOOPS_NEED_FIXUP);
798 /* Make an edge coming from the 'cond block' into the 'then block';
799 this edge is unlikely taken, so set up the probability accordingly. */
800 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
801 e->probability = PROB_VERY_UNLIKELY;
803 /* Connect 'then block' with the 'else block'. This is needed
804 as the ubsan routines we call in the 'then block' are not noreturn.
805 The 'then block' only has one outcoming edge. */
806 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
808 /* Set up the fallthrough basic block. */
809 e = find_edge (cond_bb, fallthru_bb);
810 e->flags = EDGE_FALSE_VALUE;
811 e->count = cond_bb->count;
812 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
814 /* Update dominance info for the newly created then_bb; note that
815 fallthru_bb's dominance info has already been updated by
816 split_block. */
817 if (dom_info_available_p (CDI_DOMINATORS))
818 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
820 /* Put the ubsan builtin call into the newly created BB. */
821 if (flag_sanitize_undefined_trap_on_error)
822 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
823 else
825 enum built_in_function bcode
826 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
827 | (check_null ? SANITIZE_NULL : 0)))
828 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
829 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
830 tree fn = builtin_decl_implicit (bcode);
831 tree data
832 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
833 ubsan_type_descriptor (TREE_TYPE (ckind),
834 UBSAN_PRINT_POINTER),
835 NULL_TREE,
836 align,
837 fold_convert (unsigned_char_type_node, ckind),
838 NULL_TREE);
839 data = build_fold_addr_expr_loc (loc, data);
840 g = gimple_build_call (fn, 2, data,
841 check_align ? check_align
842 : build_zero_cst (pointer_sized_int_node));
844 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
845 gimple_set_location (g, loc);
846 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
848 /* Unlink the UBSAN_NULLs vops before replacing it. */
849 unlink_stmt_vdef (stmt);
851 if (check_null)
853 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
854 NULL_TREE, NULL_TREE);
855 gimple_set_location (g, loc);
857 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
858 gsi_replace (&gsi, g, false);
859 stmt = g;
862 if (check_align)
864 if (check_null)
866 /* Split the block with the condition again. */
867 e = split_block (cond_bb, stmt);
868 basic_block cond1_bb = e->src;
869 basic_block cond2_bb = e->dest;
871 /* Make an edge coming from the 'cond1 block' into the 'then block';
872 this edge is unlikely taken, so set up the probability
873 accordingly. */
874 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
875 e->probability = PROB_VERY_UNLIKELY;
877 /* Set up the fallthrough basic block. */
878 e = find_edge (cond1_bb, cond2_bb);
879 e->flags = EDGE_FALSE_VALUE;
880 e->count = cond1_bb->count;
881 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
883 /* Update dominance info. */
884 if (dom_info_available_p (CDI_DOMINATORS))
886 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
887 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
890 gsi2 = gsi_start_bb (cond2_bb);
893 tree mask = build_int_cst (pointer_sized_int_node,
894 tree_to_uhwi (align) - 1);
895 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
896 BIT_AND_EXPR, check_align, mask);
897 gimple_set_location (g, loc);
898 if (check_null)
899 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
900 else
901 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
903 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
904 build_int_cst (pointer_sized_int_node, 0),
905 NULL_TREE, NULL_TREE);
906 gimple_set_location (g, loc);
907 if (check_null)
908 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
909 else
910 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
911 gsi_replace (&gsi, g, false);
913 return false;
916 #define OBJSZ_MAX_OFFSET (1024 * 16)
918 /* Expand UBSAN_OBJECT_SIZE internal call. */
920 bool
921 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
923 gimple *stmt = gsi_stmt (*gsi);
924 location_t loc = gimple_location (stmt);
925 gcc_assert (gimple_call_num_args (stmt) == 4);
927 tree ptr = gimple_call_arg (stmt, 0);
928 tree offset = gimple_call_arg (stmt, 1);
929 tree size = gimple_call_arg (stmt, 2);
930 tree ckind = gimple_call_arg (stmt, 3);
931 gimple_stmt_iterator gsi_orig = *gsi;
932 gimple *g;
934 /* See if we can discard the check. */
935 if (TREE_CODE (size) != INTEGER_CST
936 || integer_all_onesp (size))
937 /* Yes, __builtin_object_size couldn't determine the
938 object size. */;
939 else if (TREE_CODE (offset) == INTEGER_CST
940 && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
941 && wi::to_widest (offset) <= -1)
942 /* The offset is in range [-16K, -1]. */;
943 else
945 /* if (offset > objsize) */
946 basic_block then_bb, fallthru_bb;
947 gimple_stmt_iterator cond_insert_point
948 = create_cond_insert_point (gsi, false, false, true,
949 &then_bb, &fallthru_bb);
950 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
951 gimple_set_location (g, loc);
952 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
954 /* If the offset is small enough, we don't need the second
955 run-time check. */
956 if (TREE_CODE (offset) == INTEGER_CST
957 && wi::to_widest (offset) >= 0
958 && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
959 *gsi = gsi_after_labels (then_bb);
960 else
962 /* Don't issue run-time error if (ptr > ptr + offset). That
963 may happen when computing a POINTER_PLUS_EXPR. */
964 basic_block then2_bb, fallthru2_bb;
966 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
967 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
968 true, &then2_bb,
969 &fallthru2_bb);
970 /* Convert the pointer to an integer type. */
971 tree p = make_ssa_name (pointer_sized_int_node);
972 g = gimple_build_assign (p, NOP_EXPR, ptr);
973 gimple_set_location (g, loc);
974 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
975 p = gimple_assign_lhs (g);
976 /* Compute ptr + offset. */
977 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
978 PLUS_EXPR, p, offset);
979 gimple_set_location (g, loc);
980 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
981 /* Now build the conditional and put it into the IR. */
982 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
983 NULL_TREE, NULL_TREE);
984 gimple_set_location (g, loc);
985 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
986 *gsi = gsi_after_labels (then2_bb);
989 /* Generate __ubsan_handle_type_mismatch call. */
990 if (flag_sanitize_undefined_trap_on_error)
991 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
992 else
994 tree data
995 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
996 ubsan_type_descriptor (TREE_TYPE (ptr),
997 UBSAN_PRINT_POINTER),
998 NULL_TREE,
999 build_zero_cst (pointer_sized_int_node),
1000 ckind,
1001 NULL_TREE);
1002 data = build_fold_addr_expr_loc (loc, data);
1003 enum built_in_function bcode
1004 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1005 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1006 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
1007 tree p = make_ssa_name (pointer_sized_int_node);
1008 g = gimple_build_assign (p, NOP_EXPR, ptr);
1009 gimple_set_location (g, loc);
1010 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1011 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1013 gimple_set_location (g, loc);
1014 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1016 /* Point GSI to next logical statement. */
1017 *gsi = gsi_start_bb (fallthru_bb);
1019 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1020 unlink_stmt_vdef (stmt);
1021 gsi_remove (&gsi_orig, true);
1022 return true;
1025 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1026 unlink_stmt_vdef (stmt);
1027 gsi_remove (gsi, true);
1028 return true;
1031 /* Cached __ubsan_vptr_type_cache decl. */
1032 static GTY(()) tree ubsan_vptr_type_cache_decl;
1034 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1035 argument which is a constant, because the middle-end treats pointer
1036 conversions as useless and therefore the type of the first argument
1037 could be changed to any other pointer type. */
1039 bool
1040 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1042 gimple_stmt_iterator gsi = *gsip;
1043 gimple *stmt = gsi_stmt (gsi);
1044 location_t loc = gimple_location (stmt);
1045 gcc_assert (gimple_call_num_args (stmt) == 5);
1046 tree op = gimple_call_arg (stmt, 0);
1047 tree vptr = gimple_call_arg (stmt, 1);
1048 tree str_hash = gimple_call_arg (stmt, 2);
1049 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1050 tree ckind_tree = gimple_call_arg (stmt, 4);
1051 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1052 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1053 gimple *g;
1054 basic_block fallthru_bb = NULL;
1056 if (ckind == UBSAN_DOWNCAST_POINTER)
1058 /* Guard everything with if (op != NULL) { ... }. */
1059 basic_block then_bb;
1060 gimple_stmt_iterator cond_insert_point
1061 = create_cond_insert_point (gsip, false, false, true,
1062 &then_bb, &fallthru_bb);
1063 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1064 NULL_TREE, NULL_TREE);
1065 gimple_set_location (g, loc);
1066 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1067 *gsip = gsi_after_labels (then_bb);
1068 gsi_remove (&gsi, false);
1069 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1070 gsi = *gsip;
1073 tree htype = TREE_TYPE (str_hash);
1074 tree cst = wide_int_to_tree (htype,
1075 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1076 | 0xeb382d69, 64));
1077 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1078 vptr, str_hash);
1079 gimple_set_location (g, loc);
1080 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1081 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1082 gimple_assign_lhs (g), cst);
1083 gimple_set_location (g, loc);
1084 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1085 tree t1 = gimple_assign_lhs (g);
1086 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1087 t1, build_int_cst (integer_type_node, 47));
1088 gimple_set_location (g, loc);
1089 tree t2 = gimple_assign_lhs (g);
1090 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1091 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1092 vptr, t1);
1093 gimple_set_location (g, loc);
1094 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1095 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1096 t2, gimple_assign_lhs (g));
1097 gimple_set_location (g, loc);
1098 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1099 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1100 gimple_assign_lhs (g), cst);
1101 gimple_set_location (g, loc);
1102 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1103 tree t3 = gimple_assign_lhs (g);
1104 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1105 t3, build_int_cst (integer_type_node, 47));
1106 gimple_set_location (g, loc);
1107 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1108 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1109 t3, gimple_assign_lhs (g));
1110 gimple_set_location (g, loc);
1111 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1112 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1113 gimple_assign_lhs (g), cst);
1114 gimple_set_location (g, loc);
1115 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1116 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1118 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1119 NOP_EXPR, gimple_assign_lhs (g));
1120 gimple_set_location (g, loc);
1121 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1123 tree hash = gimple_assign_lhs (g);
1125 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1127 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1128 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1129 get_identifier ("__ubsan_vptr_type_cache"),
1130 atype);
1131 DECL_ARTIFICIAL (array) = 1;
1132 DECL_IGNORED_P (array) = 1;
1133 TREE_PUBLIC (array) = 1;
1134 TREE_STATIC (array) = 1;
1135 DECL_EXTERNAL (array) = 1;
1136 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1137 DECL_VISIBILITY_SPECIFIED (array) = 1;
1138 varpool_node::finalize_decl (array);
1139 ubsan_vptr_type_cache_decl = array;
1142 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1143 BIT_AND_EXPR, hash,
1144 build_int_cst (pointer_sized_int_node, 127));
1145 gimple_set_location (g, loc);
1146 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1148 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1149 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1150 NULL_TREE, NULL_TREE);
1151 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1152 ARRAY_REF, c);
1153 gimple_set_location (g, loc);
1154 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1156 basic_block then_bb, fallthru2_bb;
1157 gimple_stmt_iterator cond_insert_point
1158 = create_cond_insert_point (gsip, false, false, true,
1159 &then_bb, &fallthru2_bb);
1160 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1161 NULL_TREE, NULL_TREE);
1162 gimple_set_location (g, loc);
1163 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1164 *gsip = gsi_after_labels (then_bb);
1165 if (fallthru_bb == NULL)
1166 fallthru_bb = fallthru2_bb;
1168 tree data
1169 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1170 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1171 build_int_cst (unsigned_char_type_node, ckind),
1172 NULL_TREE);
1173 data = build_fold_addr_expr_loc (loc, data);
1174 enum built_in_function bcode
1175 = (flag_sanitize_recover & SANITIZE_VPTR)
1176 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1177 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1179 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1180 gimple_set_location (g, loc);
1181 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1183 /* Point GSI to next logical statement. */
1184 *gsip = gsi_start_bb (fallthru_bb);
1186 /* Get rid of the UBSAN_VPTR call from the IR. */
1187 unlink_stmt_vdef (stmt);
1188 gsi_remove (&gsi, true);
1189 return true;
1192 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1193 whether the pointer is on the left hand side of the assignment. */
1195 static void
1196 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1197 bool is_lhs)
1199 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1200 unsigned int align = 0;
1201 if (sanitize_flags_p (SANITIZE_ALIGNMENT))
1203 align = min_align_of_type (TREE_TYPE (base));
1204 if (align <= 1)
1205 align = 0;
1207 if (align == 0 && !sanitize_flags_p (SANITIZE_NULL))
1208 return;
1209 tree t = TREE_OPERAND (base, 0);
1210 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1211 return;
1212 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1213 ikind = UBSAN_MEMBER_ACCESS;
1214 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1215 tree alignt = build_int_cst (pointer_sized_int_node, align);
1216 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1217 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1218 gsi_insert_before (iter, g, GSI_SAME_STMT);
1221 /* Perform the pointer instrumentation. */
1223 static void
1224 instrument_null (gimple_stmt_iterator gsi, tree t, bool is_lhs)
1226 /* Handle also e.g. &s->i. */
1227 if (TREE_CODE (t) == ADDR_EXPR)
1228 t = TREE_OPERAND (t, 0);
1229 tree base = get_base_address (t);
1230 if (TREE_CODE (base) == MEM_REF
1231 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1232 instrument_mem_ref (t, base, &gsi, is_lhs);
1235 /* Build an ubsan builtin call for the signed-integer-overflow
1236 sanitization. CODE says what kind of builtin are we building,
1237 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1238 are operands of the binary operation. */
1240 tree
1241 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1242 tree op0, tree op1, tree *datap)
1244 if (flag_sanitize_undefined_trap_on_error)
1245 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1247 tree data;
1248 if (datap && *datap)
1249 data = *datap;
1250 else
1251 data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1252 ubsan_type_descriptor (lhstype), NULL_TREE,
1253 NULL_TREE);
1254 if (datap)
1255 *datap = data;
1256 enum built_in_function fn_code;
1258 switch (code)
1260 case PLUS_EXPR:
1261 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1262 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1263 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1264 break;
1265 case MINUS_EXPR:
1266 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1267 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1268 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1269 break;
1270 case MULT_EXPR:
1271 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1272 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1273 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1274 break;
1275 case NEGATE_EXPR:
1276 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1277 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1278 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1279 break;
1280 default:
1281 gcc_unreachable ();
1283 tree fn = builtin_decl_explicit (fn_code);
1284 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1285 build_fold_addr_expr_loc (loc, data),
1286 ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL),
1288 ? ubsan_encode_value (op1,
1289 UBSAN_ENCODE_VALUE_RTL)
1290 : NULL_TREE);
1293 /* Perform the signed integer instrumentation. GSI is the iterator
1294 pointing at statement we are trying to instrument. */
1296 static void
1297 instrument_si_overflow (gimple_stmt_iterator gsi)
1299 gimple *stmt = gsi_stmt (gsi);
1300 tree_code code = gimple_assign_rhs_code (stmt);
1301 tree lhs = gimple_assign_lhs (stmt);
1302 tree lhstype = TREE_TYPE (lhs);
1303 tree lhsinner = VECTOR_TYPE_P (lhstype) ? TREE_TYPE (lhstype) : lhstype;
1304 tree a, b;
1305 gimple *g;
1307 /* If this is not a signed operation, don't instrument anything here.
1308 Also punt on bit-fields. */
1309 if (!INTEGRAL_TYPE_P (lhsinner)
1310 || TYPE_OVERFLOW_WRAPS (lhsinner)
1311 || GET_MODE_BITSIZE (TYPE_MODE (lhsinner)) != TYPE_PRECISION (lhsinner))
1312 return;
1314 switch (code)
1316 case MINUS_EXPR:
1317 case PLUS_EXPR:
1318 case MULT_EXPR:
1319 /* Transform
1320 i = u {+,-,*} 5;
1321 into
1322 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1323 a = gimple_assign_rhs1 (stmt);
1324 b = gimple_assign_rhs2 (stmt);
1325 g = gimple_build_call_internal (code == PLUS_EXPR
1326 ? IFN_UBSAN_CHECK_ADD
1327 : code == MINUS_EXPR
1328 ? IFN_UBSAN_CHECK_SUB
1329 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1330 gimple_call_set_lhs (g, lhs);
1331 gsi_replace (&gsi, g, true);
1332 break;
1333 case NEGATE_EXPR:
1334 /* Represent i = -u;
1336 i = UBSAN_CHECK_SUB (0, u); */
1337 a = build_zero_cst (lhstype);
1338 b = gimple_assign_rhs1 (stmt);
1339 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1340 gimple_call_set_lhs (g, lhs);
1341 gsi_replace (&gsi, g, true);
1342 break;
1343 case ABS_EXPR:
1344 /* Transform i = ABS_EXPR<u>;
1345 into
1346 _N = UBSAN_CHECK_SUB (0, u);
1347 i = ABS_EXPR<_N>; */
1348 a = build_zero_cst (lhstype);
1349 b = gimple_assign_rhs1 (stmt);
1350 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1351 a = make_ssa_name (lhstype);
1352 gimple_call_set_lhs (g, a);
1353 gimple_set_location (g, gimple_location (stmt));
1354 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1355 gimple_assign_set_rhs1 (stmt, a);
1356 update_stmt (stmt);
1357 break;
1358 default:
1359 break;
1363 /* Instrument loads from (non-bitfield) bool and C++ enum values
1364 to check if the memory value is outside of the range of the valid
1365 type values. */
1367 static void
1368 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1370 gimple *stmt = gsi_stmt (*gsi);
1371 tree rhs = gimple_assign_rhs1 (stmt);
1372 tree type = TREE_TYPE (rhs);
1373 tree minv = NULL_TREE, maxv = NULL_TREE;
1375 if (TREE_CODE (type) == BOOLEAN_TYPE
1376 && sanitize_flags_p (SANITIZE_BOOL))
1378 minv = boolean_false_node;
1379 maxv = boolean_true_node;
1381 else if (TREE_CODE (type) == ENUMERAL_TYPE
1382 && sanitize_flags_p (SANITIZE_ENUM)
1383 && TREE_TYPE (type) != NULL_TREE
1384 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1385 && (TYPE_PRECISION (TREE_TYPE (type))
1386 < GET_MODE_PRECISION (TYPE_MODE (type))))
1388 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1389 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1391 else
1392 return;
1394 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1395 HOST_WIDE_INT bitsize, bitpos;
1396 tree offset;
1397 machine_mode mode;
1398 int volatilep = 0, reversep, unsignedp = 0;
1399 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1400 &unsignedp, &reversep, &volatilep);
1401 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1403 if ((VAR_P (base) && DECL_HARD_REGISTER (base))
1404 || (bitpos % modebitsize) != 0
1405 || bitsize != modebitsize
1406 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1407 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1408 return;
1410 bool ends_bb = stmt_ends_bb_p (stmt);
1411 location_t loc = gimple_location (stmt);
1412 tree lhs = gimple_assign_lhs (stmt);
1413 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1414 tree atype = reference_alias_ptr_type (rhs);
1415 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1416 build_fold_addr_expr (rhs));
1417 gimple_set_location (g, loc);
1418 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1419 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1420 build_int_cst (atype, 0));
1421 tree urhs = make_ssa_name (utype);
1422 if (ends_bb)
1424 gimple_assign_set_lhs (stmt, urhs);
1425 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1426 gimple_set_location (g, loc);
1427 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1428 gsi_insert_on_edge_immediate (e, g);
1429 gimple_assign_set_rhs_from_tree (gsi, mem);
1430 update_stmt (stmt);
1431 *gsi = gsi_for_stmt (g);
1432 g = stmt;
1434 else
1436 g = gimple_build_assign (urhs, mem);
1437 gimple_set_location (g, loc);
1438 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1440 minv = fold_convert (utype, minv);
1441 maxv = fold_convert (utype, maxv);
1442 if (!integer_zerop (minv))
1444 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1445 gimple_set_location (g, loc);
1446 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1449 gimple_stmt_iterator gsi2 = *gsi;
1450 basic_block then_bb, fallthru_bb;
1451 *gsi = create_cond_insert_point (gsi, true, false, true,
1452 &then_bb, &fallthru_bb);
1453 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1454 int_const_binop (MINUS_EXPR, maxv, minv),
1455 NULL_TREE, NULL_TREE);
1456 gimple_set_location (g, loc);
1457 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1459 if (!ends_bb)
1461 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1462 update_stmt (stmt);
1465 gsi2 = gsi_after_labels (then_bb);
1466 if (flag_sanitize_undefined_trap_on_error)
1467 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1468 else
1470 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1471 ubsan_type_descriptor (type), NULL_TREE,
1472 NULL_TREE);
1473 data = build_fold_addr_expr_loc (loc, data);
1474 enum built_in_function bcode
1475 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1476 ? SANITIZE_BOOL : SANITIZE_ENUM))
1477 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1478 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1479 tree fn = builtin_decl_explicit (bcode);
1481 tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE);
1482 val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true,
1483 GSI_SAME_STMT);
1484 g = gimple_build_call (fn, 2, data, val);
1486 gimple_set_location (g, loc);
1487 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1488 ubsan_create_edge (g);
1489 *gsi = gsi_for_stmt (stmt);
1492 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1493 new style handlers. Libubsan uses heuristics to destinguish between old and
1494 new styles and relies on these properties for filename:
1496 a) Location's filename must not be NULL.
1497 b) Location's filename must not be equal to "".
1498 c) Location's filename must not be equal to "\1".
1499 d) First two bytes of filename must not contain '\xff' symbol. */
1501 static bool
1502 ubsan_use_new_style_p (location_t loc)
1504 if (loc == UNKNOWN_LOCATION)
1505 return false;
1507 expanded_location xloc = expand_location (loc);
1508 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1509 || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1510 || xloc.file[1] == '\xff')
1511 return false;
1513 return true;
1516 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1517 destination, EXPR is floating-point expression. */
1519 tree
1520 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1522 tree expr_type = TREE_TYPE (expr);
1523 tree t, tt, fn, min, max;
1524 machine_mode mode = TYPE_MODE (expr_type);
1525 int prec = TYPE_PRECISION (type);
1526 bool uns_p = TYPE_UNSIGNED (type);
1527 if (loc == UNKNOWN_LOCATION)
1528 loc = input_location;
1530 /* Float to integer conversion first truncates toward zero, so
1531 even signed char c = 127.875f; is not problematic.
1532 Therefore, we should complain only if EXPR is unordered or smaller
1533 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1534 TYPE_MAX_VALUE + 1.0. */
1535 if (REAL_MODE_FORMAT (mode)->b == 2)
1537 /* For maximum, TYPE_MAX_VALUE might not be representable
1538 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1539 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1540 either representable or infinity. */
1541 REAL_VALUE_TYPE maxval = dconst1;
1542 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1543 real_convert (&maxval, mode, &maxval);
1544 max = build_real (expr_type, maxval);
1546 /* For unsigned, assume -1.0 is always representable. */
1547 if (uns_p)
1548 min = build_minus_one_cst (expr_type);
1549 else
1551 /* TYPE_MIN_VALUE is generally representable (or -inf),
1552 but TYPE_MIN_VALUE - 1.0 might not be. */
1553 REAL_VALUE_TYPE minval = dconstm1, minval2;
1554 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1555 real_convert (&minval, mode, &minval);
1556 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1557 real_convert (&minval2, mode, &minval2);
1558 if (real_compare (EQ_EXPR, &minval, &minval2)
1559 && !real_isinf (&minval))
1561 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1562 rounds to TYPE_MIN_VALUE, we need to subtract
1563 more. As REAL_MODE_FORMAT (mode)->p is the number
1564 of base digits, we want to subtract a number that
1565 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1566 times smaller than minval. */
1567 minval2 = dconst1;
1568 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1569 SET_REAL_EXP (&minval2,
1570 REAL_EXP (&minval2) + prec - 1
1571 - REAL_MODE_FORMAT (mode)->p + 1);
1572 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1573 real_convert (&minval2, mode, &minval2);
1575 min = build_real (expr_type, minval2);
1578 else if (REAL_MODE_FORMAT (mode)->b == 10)
1580 /* For _Decimal128 up to 34 decimal digits, - sign,
1581 dot, e, exponent. */
1582 char buf[64];
1583 mpfr_t m;
1584 int p = REAL_MODE_FORMAT (mode)->p;
1585 REAL_VALUE_TYPE maxval, minval;
1587 /* Use mpfr_snprintf rounding to compute the smallest
1588 representable decimal number greater or equal than
1589 1 << (prec - !uns_p). */
1590 mpfr_init2 (m, prec + 2);
1591 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1592 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1593 decimal_real_from_string (&maxval, buf);
1594 max = build_real (expr_type, maxval);
1596 /* For unsigned, assume -1.0 is always representable. */
1597 if (uns_p)
1598 min = build_minus_one_cst (expr_type);
1599 else
1601 /* Use mpfr_snprintf rounding to compute the largest
1602 representable decimal number less or equal than
1603 (-1 << (prec - 1)) - 1. */
1604 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1605 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1606 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1607 decimal_real_from_string (&minval, buf);
1608 min = build_real (expr_type, minval);
1610 mpfr_clear (m);
1612 else
1613 return NULL_TREE;
1615 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1616 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1617 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1618 if (integer_zerop (t))
1619 return NULL_TREE;
1621 if (flag_sanitize_undefined_trap_on_error)
1622 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1623 else
1625 location_t *loc_ptr = NULL;
1626 unsigned num_locations = 0;
1627 /* Figure out if we can propagate location to ubsan_data and use new
1628 style handlers in libubsan. */
1629 if (ubsan_use_new_style_p (loc))
1631 loc_ptr = &loc;
1632 num_locations = 1;
1634 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1635 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1636 num_locations, loc_ptr,
1637 ubsan_type_descriptor (expr_type),
1638 ubsan_type_descriptor (type), NULL_TREE,
1639 NULL_TREE);
1640 enum built_in_function bcode
1641 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1642 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1643 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1644 fn = builtin_decl_explicit (bcode);
1645 fn = build_call_expr_loc (loc, fn, 2,
1646 build_fold_addr_expr_loc (loc, data),
1647 ubsan_encode_value (expr));
1650 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1653 /* Instrument values passed to function arguments with nonnull attribute. */
1655 static void
1656 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1658 gimple *stmt = gsi_stmt (*gsi);
1659 location_t loc[2];
1660 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1661 while for nonnull sanitization it is clear. */
1662 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1663 flag_delete_null_pointer_checks = 1;
1664 loc[0] = gimple_location (stmt);
1665 loc[1] = UNKNOWN_LOCATION;
1666 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1668 tree arg = gimple_call_arg (stmt, i);
1669 if (POINTER_TYPE_P (TREE_TYPE (arg))
1670 && infer_nonnull_range_by_attribute (stmt, arg))
1672 gimple *g;
1673 if (!is_gimple_val (arg))
1675 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1676 gimple_set_location (g, loc[0]);
1677 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1678 arg = gimple_assign_lhs (g);
1681 basic_block then_bb, fallthru_bb;
1682 *gsi = create_cond_insert_point (gsi, true, false, true,
1683 &then_bb, &fallthru_bb);
1684 g = gimple_build_cond (EQ_EXPR, arg,
1685 build_zero_cst (TREE_TYPE (arg)),
1686 NULL_TREE, NULL_TREE);
1687 gimple_set_location (g, loc[0]);
1688 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1690 *gsi = gsi_after_labels (then_bb);
1691 if (flag_sanitize_undefined_trap_on_error)
1692 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1693 else
1695 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1696 2, loc, NULL_TREE,
1697 build_int_cst (integer_type_node,
1698 i + 1),
1699 NULL_TREE);
1700 data = build_fold_addr_expr_loc (loc[0], data);
1701 enum built_in_function bcode
1702 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1703 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1704 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1705 tree fn = builtin_decl_explicit (bcode);
1707 g = gimple_build_call (fn, 1, data);
1709 gimple_set_location (g, loc[0]);
1710 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1711 ubsan_create_edge (g);
1713 *gsi = gsi_for_stmt (stmt);
1715 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1718 /* Instrument returns in functions with returns_nonnull attribute. */
1720 static void
1721 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1723 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1724 location_t loc[2];
1725 tree arg = gimple_return_retval (stmt);
1726 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1727 while for nonnull return sanitization it is clear. */
1728 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1729 flag_delete_null_pointer_checks = 1;
1730 loc[0] = gimple_location (stmt);
1731 loc[1] = UNKNOWN_LOCATION;
1732 if (arg
1733 && POINTER_TYPE_P (TREE_TYPE (arg))
1734 && is_gimple_val (arg)
1735 && infer_nonnull_range_by_attribute (stmt, arg))
1737 basic_block then_bb, fallthru_bb;
1738 *gsi = create_cond_insert_point (gsi, true, false, true,
1739 &then_bb, &fallthru_bb);
1740 gimple *g = gimple_build_cond (EQ_EXPR, arg,
1741 build_zero_cst (TREE_TYPE (arg)),
1742 NULL_TREE, NULL_TREE);
1743 gimple_set_location (g, loc[0]);
1744 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1746 *gsi = gsi_after_labels (then_bb);
1747 if (flag_sanitize_undefined_trap_on_error)
1748 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1749 else
1751 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1752 2, loc, NULL_TREE, NULL_TREE);
1753 data = build_fold_addr_expr_loc (loc[0], data);
1754 enum built_in_function bcode
1755 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1756 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1757 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1758 tree fn = builtin_decl_explicit (bcode);
1760 g = gimple_build_call (fn, 1, data);
1762 gimple_set_location (g, loc[0]);
1763 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1764 ubsan_create_edge (g);
1765 *gsi = gsi_for_stmt (stmt);
1767 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1770 /* Instrument memory references. Here we check whether the pointer
1771 points to an out-of-bounds location. */
1773 static void
1774 instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
1776 gimple *stmt = gsi_stmt (*gsi);
1777 location_t loc = gimple_location (stmt);
1778 tree type;
1779 tree index = NULL_TREE;
1780 HOST_WIDE_INT size_in_bytes;
1782 type = TREE_TYPE (t);
1783 if (VOID_TYPE_P (type))
1784 return;
1786 switch (TREE_CODE (t))
1788 case COMPONENT_REF:
1789 if (TREE_CODE (t) == COMPONENT_REF
1790 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1792 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1793 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1794 repr, TREE_OPERAND (t, 2));
1796 break;
1797 case ARRAY_REF:
1798 index = TREE_OPERAND (t, 1);
1799 break;
1800 case INDIRECT_REF:
1801 case MEM_REF:
1802 case VAR_DECL:
1803 case PARM_DECL:
1804 case RESULT_DECL:
1805 break;
1806 default:
1807 return;
1810 size_in_bytes = int_size_in_bytes (type);
1811 if (size_in_bytes <= 0)
1812 return;
1814 HOST_WIDE_INT bitsize, bitpos;
1815 tree offset;
1816 machine_mode mode;
1817 int volatilep = 0, reversep, unsignedp = 0;
1818 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1819 &unsignedp, &reversep, &volatilep);
1821 if (bitpos % BITS_PER_UNIT != 0
1822 || bitsize != size_in_bytes * BITS_PER_UNIT)
1823 return;
1825 bool decl_p = DECL_P (inner);
1826 tree base;
1827 if (decl_p)
1829 if (DECL_REGISTER (inner))
1830 return;
1831 base = inner;
1833 else if (TREE_CODE (inner) == MEM_REF)
1834 base = TREE_OPERAND (inner, 0);
1835 else
1836 return;
1837 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1839 while (TREE_CODE (base) == SSA_NAME)
1841 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
1842 if (gimple_assign_ssa_name_copy_p (def_stmt)
1843 || (gimple_assign_cast_p (def_stmt)
1844 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1845 || (is_gimple_assign (def_stmt)
1846 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1848 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1849 if (TREE_CODE (rhs1) == SSA_NAME
1850 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1851 break;
1852 else
1853 base = rhs1;
1855 else
1856 break;
1859 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1860 return;
1862 tree sizet;
1863 tree base_addr = base;
1864 gimple *bos_stmt = NULL;
1865 if (decl_p)
1866 base_addr = build1 (ADDR_EXPR,
1867 build_pointer_type (TREE_TYPE (base)), base);
1868 unsigned HOST_WIDE_INT size;
1869 if (compute_builtin_object_size (base_addr, 0, &size))
1870 sizet = build_int_cst (sizetype, size);
1871 else if (optimize)
1873 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1874 loc = input_location;
1875 /* Generate __builtin_object_size call. */
1876 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1877 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1878 integer_zero_node);
1879 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1880 GSI_SAME_STMT);
1881 /* If the call above didn't end up being an integer constant, go one
1882 statement back and get the __builtin_object_size stmt. Save it,
1883 we might need it later. */
1884 if (SSA_VAR_P (sizet))
1886 gsi_prev (gsi);
1887 bos_stmt = gsi_stmt (*gsi);
1889 /* Move on to where we were. */
1890 gsi_next (gsi);
1893 else
1894 return;
1896 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1897 call. */
1898 /* ptr + sizeof (*ptr) - base */
1899 t = fold_build2 (MINUS_EXPR, sizetype,
1900 fold_convert (pointer_sized_int_node, ptr),
1901 fold_convert (pointer_sized_int_node, base_addr));
1902 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1904 /* Perhaps we can omit the check. */
1905 if (TREE_CODE (t) == INTEGER_CST
1906 && TREE_CODE (sizet) == INTEGER_CST
1907 && tree_int_cst_le (t, sizet))
1908 return;
1910 if (index != NULL_TREE
1911 && TREE_CODE (index) == SSA_NAME
1912 && TREE_CODE (sizet) == INTEGER_CST)
1914 gimple *def = SSA_NAME_DEF_STMT (index);
1915 if (is_gimple_assign (def)
1916 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1917 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1919 tree cst = gimple_assign_rhs2 (def);
1920 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1921 TYPE_SIZE_UNIT (type));
1922 if (tree_int_cst_sgn (cst) >= 0
1923 && tree_int_cst_lt (cst, sz))
1924 return;
1928 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1929 ubsan_create_edge (bos_stmt);
1931 /* We have to emit the check. */
1932 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1933 GSI_SAME_STMT);
1934 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1935 GSI_SAME_STMT);
1936 tree ckind = build_int_cst (unsigned_char_type_node,
1937 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1938 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1939 ptr, t, sizet, ckind);
1940 gimple_set_location (g, loc);
1941 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1944 namespace {
1946 const pass_data pass_data_ubsan =
1948 GIMPLE_PASS, /* type */
1949 "ubsan", /* name */
1950 OPTGROUP_NONE, /* optinfo_flags */
1951 TV_TREE_UBSAN, /* tv_id */
1952 ( PROP_cfg | PROP_ssa ), /* properties_required */
1953 0, /* properties_provided */
1954 0, /* properties_destroyed */
1955 0, /* todo_flags_start */
1956 TODO_update_ssa, /* todo_flags_finish */
1959 class pass_ubsan : public gimple_opt_pass
1961 public:
1962 pass_ubsan (gcc::context *ctxt)
1963 : gimple_opt_pass (pass_data_ubsan, ctxt)
1966 /* opt_pass methods: */
1967 virtual bool gate (function *)
1969 return sanitize_flags_p ((SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1970 | SANITIZE_BOOL | SANITIZE_ENUM
1971 | SANITIZE_ALIGNMENT
1972 | SANITIZE_NONNULL_ATTRIBUTE
1973 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1974 | SANITIZE_OBJECT_SIZE));
1977 virtual unsigned int execute (function *);
1979 }; // class pass_ubsan
1981 unsigned int
1982 pass_ubsan::execute (function *fun)
1984 basic_block bb;
1985 gimple_stmt_iterator gsi;
1986 unsigned int ret = 0;
1988 initialize_sanitizer_builtins ();
1990 FOR_EACH_BB_FN (bb, fun)
1992 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1994 gimple *stmt = gsi_stmt (gsi);
1995 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1997 gsi_next (&gsi);
1998 continue;
2001 if ((sanitize_flags_p (SANITIZE_SI_OVERFLOW, fun->decl))
2002 && is_gimple_assign (stmt))
2003 instrument_si_overflow (gsi);
2005 if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT, fun->decl))
2007 if (gimple_store_p (stmt))
2008 instrument_null (gsi, gimple_get_lhs (stmt), true);
2009 if (gimple_assign_single_p (stmt))
2010 instrument_null (gsi, gimple_assign_rhs1 (stmt), false);
2011 if (is_gimple_call (stmt))
2013 unsigned args_num = gimple_call_num_args (stmt);
2014 for (unsigned i = 0; i < args_num; ++i)
2016 tree arg = gimple_call_arg (stmt, i);
2017 if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2018 continue;
2019 instrument_null (gsi, arg, false);
2024 if (sanitize_flags_p (SANITIZE_BOOL | SANITIZE_ENUM, fun->decl)
2025 && gimple_assign_load_p (stmt))
2027 instrument_bool_enum_load (&gsi);
2028 bb = gimple_bb (stmt);
2031 if (sanitize_flags_p (SANITIZE_NONNULL_ATTRIBUTE, fun->decl)
2032 && is_gimple_call (stmt)
2033 && !gimple_call_internal_p (stmt))
2035 instrument_nonnull_arg (&gsi);
2036 bb = gimple_bb (stmt);
2039 if (sanitize_flags_p (SANITIZE_RETURNS_NONNULL_ATTRIBUTE, fun->decl)
2040 && gimple_code (stmt) == GIMPLE_RETURN)
2042 instrument_nonnull_return (&gsi);
2043 bb = gimple_bb (stmt);
2046 if (sanitize_flags_p (SANITIZE_OBJECT_SIZE, fun->decl))
2048 if (gimple_store_p (stmt))
2049 instrument_object_size (&gsi, gimple_get_lhs (stmt), true);
2050 if (gimple_assign_load_p (stmt))
2051 instrument_object_size (&gsi, gimple_assign_rhs1 (stmt),
2052 false);
2053 if (is_gimple_call (stmt))
2055 unsigned args_num = gimple_call_num_args (stmt);
2056 for (unsigned i = 0; i < args_num; ++i)
2058 tree arg = gimple_call_arg (stmt, i);
2059 if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2060 continue;
2061 instrument_object_size (&gsi, arg, false);
2066 gsi_next (&gsi);
2068 if (gimple_purge_dead_eh_edges (bb))
2069 ret = TODO_cleanup_cfg;
2071 return ret;
2074 } // anon namespace
2076 gimple_opt_pass *
2077 make_pass_ubsan (gcc::context *ctxt)
2079 return new pass_ubsan (ctxt);
2082 #include "gt-ubsan.h"