2015-12-18 Ville Voutilainen <ville.voutilainen@gmail.com>
[official-gcc.git] / gcc / ubsan.c
blob6fc6233c035edc3b0ada840daf817e6678c5c390
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2015 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "rtl.h"
26 #include "c-family/c-common.h"
27 #include "gimple.h"
28 #include "cfghooks.h"
29 #include "tree-pass.h"
30 #include "tm_p.h"
31 #include "ssa.h"
32 #include "cgraph.h"
33 #include "tree-pretty-print.h"
34 #include "stor-layout.h"
35 #include "cfganal.h"
36 #include "gimple-iterator.h"
37 #include "output.h"
38 #include "cfgloop.h"
39 #include "ubsan.h"
40 #include "expr.h"
41 #include "asan.h"
42 #include "gimplify-me.h"
43 #include "dfp.h"
44 #include "builtins.h"
45 #include "tree-object-size.h"
46 #include "tree-cfg.h"
48 /* Map from a tree to a VAR_DECL tree. */
50 struct GTY((for_user)) tree_type_map {
51 struct tree_map_base type;
52 tree decl;
55 struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
57 static inline hashval_t
58 hash (tree_type_map *t)
60 return TYPE_UID (t->type.from);
63 static inline bool
64 equal (tree_type_map *a, tree_type_map *b)
66 return a->type.from == b->type.from;
69 static int
70 keep_cache_entry (tree_type_map *&m)
72 return ggc_marked_p (m->type.from);
76 static GTY ((cache))
77 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
79 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
81 static tree
82 decl_for_type_lookup (tree type)
84 /* If the hash table is not initialized yet, create it now. */
85 if (decl_tree_for_type == NULL)
87 decl_tree_for_type
88 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
89 /* That also means we don't have to bother with the lookup. */
90 return NULL_TREE;
93 struct tree_type_map *h, in;
94 in.type.from = type;
96 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
97 return h ? h->decl : NULL_TREE;
100 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
102 static void
103 decl_for_type_insert (tree type, tree decl)
105 struct tree_type_map *h;
107 h = ggc_alloc<tree_type_map> ();
108 h->type.from = type;
109 h->decl = decl;
110 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
113 /* Helper routine, which encodes a value in the pointer_sized_int_node.
114 Arguments with precision <= POINTER_SIZE are passed directly,
115 the rest is passed by reference. T is a value we are to encode.
116 IN_EXPAND_P is true if this function is called during expansion. */
118 tree
119 ubsan_encode_value (tree t, bool in_expand_p)
121 tree type = TREE_TYPE (t);
122 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
123 if (bitsize <= POINTER_SIZE)
124 switch (TREE_CODE (type))
126 case BOOLEAN_TYPE:
127 case ENUMERAL_TYPE:
128 case INTEGER_TYPE:
129 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
130 case REAL_TYPE:
132 tree itype = build_nonstandard_integer_type (bitsize, true);
133 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
134 return fold_convert (pointer_sized_int_node, t);
136 default:
137 gcc_unreachable ();
139 else
141 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
143 /* The reason for this is that we don't want to pessimize
144 code by making vars unnecessarily addressable. */
145 tree var = create_tmp_var (type);
146 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
147 if (in_expand_p)
149 rtx mem
150 = assign_stack_temp_for_type (TYPE_MODE (type),
151 GET_MODE_SIZE (TYPE_MODE (type)),
152 type);
153 SET_DECL_RTL (var, mem);
154 expand_assignment (var, t, false);
155 return build_fold_addr_expr (var);
157 t = build_fold_addr_expr (var);
158 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
160 else
161 return build_fold_addr_expr (t);
165 /* Cached ubsan_get_type_descriptor_type () return value. */
166 static GTY(()) tree ubsan_type_descriptor_type;
168 /* Build
169 struct __ubsan_type_descriptor
171 unsigned short __typekind;
172 unsigned short __typeinfo;
173 char __typename[];
175 type. */
177 static tree
178 ubsan_get_type_descriptor_type (void)
180 static const char *field_names[3]
181 = { "__typekind", "__typeinfo", "__typename" };
182 tree fields[3], ret;
184 if (ubsan_type_descriptor_type)
185 return ubsan_type_descriptor_type;
187 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
188 tree flex_arr_type = build_array_type (char_type_node, itype);
190 ret = make_node (RECORD_TYPE);
191 for (int i = 0; i < 3; i++)
193 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
194 get_identifier (field_names[i]),
195 (i == 2) ? flex_arr_type
196 : short_unsigned_type_node);
197 DECL_CONTEXT (fields[i]) = ret;
198 if (i)
199 DECL_CHAIN (fields[i - 1]) = fields[i];
201 tree type_decl = build_decl (input_location, TYPE_DECL,
202 get_identifier ("__ubsan_type_descriptor"),
203 ret);
204 DECL_IGNORED_P (type_decl) = 1;
205 DECL_ARTIFICIAL (type_decl) = 1;
206 TYPE_FIELDS (ret) = fields[0];
207 TYPE_NAME (ret) = type_decl;
208 TYPE_STUB_DECL (ret) = type_decl;
209 layout_type (ret);
210 ubsan_type_descriptor_type = ret;
211 return ret;
214 /* Cached ubsan_get_source_location_type () return value. */
215 static GTY(()) tree ubsan_source_location_type;
217 /* Build
218 struct __ubsan_source_location
220 const char *__filename;
221 unsigned int __line;
222 unsigned int __column;
224 type. */
226 tree
227 ubsan_get_source_location_type (void)
229 static const char *field_names[3]
230 = { "__filename", "__line", "__column" };
231 tree fields[3], ret;
232 if (ubsan_source_location_type)
233 return ubsan_source_location_type;
235 tree const_char_type = build_qualified_type (char_type_node,
236 TYPE_QUAL_CONST);
238 ret = make_node (RECORD_TYPE);
239 for (int i = 0; i < 3; i++)
241 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
242 get_identifier (field_names[i]),
243 (i == 0) ? build_pointer_type (const_char_type)
244 : unsigned_type_node);
245 DECL_CONTEXT (fields[i]) = ret;
246 if (i)
247 DECL_CHAIN (fields[i - 1]) = fields[i];
249 tree type_decl = build_decl (input_location, TYPE_DECL,
250 get_identifier ("__ubsan_source_location"),
251 ret);
252 DECL_IGNORED_P (type_decl) = 1;
253 DECL_ARTIFICIAL (type_decl) = 1;
254 TYPE_FIELDS (ret) = fields[0];
255 TYPE_NAME (ret) = type_decl;
256 TYPE_STUB_DECL (ret) = type_decl;
257 layout_type (ret);
258 ubsan_source_location_type = ret;
259 return ret;
262 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
263 type with its fields filled from a location_t LOC. */
265 static tree
266 ubsan_source_location (location_t loc)
268 expanded_location xloc;
269 tree type = ubsan_get_source_location_type ();
271 xloc = expand_location (loc);
272 tree str;
273 if (xloc.file == NULL)
275 str = build_int_cst (ptr_type_node, 0);
276 xloc.line = 0;
277 xloc.column = 0;
279 else
281 /* Fill in the values from LOC. */
282 size_t len = strlen (xloc.file) + 1;
283 str = build_string (len, xloc.file);
284 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
285 TREE_READONLY (str) = 1;
286 TREE_STATIC (str) = 1;
287 str = build_fold_addr_expr (str);
289 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
290 build_int_cst (unsigned_type_node,
291 xloc.line), NULL_TREE,
292 build_int_cst (unsigned_type_node,
293 xloc.column));
294 TREE_CONSTANT (ctor) = 1;
295 TREE_STATIC (ctor) = 1;
297 return ctor;
300 /* This routine returns a magic number for TYPE. */
302 static unsigned short
303 get_ubsan_type_info_for_type (tree type)
305 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
306 if (TREE_CODE (type) == REAL_TYPE)
307 return tree_to_uhwi (TYPE_SIZE (type));
308 else if (INTEGRAL_TYPE_P (type))
310 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
311 gcc_assert (prec != -1);
312 return (prec << 1) | !TYPE_UNSIGNED (type);
314 else
315 return 0;
318 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
319 descriptor. It first looks into the hash table; if not found,
320 create the VAR_DECL, put it into the hash table and return the
321 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
322 an enum controlling how we want to print the type. */
324 tree
325 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
327 /* See through any typedefs. */
328 type = TYPE_MAIN_VARIANT (type);
330 tree decl = decl_for_type_lookup (type);
331 /* It is possible that some of the earlier created DECLs were found
332 unused, in that case they weren't emitted and varpool_node::get
333 returns NULL node on them. But now we really need them. Thus,
334 renew them here. */
335 if (decl != NULL_TREE && varpool_node::get (decl))
336 return build_fold_addr_expr (decl);
338 tree dtype = ubsan_get_type_descriptor_type ();
339 tree type2 = type;
340 const char *tname = NULL;
341 pretty_printer pretty_name;
342 unsigned char deref_depth = 0;
343 unsigned short tkind, tinfo;
345 /* Get the name of the type, or the name of the pointer type. */
346 if (pstyle == UBSAN_PRINT_POINTER)
348 gcc_assert (POINTER_TYPE_P (type));
349 type2 = TREE_TYPE (type);
351 /* Remove any '*' operators from TYPE. */
352 while (POINTER_TYPE_P (type2))
353 deref_depth++, type2 = TREE_TYPE (type2);
355 if (TREE_CODE (type2) == METHOD_TYPE)
356 type2 = TYPE_METHOD_BASETYPE (type2);
359 /* If an array, get its type. */
360 type2 = strip_array_types (type2);
362 if (pstyle == UBSAN_PRINT_ARRAY)
364 while (POINTER_TYPE_P (type2))
365 deref_depth++, type2 = TREE_TYPE (type2);
368 if (TYPE_NAME (type2) != NULL)
370 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
371 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
372 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
373 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
376 if (tname == NULL)
377 /* We weren't able to determine the type name. */
378 tname = "<unknown>";
380 if (pstyle == UBSAN_PRINT_POINTER)
382 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
383 TYPE_VOLATILE (type2) ? "volatile " : "",
384 TYPE_READONLY (type2) ? "const " : "",
385 TYPE_RESTRICT (type2) ? "restrict " : "",
386 TYPE_ATOMIC (type2) ? "_Atomic " : "",
387 TREE_CODE (type2) == RECORD_TYPE
388 ? "struct "
389 : TREE_CODE (type2) == UNION_TYPE
390 ? "union " : "", tname,
391 deref_depth == 0 ? "" : " ");
392 while (deref_depth-- > 0)
393 pp_star (&pretty_name);
394 pp_quote (&pretty_name);
396 else if (pstyle == UBSAN_PRINT_ARRAY)
398 /* Pretty print the array dimensions. */
399 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
400 tree t = type;
401 pp_printf (&pretty_name, "'%s ", tname);
402 while (deref_depth-- > 0)
403 pp_star (&pretty_name);
404 while (TREE_CODE (t) == ARRAY_TYPE)
406 pp_left_bracket (&pretty_name);
407 tree dom = TYPE_DOMAIN (t);
408 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
410 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
411 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
412 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
413 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
414 else
415 pp_wide_int (&pretty_name,
416 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
417 TYPE_SIGN (TREE_TYPE (dom)));
419 else
420 /* ??? We can't determine the variable name; print VLA unspec. */
421 pp_star (&pretty_name);
422 pp_right_bracket (&pretty_name);
423 t = TREE_TYPE (t);
425 pp_quote (&pretty_name);
427 /* Save the tree with stripped types. */
428 type = t;
430 else
431 pp_printf (&pretty_name, "'%s'", tname);
433 switch (TREE_CODE (type))
435 case BOOLEAN_TYPE:
436 case ENUMERAL_TYPE:
437 case INTEGER_TYPE:
438 tkind = 0x0000;
439 break;
440 case REAL_TYPE:
441 /* FIXME: libubsan right now only supports float, double and
442 long double type formats. */
443 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
444 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
445 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
446 tkind = 0x0001;
447 else
448 tkind = 0xffff;
449 break;
450 default:
451 tkind = 0xffff;
452 break;
454 tinfo = get_ubsan_type_info_for_type (type);
456 /* Create a new VAR_DECL of type descriptor. */
457 const char *tmp = pp_formatted_text (&pretty_name);
458 size_t len = strlen (tmp) + 1;
459 tree str = build_string (len, tmp);
460 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
461 TREE_READONLY (str) = 1;
462 TREE_STATIC (str) = 1;
464 char tmp_name[32];
465 static unsigned int type_var_id_num;
466 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
467 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
468 dtype);
469 TREE_STATIC (decl) = 1;
470 TREE_PUBLIC (decl) = 0;
471 DECL_ARTIFICIAL (decl) = 1;
472 DECL_IGNORED_P (decl) = 1;
473 DECL_EXTERNAL (decl) = 0;
474 DECL_SIZE (decl)
475 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
476 DECL_SIZE_UNIT (decl)
477 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
478 TYPE_SIZE_UNIT (TREE_TYPE (str)));
480 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
481 build_int_cst (short_unsigned_type_node,
482 tkind), NULL_TREE,
483 build_int_cst (short_unsigned_type_node,
484 tinfo), NULL_TREE, str);
485 TREE_CONSTANT (ctor) = 1;
486 TREE_STATIC (ctor) = 1;
487 DECL_INITIAL (decl) = ctor;
488 varpool_node::finalize_decl (decl);
490 /* Save the VAR_DECL into the hash table. */
491 decl_for_type_insert (type, decl);
493 return build_fold_addr_expr (decl);
496 /* Create a structure for the ubsan library. NAME is a name of the new
497 structure. LOCCNT is number of locations, PLOC points to array of
498 locations. The arguments in ... are of __ubsan_type_descriptor type
499 and there are at most two of them, followed by NULL_TREE, followed
500 by optional extra arguments and another NULL_TREE. */
502 tree
503 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
505 va_list args;
506 tree ret, t;
507 tree fields[6];
508 vec<tree, va_gc> *saved_args = NULL;
509 size_t i = 0;
510 int j;
512 /* Firstly, create a pointer to type descriptor type. */
513 tree td_type = ubsan_get_type_descriptor_type ();
514 td_type = build_pointer_type (td_type);
516 /* Create the structure type. */
517 ret = make_node (RECORD_TYPE);
518 for (j = 0; j < loccnt; j++)
520 gcc_checking_assert (i < 2);
521 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
522 ubsan_get_source_location_type ());
523 DECL_CONTEXT (fields[i]) = ret;
524 if (i)
525 DECL_CHAIN (fields[i - 1]) = fields[i];
526 i++;
529 va_start (args, ploc);
530 for (t = va_arg (args, tree); t != NULL_TREE;
531 i++, t = va_arg (args, tree))
533 gcc_checking_assert (i < 4);
534 /* Save the tree arguments for later use. */
535 vec_safe_push (saved_args, t);
536 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
537 td_type);
538 DECL_CONTEXT (fields[i]) = ret;
539 if (i)
540 DECL_CHAIN (fields[i - 1]) = fields[i];
543 for (t = va_arg (args, tree); t != NULL_TREE;
544 i++, t = va_arg (args, tree))
546 gcc_checking_assert (i < 6);
547 /* Save the tree arguments for later use. */
548 vec_safe_push (saved_args, t);
549 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
550 TREE_TYPE (t));
551 DECL_CONTEXT (fields[i]) = ret;
552 if (i)
553 DECL_CHAIN (fields[i - 1]) = fields[i];
555 va_end (args);
557 tree type_decl = build_decl (input_location, TYPE_DECL,
558 get_identifier (name), ret);
559 DECL_IGNORED_P (type_decl) = 1;
560 DECL_ARTIFICIAL (type_decl) = 1;
561 TYPE_FIELDS (ret) = fields[0];
562 TYPE_NAME (ret) = type_decl;
563 TYPE_STUB_DECL (ret) = type_decl;
564 layout_type (ret);
566 /* Now, fill in the type. */
567 char tmp_name[32];
568 static unsigned int ubsan_var_id_num;
569 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
570 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
571 ret);
572 TREE_STATIC (var) = 1;
573 TREE_PUBLIC (var) = 0;
574 DECL_ARTIFICIAL (var) = 1;
575 DECL_IGNORED_P (var) = 1;
576 DECL_EXTERNAL (var) = 0;
578 vec<constructor_elt, va_gc> *v;
579 vec_alloc (v, i);
580 tree ctor = build_constructor (ret, v);
582 /* If desirable, set the __ubsan_source_location element. */
583 for (j = 0; j < loccnt; j++)
585 location_t loc = LOCATION_LOCUS (ploc[j]);
586 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
589 size_t nelts = vec_safe_length (saved_args);
590 for (i = 0; i < nelts; i++)
592 t = (*saved_args)[i];
593 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
596 TREE_CONSTANT (ctor) = 1;
597 TREE_STATIC (ctor) = 1;
598 DECL_INITIAL (var) = ctor;
599 varpool_node::finalize_decl (var);
601 return var;
604 /* Instrument the __builtin_unreachable call. We just call the libubsan
605 routine instead. */
607 bool
608 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
610 gimple *g;
611 location_t loc = gimple_location (gsi_stmt (*gsi));
613 if (flag_sanitize_undefined_trap_on_error)
614 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
615 else
617 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
618 NULL_TREE, NULL_TREE);
619 data = build_fold_addr_expr_loc (loc, data);
620 tree fn
621 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
622 g = gimple_build_call (fn, 1, data);
624 gimple_set_location (g, loc);
625 gsi_replace (gsi, g, false);
626 return false;
629 /* Return true if T is a call to a libubsan routine. */
631 bool
632 is_ubsan_builtin_p (tree t)
634 return TREE_CODE (t) == FUNCTION_DECL
635 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
636 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
637 "__builtin___ubsan_", 18) == 0;
640 /* Create a callgraph edge for statement STMT. */
642 static void
643 ubsan_create_edge (gimple *stmt)
645 gcall *call_stmt = dyn_cast <gcall *> (stmt);
646 basic_block bb = gimple_bb (stmt);
647 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
648 cgraph_node *node = cgraph_node::get (current_function_decl);
649 tree decl = gimple_call_fndecl (call_stmt);
650 if (decl)
651 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
652 freq);
655 /* Expand the UBSAN_BOUNDS special builtin function. */
657 bool
658 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
660 gimple *stmt = gsi_stmt (*gsi);
661 location_t loc = gimple_location (stmt);
662 gcc_assert (gimple_call_num_args (stmt) == 3);
664 /* Pick up the arguments of the UBSAN_BOUNDS call. */
665 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
666 tree index = gimple_call_arg (stmt, 1);
667 tree orig_index_type = TREE_TYPE (index);
668 tree bound = gimple_call_arg (stmt, 2);
670 gimple_stmt_iterator gsi_orig = *gsi;
672 /* Create condition "if (index > bound)". */
673 basic_block then_bb, fallthru_bb;
674 gimple_stmt_iterator cond_insert_point
675 = create_cond_insert_point (gsi, false, false, true,
676 &then_bb, &fallthru_bb);
677 index = fold_convert (TREE_TYPE (bound), index);
678 index = force_gimple_operand_gsi (&cond_insert_point, index,
679 true, NULL_TREE,
680 false, GSI_NEW_STMT);
681 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
682 gimple_set_location (g, loc);
683 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
685 /* Generate __ubsan_handle_out_of_bounds call. */
686 *gsi = gsi_after_labels (then_bb);
687 if (flag_sanitize_undefined_trap_on_error)
688 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
689 else
691 tree data
692 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
693 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
694 ubsan_type_descriptor (orig_index_type),
695 NULL_TREE, NULL_TREE);
696 data = build_fold_addr_expr_loc (loc, data);
697 enum built_in_function bcode
698 = (flag_sanitize_recover & SANITIZE_BOUNDS)
699 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
700 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
701 tree fn = builtin_decl_explicit (bcode);
702 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
703 true, NULL_TREE, true,
704 GSI_SAME_STMT);
705 g = gimple_build_call (fn, 2, data, val);
707 gimple_set_location (g, loc);
708 gsi_insert_before (gsi, g, GSI_SAME_STMT);
710 /* Get rid of the UBSAN_BOUNDS call from the IR. */
711 unlink_stmt_vdef (stmt);
712 gsi_remove (&gsi_orig, true);
714 /* Point GSI to next logical statement. */
715 *gsi = gsi_start_bb (fallthru_bb);
716 return true;
719 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
720 argument which is a constant, because the middle-end treats pointer
721 conversions as useless and therefore the type of the first argument
722 could be changed to any other pointer type. */
724 bool
725 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
727 gimple_stmt_iterator gsi = *gsip;
728 gimple *stmt = gsi_stmt (gsi);
729 location_t loc = gimple_location (stmt);
730 gcc_assert (gimple_call_num_args (stmt) == 3);
731 tree ptr = gimple_call_arg (stmt, 0);
732 tree ckind = gimple_call_arg (stmt, 1);
733 tree align = gimple_call_arg (stmt, 2);
734 tree check_align = NULL_TREE;
735 bool check_null;
737 basic_block cur_bb = gsi_bb (gsi);
739 gimple *g;
740 if (!integer_zerop (align))
742 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
743 if (compare_tree_int (align, ptralign) == 1)
745 check_align = make_ssa_name (pointer_sized_int_node);
746 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
747 gimple_set_location (g, loc);
748 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
751 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
753 if (check_align == NULL_TREE && !check_null)
755 gsi_remove (gsip, true);
756 /* Unlink the UBSAN_NULLs vops before replacing it. */
757 unlink_stmt_vdef (stmt);
758 return true;
761 /* Split the original block holding the pointer dereference. */
762 edge e = split_block (cur_bb, stmt);
764 /* Get a hold on the 'condition block', the 'then block' and the
765 'else block'. */
766 basic_block cond_bb = e->src;
767 basic_block fallthru_bb = e->dest;
768 basic_block then_bb = create_empty_bb (cond_bb);
769 add_bb_to_loop (then_bb, cond_bb->loop_father);
770 loops_state_set (LOOPS_NEED_FIXUP);
772 /* Make an edge coming from the 'cond block' into the 'then block';
773 this edge is unlikely taken, so set up the probability accordingly. */
774 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
775 e->probability = PROB_VERY_UNLIKELY;
777 /* Connect 'then block' with the 'else block'. This is needed
778 as the ubsan routines we call in the 'then block' are not noreturn.
779 The 'then block' only has one outcoming edge. */
780 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
782 /* Set up the fallthrough basic block. */
783 e = find_edge (cond_bb, fallthru_bb);
784 e->flags = EDGE_FALSE_VALUE;
785 e->count = cond_bb->count;
786 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
788 /* Update dominance info for the newly created then_bb; note that
789 fallthru_bb's dominance info has already been updated by
790 split_block. */
791 if (dom_info_available_p (CDI_DOMINATORS))
792 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
794 /* Put the ubsan builtin call into the newly created BB. */
795 if (flag_sanitize_undefined_trap_on_error)
796 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
797 else
799 enum built_in_function bcode
800 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
801 | (check_null ? SANITIZE_NULL : 0)))
802 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
803 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
804 tree fn = builtin_decl_implicit (bcode);
805 tree data
806 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
807 ubsan_type_descriptor (TREE_TYPE (ckind),
808 UBSAN_PRINT_POINTER),
809 NULL_TREE,
810 align,
811 fold_convert (unsigned_char_type_node, ckind),
812 NULL_TREE);
813 data = build_fold_addr_expr_loc (loc, data);
814 g = gimple_build_call (fn, 2, data,
815 check_align ? check_align
816 : build_zero_cst (pointer_sized_int_node));
818 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
819 gimple_set_location (g, loc);
820 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
822 /* Unlink the UBSAN_NULLs vops before replacing it. */
823 unlink_stmt_vdef (stmt);
825 if (check_null)
827 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
828 NULL_TREE, NULL_TREE);
829 gimple_set_location (g, loc);
831 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
832 gsi_replace (&gsi, g, false);
833 stmt = g;
836 if (check_align)
838 if (check_null)
840 /* Split the block with the condition again. */
841 e = split_block (cond_bb, stmt);
842 basic_block cond1_bb = e->src;
843 basic_block cond2_bb = e->dest;
845 /* Make an edge coming from the 'cond1 block' into the 'then block';
846 this edge is unlikely taken, so set up the probability
847 accordingly. */
848 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
849 e->probability = PROB_VERY_UNLIKELY;
851 /* Set up the fallthrough basic block. */
852 e = find_edge (cond1_bb, cond2_bb);
853 e->flags = EDGE_FALSE_VALUE;
854 e->count = cond1_bb->count;
855 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
857 /* Update dominance info. */
858 if (dom_info_available_p (CDI_DOMINATORS))
860 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
861 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
864 gsi2 = gsi_start_bb (cond2_bb);
867 tree mask = build_int_cst (pointer_sized_int_node,
868 tree_to_uhwi (align) - 1);
869 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
870 BIT_AND_EXPR, check_align, mask);
871 gimple_set_location (g, loc);
872 if (check_null)
873 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
874 else
875 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
877 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
878 build_int_cst (pointer_sized_int_node, 0),
879 NULL_TREE, NULL_TREE);
880 gimple_set_location (g, loc);
881 if (check_null)
882 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
883 else
884 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
885 gsi_replace (&gsi, g, false);
887 return false;
890 #define OBJSZ_MAX_OFFSET (1024 * 16)
892 /* Expand UBSAN_OBJECT_SIZE internal call. */
894 bool
895 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
897 gimple *stmt = gsi_stmt (*gsi);
898 location_t loc = gimple_location (stmt);
899 gcc_assert (gimple_call_num_args (stmt) == 4);
901 tree ptr = gimple_call_arg (stmt, 0);
902 tree offset = gimple_call_arg (stmt, 1);
903 tree size = gimple_call_arg (stmt, 2);
904 tree ckind = gimple_call_arg (stmt, 3);
905 gimple_stmt_iterator gsi_orig = *gsi;
906 gimple *g;
908 /* See if we can discard the check. */
909 if (TREE_CODE (size) != INTEGER_CST
910 || integer_all_onesp (size))
911 /* Yes, __builtin_object_size couldn't determine the
912 object size. */;
913 else if (TREE_CODE (offset) == INTEGER_CST
914 && wi::ges_p (wi::to_widest (offset), -OBJSZ_MAX_OFFSET)
915 && wi::les_p (wi::to_widest (offset), -1))
916 /* The offset is in range [-16K, -1]. */;
917 else
919 /* if (offset > objsize) */
920 basic_block then_bb, fallthru_bb;
921 gimple_stmt_iterator cond_insert_point
922 = create_cond_insert_point (gsi, false, false, true,
923 &then_bb, &fallthru_bb);
924 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
925 gimple_set_location (g, loc);
926 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
928 /* If the offset is small enough, we don't need the second
929 run-time check. */
930 if (TREE_CODE (offset) == INTEGER_CST
931 && wi::ges_p (wi::to_widest (offset), 0)
932 && wi::les_p (wi::to_widest (offset), OBJSZ_MAX_OFFSET))
933 *gsi = gsi_after_labels (then_bb);
934 else
936 /* Don't issue run-time error if (ptr > ptr + offset). That
937 may happen when computing a POINTER_PLUS_EXPR. */
938 basic_block then2_bb, fallthru2_bb;
940 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
941 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
942 true, &then2_bb,
943 &fallthru2_bb);
944 /* Convert the pointer to an integer type. */
945 tree p = make_ssa_name (pointer_sized_int_node);
946 g = gimple_build_assign (p, NOP_EXPR, ptr);
947 gimple_set_location (g, loc);
948 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
949 p = gimple_assign_lhs (g);
950 /* Compute ptr + offset. */
951 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
952 PLUS_EXPR, p, offset);
953 gimple_set_location (g, loc);
954 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
955 /* Now build the conditional and put it into the IR. */
956 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
957 NULL_TREE, NULL_TREE);
958 gimple_set_location (g, loc);
959 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
960 *gsi = gsi_after_labels (then2_bb);
963 /* Generate __ubsan_handle_type_mismatch call. */
964 if (flag_sanitize_undefined_trap_on_error)
965 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
966 else
968 tree data
969 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
970 ubsan_type_descriptor (TREE_TYPE (ptr),
971 UBSAN_PRINT_POINTER),
972 NULL_TREE,
973 build_zero_cst (pointer_sized_int_node),
974 ckind,
975 NULL_TREE);
976 data = build_fold_addr_expr_loc (loc, data);
977 enum built_in_function bcode
978 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
979 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
980 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
981 tree p = make_ssa_name (pointer_sized_int_node);
982 g = gimple_build_assign (p, NOP_EXPR, ptr);
983 gimple_set_location (g, loc);
984 gsi_insert_before (gsi, g, GSI_SAME_STMT);
985 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
987 gimple_set_location (g, loc);
988 gsi_insert_before (gsi, g, GSI_SAME_STMT);
990 /* Point GSI to next logical statement. */
991 *gsi = gsi_start_bb (fallthru_bb);
993 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
994 unlink_stmt_vdef (stmt);
995 gsi_remove (&gsi_orig, true);
996 return true;
999 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1000 unlink_stmt_vdef (stmt);
1001 gsi_remove (gsi, true);
1002 return true;
1005 /* Cached __ubsan_vptr_type_cache decl. */
1006 static GTY(()) tree ubsan_vptr_type_cache_decl;
1008 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1009 argument which is a constant, because the middle-end treats pointer
1010 conversions as useless and therefore the type of the first argument
1011 could be changed to any other pointer type. */
1013 bool
1014 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1016 gimple_stmt_iterator gsi = *gsip;
1017 gimple *stmt = gsi_stmt (gsi);
1018 location_t loc = gimple_location (stmt);
1019 gcc_assert (gimple_call_num_args (stmt) == 5);
1020 tree op = gimple_call_arg (stmt, 0);
1021 tree vptr = gimple_call_arg (stmt, 1);
1022 tree str_hash = gimple_call_arg (stmt, 2);
1023 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1024 tree ckind_tree = gimple_call_arg (stmt, 4);
1025 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1026 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1027 gimple *g;
1028 basic_block fallthru_bb = NULL;
1030 if (ckind == UBSAN_DOWNCAST_POINTER)
1032 /* Guard everything with if (op != NULL) { ... }. */
1033 basic_block then_bb;
1034 gimple_stmt_iterator cond_insert_point
1035 = create_cond_insert_point (gsip, false, false, true,
1036 &then_bb, &fallthru_bb);
1037 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1038 NULL_TREE, NULL_TREE);
1039 gimple_set_location (g, loc);
1040 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1041 *gsip = gsi_after_labels (then_bb);
1042 gsi_remove (&gsi, false);
1043 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1044 gsi = *gsip;
1047 tree htype = TREE_TYPE (str_hash);
1048 tree cst = wide_int_to_tree (htype,
1049 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1050 | 0xeb382d69, 64));
1051 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1052 vptr, str_hash);
1053 gimple_set_location (g, loc);
1054 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1055 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1056 gimple_assign_lhs (g), cst);
1057 gimple_set_location (g, loc);
1058 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1059 tree t1 = gimple_assign_lhs (g);
1060 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1061 t1, build_int_cst (integer_type_node, 47));
1062 gimple_set_location (g, loc);
1063 tree t2 = gimple_assign_lhs (g);
1064 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1065 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1066 vptr, t1);
1067 gimple_set_location (g, loc);
1068 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1069 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1070 t2, gimple_assign_lhs (g));
1071 gimple_set_location (g, loc);
1072 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1073 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1074 gimple_assign_lhs (g), cst);
1075 gimple_set_location (g, loc);
1076 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1077 tree t3 = gimple_assign_lhs (g);
1078 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1079 t3, build_int_cst (integer_type_node, 47));
1080 gimple_set_location (g, loc);
1081 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1082 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1083 t3, gimple_assign_lhs (g));
1084 gimple_set_location (g, loc);
1085 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1086 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1087 gimple_assign_lhs (g), cst);
1088 gimple_set_location (g, loc);
1089 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1090 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1092 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1093 NOP_EXPR, gimple_assign_lhs (g));
1094 gimple_set_location (g, loc);
1095 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1097 tree hash = gimple_assign_lhs (g);
1099 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1101 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1102 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1103 get_identifier ("__ubsan_vptr_type_cache"),
1104 atype);
1105 DECL_ARTIFICIAL (array) = 1;
1106 DECL_IGNORED_P (array) = 1;
1107 TREE_PUBLIC (array) = 1;
1108 TREE_STATIC (array) = 1;
1109 DECL_EXTERNAL (array) = 1;
1110 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1111 DECL_VISIBILITY_SPECIFIED (array) = 1;
1112 varpool_node::finalize_decl (array);
1113 ubsan_vptr_type_cache_decl = array;
1116 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1117 BIT_AND_EXPR, hash,
1118 build_int_cst (pointer_sized_int_node, 127));
1119 gimple_set_location (g, loc);
1120 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1122 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1123 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1124 NULL_TREE, NULL_TREE);
1125 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1126 ARRAY_REF, c);
1127 gimple_set_location (g, loc);
1128 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1130 basic_block then_bb, fallthru2_bb;
1131 gimple_stmt_iterator cond_insert_point
1132 = create_cond_insert_point (gsip, false, false, true,
1133 &then_bb, &fallthru2_bb);
1134 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1135 NULL_TREE, NULL_TREE);
1136 gimple_set_location (g, loc);
1137 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1138 *gsip = gsi_after_labels (then_bb);
1139 if (fallthru_bb == NULL)
1140 fallthru_bb = fallthru2_bb;
1142 tree data
1143 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1144 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1145 build_int_cst (unsigned_char_type_node, ckind),
1146 NULL_TREE);
1147 data = build_fold_addr_expr_loc (loc, data);
1148 enum built_in_function bcode
1149 = (flag_sanitize_recover & SANITIZE_VPTR)
1150 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1151 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1153 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1154 gimple_set_location (g, loc);
1155 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1157 /* Point GSI to next logical statement. */
1158 *gsip = gsi_start_bb (fallthru_bb);
1160 /* Get rid of the UBSAN_VPTR call from the IR. */
1161 unlink_stmt_vdef (stmt);
1162 gsi_remove (&gsi, true);
1163 return true;
1166 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1167 whether the pointer is on the left hand side of the assignment. */
1169 static void
1170 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1171 bool is_lhs)
1173 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1174 unsigned int align = 0;
1175 if (flag_sanitize & SANITIZE_ALIGNMENT)
1177 align = min_align_of_type (TREE_TYPE (base));
1178 if (align <= 1)
1179 align = 0;
1181 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1182 return;
1183 tree t = TREE_OPERAND (base, 0);
1184 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1185 return;
1186 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1187 ikind = UBSAN_MEMBER_ACCESS;
1188 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1189 tree alignt = build_int_cst (pointer_sized_int_node, align);
1190 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1191 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1192 gsi_insert_before (iter, g, GSI_SAME_STMT);
1195 /* Perform the pointer instrumentation. */
1197 static void
1198 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1200 gimple *stmt = gsi_stmt (gsi);
1201 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1202 tree base = get_base_address (t);
1203 const enum tree_code code = TREE_CODE (base);
1204 if (code == MEM_REF
1205 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1206 instrument_mem_ref (t, base, &gsi, is_lhs);
1209 /* Build an ubsan builtin call for the signed-integer-overflow
1210 sanitization. CODE says what kind of builtin are we building,
1211 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1212 are operands of the binary operation. */
1214 tree
1215 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1216 tree op0, tree op1)
1218 if (flag_sanitize_undefined_trap_on_error)
1219 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1221 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1222 ubsan_type_descriptor (lhstype), NULL_TREE,
1223 NULL_TREE);
1224 enum built_in_function fn_code;
1226 switch (code)
1228 case PLUS_EXPR:
1229 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1230 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1231 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1232 break;
1233 case MINUS_EXPR:
1234 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1235 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1236 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1237 break;
1238 case MULT_EXPR:
1239 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1240 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1241 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1242 break;
1243 case NEGATE_EXPR:
1244 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1245 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1246 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1247 break;
1248 default:
1249 gcc_unreachable ();
1251 tree fn = builtin_decl_explicit (fn_code);
1252 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1253 build_fold_addr_expr_loc (loc, data),
1254 ubsan_encode_value (op0, true),
1255 op1 ? ubsan_encode_value (op1, true)
1256 : NULL_TREE);
1259 /* Perform the signed integer instrumentation. GSI is the iterator
1260 pointing at statement we are trying to instrument. */
1262 static void
1263 instrument_si_overflow (gimple_stmt_iterator gsi)
1265 gimple *stmt = gsi_stmt (gsi);
1266 tree_code code = gimple_assign_rhs_code (stmt);
1267 tree lhs = gimple_assign_lhs (stmt);
1268 tree lhstype = TREE_TYPE (lhs);
1269 tree a, b;
1270 gimple *g;
1272 /* If this is not a signed operation, don't instrument anything here.
1273 Also punt on bit-fields. */
1274 if (!INTEGRAL_TYPE_P (lhstype)
1275 || TYPE_OVERFLOW_WRAPS (lhstype)
1276 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1277 return;
1279 switch (code)
1281 case MINUS_EXPR:
1282 case PLUS_EXPR:
1283 case MULT_EXPR:
1284 /* Transform
1285 i = u {+,-,*} 5;
1286 into
1287 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1288 a = gimple_assign_rhs1 (stmt);
1289 b = gimple_assign_rhs2 (stmt);
1290 g = gimple_build_call_internal (code == PLUS_EXPR
1291 ? IFN_UBSAN_CHECK_ADD
1292 : code == MINUS_EXPR
1293 ? IFN_UBSAN_CHECK_SUB
1294 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1295 gimple_call_set_lhs (g, lhs);
1296 gsi_replace (&gsi, g, false);
1297 break;
1298 case NEGATE_EXPR:
1299 /* Represent i = -u;
1301 i = UBSAN_CHECK_SUB (0, u); */
1302 a = build_int_cst (lhstype, 0);
1303 b = gimple_assign_rhs1 (stmt);
1304 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1305 gimple_call_set_lhs (g, lhs);
1306 gsi_replace (&gsi, g, false);
1307 break;
1308 case ABS_EXPR:
1309 /* Transform i = ABS_EXPR<u>;
1310 into
1311 _N = UBSAN_CHECK_SUB (0, u);
1312 i = ABS_EXPR<_N>; */
1313 a = build_int_cst (lhstype, 0);
1314 b = gimple_assign_rhs1 (stmt);
1315 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1316 a = make_ssa_name (lhstype);
1317 gimple_call_set_lhs (g, a);
1318 gimple_set_location (g, gimple_location (stmt));
1319 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1320 gimple_assign_set_rhs1 (stmt, a);
1321 update_stmt (stmt);
1322 break;
1323 default:
1324 break;
1328 /* Instrument loads from (non-bitfield) bool and C++ enum values
1329 to check if the memory value is outside of the range of the valid
1330 type values. */
1332 static void
1333 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1335 gimple *stmt = gsi_stmt (*gsi);
1336 tree rhs = gimple_assign_rhs1 (stmt);
1337 tree type = TREE_TYPE (rhs);
1338 tree minv = NULL_TREE, maxv = NULL_TREE;
1340 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1342 minv = boolean_false_node;
1343 maxv = boolean_true_node;
1345 else if (TREE_CODE (type) == ENUMERAL_TYPE
1346 && (flag_sanitize & SANITIZE_ENUM)
1347 && TREE_TYPE (type) != NULL_TREE
1348 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1349 && (TYPE_PRECISION (TREE_TYPE (type))
1350 < GET_MODE_PRECISION (TYPE_MODE (type))))
1352 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1353 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1355 else
1356 return;
1358 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1359 HOST_WIDE_INT bitsize, bitpos;
1360 tree offset;
1361 machine_mode mode;
1362 int volatilep = 0, reversep, unsignedp = 0;
1363 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1364 &unsignedp, &reversep, &volatilep, false);
1365 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1367 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1368 || (bitpos % modebitsize) != 0
1369 || bitsize != modebitsize
1370 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1371 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1372 return;
1374 bool ends_bb = stmt_ends_bb_p (stmt);
1375 location_t loc = gimple_location (stmt);
1376 tree lhs = gimple_assign_lhs (stmt);
1377 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1378 tree atype = reference_alias_ptr_type (rhs);
1379 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1380 build_fold_addr_expr (rhs));
1381 gimple_set_location (g, loc);
1382 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1383 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1384 build_int_cst (atype, 0));
1385 tree urhs = make_ssa_name (utype);
1386 if (ends_bb)
1388 gimple_assign_set_lhs (stmt, urhs);
1389 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1390 gimple_set_location (g, loc);
1391 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1392 gsi_insert_on_edge_immediate (e, g);
1393 gimple_assign_set_rhs_from_tree (gsi, mem);
1394 update_stmt (stmt);
1395 *gsi = gsi_for_stmt (g);
1396 g = stmt;
1398 else
1400 g = gimple_build_assign (urhs, mem);
1401 gimple_set_location (g, loc);
1402 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1404 minv = fold_convert (utype, minv);
1405 maxv = fold_convert (utype, maxv);
1406 if (!integer_zerop (minv))
1408 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1409 gimple_set_location (g, loc);
1410 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1413 gimple_stmt_iterator gsi2 = *gsi;
1414 basic_block then_bb, fallthru_bb;
1415 *gsi = create_cond_insert_point (gsi, true, false, true,
1416 &then_bb, &fallthru_bb);
1417 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1418 int_const_binop (MINUS_EXPR, maxv, minv),
1419 NULL_TREE, NULL_TREE);
1420 gimple_set_location (g, loc);
1421 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1423 if (!ends_bb)
1425 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1426 update_stmt (stmt);
1429 gsi2 = gsi_after_labels (then_bb);
1430 if (flag_sanitize_undefined_trap_on_error)
1431 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1432 else
1434 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1435 ubsan_type_descriptor (type), NULL_TREE,
1436 NULL_TREE);
1437 data = build_fold_addr_expr_loc (loc, data);
1438 enum built_in_function bcode
1439 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1440 ? SANITIZE_BOOL : SANITIZE_ENUM))
1441 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1442 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1443 tree fn = builtin_decl_explicit (bcode);
1445 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1446 true, NULL_TREE, true,
1447 GSI_SAME_STMT);
1448 g = gimple_build_call (fn, 2, data, val);
1450 gimple_set_location (g, loc);
1451 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1452 ubsan_create_edge (g);
1453 *gsi = gsi_for_stmt (stmt);
1456 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1457 new style handlers. Libubsan uses heuristics to destinguish between old and
1458 new styles and relies on these properties for filename:
1460 a) Location's filename must not be NULL.
1461 b) Location's filename must not be equal to "".
1462 c) Location's filename must not be equal to "\1".
1463 d) First two bytes of filename must not contain '\xff' symbol. */
1465 static bool
1466 ubsan_use_new_style_p (location_t loc)
1468 if (loc == UNKNOWN_LOCATION)
1469 return false;
1471 expanded_location xloc = expand_location (loc);
1472 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1473 || xloc.file == '\0' || xloc.file[0] == '\xff'
1474 || xloc.file[1] == '\xff')
1475 return false;
1477 return true;
1480 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1481 destination, EXPR is floating-point expression. ARG is what to pass
1482 the libubsan call as value, often EXPR itself. */
1484 tree
1485 ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
1487 tree expr_type = TREE_TYPE (expr);
1488 tree t, tt, fn, min, max;
1489 machine_mode mode = TYPE_MODE (expr_type);
1490 int prec = TYPE_PRECISION (type);
1491 bool uns_p = TYPE_UNSIGNED (type);
1492 if (!loc) loc = input_location;
1494 /* Float to integer conversion first truncates toward zero, so
1495 even signed char c = 127.875f; is not problematic.
1496 Therefore, we should complain only if EXPR is unordered or smaller
1497 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1498 TYPE_MAX_VALUE + 1.0. */
1499 if (REAL_MODE_FORMAT (mode)->b == 2)
1501 /* For maximum, TYPE_MAX_VALUE might not be representable
1502 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1503 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1504 either representable or infinity. */
1505 REAL_VALUE_TYPE maxval = dconst1;
1506 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1507 real_convert (&maxval, mode, &maxval);
1508 max = build_real (expr_type, maxval);
1510 /* For unsigned, assume -1.0 is always representable. */
1511 if (uns_p)
1512 min = build_minus_one_cst (expr_type);
1513 else
1515 /* TYPE_MIN_VALUE is generally representable (or -inf),
1516 but TYPE_MIN_VALUE - 1.0 might not be. */
1517 REAL_VALUE_TYPE minval = dconstm1, minval2;
1518 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1519 real_convert (&minval, mode, &minval);
1520 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1521 real_convert (&minval2, mode, &minval2);
1522 if (real_compare (EQ_EXPR, &minval, &minval2)
1523 && !real_isinf (&minval))
1525 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1526 rounds to TYPE_MIN_VALUE, we need to subtract
1527 more. As REAL_MODE_FORMAT (mode)->p is the number
1528 of base digits, we want to subtract a number that
1529 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1530 times smaller than minval. */
1531 minval2 = dconst1;
1532 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1533 SET_REAL_EXP (&minval2,
1534 REAL_EXP (&minval2) + prec - 1
1535 - REAL_MODE_FORMAT (mode)->p + 1);
1536 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1537 real_convert (&minval2, mode, &minval2);
1539 min = build_real (expr_type, minval2);
1542 else if (REAL_MODE_FORMAT (mode)->b == 10)
1544 /* For _Decimal128 up to 34 decimal digits, - sign,
1545 dot, e, exponent. */
1546 char buf[64];
1547 mpfr_t m;
1548 int p = REAL_MODE_FORMAT (mode)->p;
1549 REAL_VALUE_TYPE maxval, minval;
1551 /* Use mpfr_snprintf rounding to compute the smallest
1552 representable decimal number greater or equal than
1553 1 << (prec - !uns_p). */
1554 mpfr_init2 (m, prec + 2);
1555 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1556 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1557 decimal_real_from_string (&maxval, buf);
1558 max = build_real (expr_type, maxval);
1560 /* For unsigned, assume -1.0 is always representable. */
1561 if (uns_p)
1562 min = build_minus_one_cst (expr_type);
1563 else
1565 /* Use mpfr_snprintf rounding to compute the largest
1566 representable decimal number less or equal than
1567 (-1 << (prec - 1)) - 1. */
1568 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1569 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1570 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1571 decimal_real_from_string (&minval, buf);
1572 min = build_real (expr_type, minval);
1574 mpfr_clear (m);
1576 else
1577 return NULL_TREE;
1579 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1580 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1581 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1582 if (integer_zerop (t))
1583 return NULL_TREE;
1585 if (flag_sanitize_undefined_trap_on_error)
1586 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1587 else
1589 location_t *loc_ptr = NULL;
1590 unsigned num_locations = 0;
1591 /* Figure out if we can propagate location to ubsan_data and use new
1592 style handlers in libubsan. */
1593 if (ubsan_use_new_style_p (loc))
1595 loc_ptr = &loc;
1596 num_locations = 1;
1598 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1599 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1600 num_locations, loc_ptr,
1601 ubsan_type_descriptor (expr_type),
1602 ubsan_type_descriptor (type), NULL_TREE,
1603 NULL_TREE);
1604 enum built_in_function bcode
1605 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1606 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1607 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1608 fn = builtin_decl_explicit (bcode);
1609 fn = build_call_expr_loc (loc, fn, 2,
1610 build_fold_addr_expr_loc (loc, data),
1611 ubsan_encode_value (arg, false));
1614 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1617 /* Instrument values passed to function arguments with nonnull attribute. */
1619 static void
1620 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1622 gimple *stmt = gsi_stmt (*gsi);
1623 location_t loc[2];
1624 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1625 while for nonnull sanitization it is clear. */
1626 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1627 flag_delete_null_pointer_checks = 1;
1628 loc[0] = gimple_location (stmt);
1629 loc[1] = UNKNOWN_LOCATION;
1630 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1632 tree arg = gimple_call_arg (stmt, i);
1633 if (POINTER_TYPE_P (TREE_TYPE (arg))
1634 && infer_nonnull_range_by_attribute (stmt, arg))
1636 gimple *g;
1637 if (!is_gimple_val (arg))
1639 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1640 gimple_set_location (g, loc[0]);
1641 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1642 arg = gimple_assign_lhs (g);
1645 basic_block then_bb, fallthru_bb;
1646 *gsi = create_cond_insert_point (gsi, true, false, true,
1647 &then_bb, &fallthru_bb);
1648 g = gimple_build_cond (EQ_EXPR, arg,
1649 build_zero_cst (TREE_TYPE (arg)),
1650 NULL_TREE, NULL_TREE);
1651 gimple_set_location (g, loc[0]);
1652 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1654 *gsi = gsi_after_labels (then_bb);
1655 if (flag_sanitize_undefined_trap_on_error)
1656 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1657 else
1659 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1660 2, loc, NULL_TREE,
1661 build_int_cst (integer_type_node,
1662 i + 1),
1663 NULL_TREE);
1664 data = build_fold_addr_expr_loc (loc[0], data);
1665 enum built_in_function bcode
1666 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1667 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1668 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1669 tree fn = builtin_decl_explicit (bcode);
1671 g = gimple_build_call (fn, 1, data);
1673 gimple_set_location (g, loc[0]);
1674 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1675 ubsan_create_edge (g);
1677 *gsi = gsi_for_stmt (stmt);
1679 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1682 /* Instrument returns in functions with returns_nonnull attribute. */
1684 static void
1685 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1687 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1688 location_t loc[2];
1689 tree arg = gimple_return_retval (stmt);
1690 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1691 while for nonnull return sanitization it is clear. */
1692 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1693 flag_delete_null_pointer_checks = 1;
1694 loc[0] = gimple_location (stmt);
1695 loc[1] = UNKNOWN_LOCATION;
1696 if (arg
1697 && POINTER_TYPE_P (TREE_TYPE (arg))
1698 && is_gimple_val (arg)
1699 && infer_nonnull_range_by_attribute (stmt, arg))
1701 basic_block then_bb, fallthru_bb;
1702 *gsi = create_cond_insert_point (gsi, true, false, true,
1703 &then_bb, &fallthru_bb);
1704 gimple *g = gimple_build_cond (EQ_EXPR, arg,
1705 build_zero_cst (TREE_TYPE (arg)),
1706 NULL_TREE, NULL_TREE);
1707 gimple_set_location (g, loc[0]);
1708 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1710 *gsi = gsi_after_labels (then_bb);
1711 if (flag_sanitize_undefined_trap_on_error)
1712 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1713 else
1715 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1716 2, loc, NULL_TREE, NULL_TREE);
1717 data = build_fold_addr_expr_loc (loc[0], data);
1718 enum built_in_function bcode
1719 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1720 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1721 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1722 tree fn = builtin_decl_explicit (bcode);
1724 g = gimple_build_call (fn, 1, data);
1726 gimple_set_location (g, loc[0]);
1727 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1728 ubsan_create_edge (g);
1729 *gsi = gsi_for_stmt (stmt);
1731 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1734 /* Instrument memory references. Here we check whether the pointer
1735 points to an out-of-bounds location. */
1737 static void
1738 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1740 gimple *stmt = gsi_stmt (*gsi);
1741 location_t loc = gimple_location (stmt);
1742 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1743 tree type;
1744 tree index = NULL_TREE;
1745 HOST_WIDE_INT size_in_bytes;
1747 type = TREE_TYPE (t);
1748 if (VOID_TYPE_P (type))
1749 return;
1751 switch (TREE_CODE (t))
1753 case COMPONENT_REF:
1754 if (TREE_CODE (t) == COMPONENT_REF
1755 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1757 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1758 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1759 repr, NULL_TREE);
1761 break;
1762 case ARRAY_REF:
1763 index = TREE_OPERAND (t, 1);
1764 break;
1765 case INDIRECT_REF:
1766 case MEM_REF:
1767 case VAR_DECL:
1768 case PARM_DECL:
1769 case RESULT_DECL:
1770 break;
1771 default:
1772 return;
1775 size_in_bytes = int_size_in_bytes (type);
1776 if (size_in_bytes <= 0)
1777 return;
1779 HOST_WIDE_INT bitsize, bitpos;
1780 tree offset;
1781 machine_mode mode;
1782 int volatilep = 0, reversep, unsignedp = 0;
1783 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1784 &unsignedp, &reversep, &volatilep, false);
1786 if (bitpos % BITS_PER_UNIT != 0
1787 || bitsize != size_in_bytes * BITS_PER_UNIT)
1788 return;
1790 bool decl_p = DECL_P (inner);
1791 tree base;
1792 if (decl_p)
1793 base = inner;
1794 else if (TREE_CODE (inner) == MEM_REF)
1795 base = TREE_OPERAND (inner, 0);
1796 else
1797 return;
1798 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1800 while (TREE_CODE (base) == SSA_NAME)
1802 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
1803 if (gimple_assign_ssa_name_copy_p (def_stmt)
1804 || (gimple_assign_cast_p (def_stmt)
1805 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1806 || (is_gimple_assign (def_stmt)
1807 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1809 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1810 if (TREE_CODE (rhs1) == SSA_NAME
1811 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1812 break;
1813 else
1814 base = rhs1;
1816 else
1817 break;
1820 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1821 return;
1823 tree sizet;
1824 tree base_addr = base;
1825 gimple *bos_stmt = NULL;
1826 if (decl_p)
1827 base_addr = build1 (ADDR_EXPR,
1828 build_pointer_type (TREE_TYPE (base)), base);
1829 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1830 if (size != (unsigned HOST_WIDE_INT) -1)
1831 sizet = build_int_cst (sizetype, size);
1832 else if (optimize)
1834 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1835 loc = input_location;
1836 /* Generate __builtin_object_size call. */
1837 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1838 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1839 integer_zero_node);
1840 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1841 GSI_SAME_STMT);
1842 /* If the call above didn't end up being an integer constant, go one
1843 statement back and get the __builtin_object_size stmt. Save it,
1844 we might need it later. */
1845 if (SSA_VAR_P (sizet))
1847 gsi_prev (gsi);
1848 bos_stmt = gsi_stmt (*gsi);
1850 /* Move on to where we were. */
1851 gsi_next (gsi);
1854 else
1855 return;
1857 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1858 call. */
1859 /* ptr + sizeof (*ptr) - base */
1860 t = fold_build2 (MINUS_EXPR, sizetype,
1861 fold_convert (pointer_sized_int_node, ptr),
1862 fold_convert (pointer_sized_int_node, base_addr));
1863 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1865 /* Perhaps we can omit the check. */
1866 if (TREE_CODE (t) == INTEGER_CST
1867 && TREE_CODE (sizet) == INTEGER_CST
1868 && tree_int_cst_le (t, sizet))
1869 return;
1871 if (index != NULL_TREE
1872 && TREE_CODE (index) == SSA_NAME
1873 && TREE_CODE (sizet) == INTEGER_CST)
1875 gimple *def = SSA_NAME_DEF_STMT (index);
1876 if (is_gimple_assign (def)
1877 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1878 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1880 tree cst = gimple_assign_rhs2 (def);
1881 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1882 TYPE_SIZE_UNIT (type));
1883 if (tree_int_cst_sgn (cst) >= 0
1884 && tree_int_cst_lt (cst, sz))
1885 return;
1889 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1890 ubsan_create_edge (bos_stmt);
1892 /* We have to emit the check. */
1893 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1894 GSI_SAME_STMT);
1895 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1896 GSI_SAME_STMT);
1897 tree ckind = build_int_cst (unsigned_char_type_node,
1898 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1899 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1900 ptr, t, sizet, ckind);
1901 gimple_set_location (g, loc);
1902 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1905 /* True if we want to play UBSan games in the current function. */
1907 bool
1908 do_ubsan_in_current_function ()
1910 return (current_function_decl != NULL_TREE
1911 && !lookup_attribute ("no_sanitize_undefined",
1912 DECL_ATTRIBUTES (current_function_decl)));
1915 namespace {
1917 const pass_data pass_data_ubsan =
1919 GIMPLE_PASS, /* type */
1920 "ubsan", /* name */
1921 OPTGROUP_NONE, /* optinfo_flags */
1922 TV_TREE_UBSAN, /* tv_id */
1923 ( PROP_cfg | PROP_ssa ), /* properties_required */
1924 0, /* properties_provided */
1925 0, /* properties_destroyed */
1926 0, /* todo_flags_start */
1927 TODO_update_ssa, /* todo_flags_finish */
1930 class pass_ubsan : public gimple_opt_pass
1932 public:
1933 pass_ubsan (gcc::context *ctxt)
1934 : gimple_opt_pass (pass_data_ubsan, ctxt)
1937 /* opt_pass methods: */
1938 virtual bool gate (function *)
1940 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1941 | SANITIZE_BOOL | SANITIZE_ENUM
1942 | SANITIZE_ALIGNMENT
1943 | SANITIZE_NONNULL_ATTRIBUTE
1944 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1945 | SANITIZE_OBJECT_SIZE)
1946 && do_ubsan_in_current_function ();
1949 virtual unsigned int execute (function *);
1951 }; // class pass_ubsan
1953 unsigned int
1954 pass_ubsan::execute (function *fun)
1956 basic_block bb;
1957 gimple_stmt_iterator gsi;
1959 initialize_sanitizer_builtins ();
1961 FOR_EACH_BB_FN (bb, fun)
1963 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1965 gimple *stmt = gsi_stmt (gsi);
1966 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1968 gsi_next (&gsi);
1969 continue;
1972 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1973 && is_gimple_assign (stmt))
1974 instrument_si_overflow (gsi);
1976 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1978 if (gimple_store_p (stmt))
1979 instrument_null (gsi, true);
1980 if (gimple_assign_load_p (stmt))
1981 instrument_null (gsi, false);
1984 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1985 && gimple_assign_load_p (stmt))
1987 instrument_bool_enum_load (&gsi);
1988 bb = gimple_bb (stmt);
1991 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1992 && is_gimple_call (stmt)
1993 && !gimple_call_internal_p (stmt))
1995 instrument_nonnull_arg (&gsi);
1996 bb = gimple_bb (stmt);
1999 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2000 && gimple_code (stmt) == GIMPLE_RETURN)
2002 instrument_nonnull_return (&gsi);
2003 bb = gimple_bb (stmt);
2006 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2008 if (gimple_store_p (stmt))
2009 instrument_object_size (&gsi, true);
2010 if (gimple_assign_load_p (stmt))
2011 instrument_object_size (&gsi, false);
2014 gsi_next (&gsi);
2017 return 0;
2020 } // anon namespace
2022 gimple_opt_pass *
2023 make_pass_ubsan (gcc::context *ctxt)
2025 return new pass_ubsan (ctxt);
2028 #include "gt-ubsan.h"