Refactor graphite-sese-to-poly, sese.h, graphite-poly.h
[official-gcc.git] / gcc / ubsan.c
blobf30a2d51cfa303c693d9cd2c76d55639a0c88916
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 "alias.h"
25 #include "backend.h"
26 #include "cfghooks.h"
27 #include "tree.h"
28 #include "gimple.h"
29 #include "rtl.h"
30 #include "ssa.h"
31 #include "options.h"
32 #include "fold-const.h"
33 #include "stor-layout.h"
34 #include "cfganal.h"
35 #include "cgraph.h"
36 #include "tree-pass.h"
37 #include "tree-pretty-print.h"
38 #include "internal-fn.h"
39 #include "gimple-iterator.h"
40 #include "gimple-walk.h"
41 #include "output.h"
42 #include "tm_p.h"
43 #include "toplev.h"
44 #include "cfgloop.h"
45 #include "ubsan.h"
46 #include "c-family/c-common.h"
47 #include "flags.h"
48 #include "insn-config.h"
49 #include "expmed.h"
50 #include "dojump.h"
51 #include "explow.h"
52 #include "calls.h"
53 #include "emit-rtl.h"
54 #include "varasm.h"
55 #include "stmt.h"
56 #include "expr.h"
57 #include "asan.h"
58 #include "gimplify-me.h"
59 #include "intl.h"
60 #include "realmpfr.h"
61 #include "dfp.h"
62 #include "builtins.h"
63 #include "tree-object-size.h"
64 #include "tree-eh.h"
65 #include "tree-cfg.h"
67 /* Map from a tree to a VAR_DECL tree. */
69 struct GTY((for_user)) tree_type_map {
70 struct tree_map_base type;
71 tree decl;
74 struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
76 static inline hashval_t
77 hash (tree_type_map *t)
79 return TYPE_UID (t->type.from);
82 static inline bool
83 equal (tree_type_map *a, tree_type_map *b)
85 return a->type.from == b->type.from;
88 static int
89 keep_cache_entry (tree_type_map *&m)
91 return ggc_marked_p (m->type.from);
95 static GTY ((cache))
96 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
98 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
100 static tree
101 decl_for_type_lookup (tree type)
103 /* If the hash table is not initialized yet, create it now. */
104 if (decl_tree_for_type == NULL)
106 decl_tree_for_type
107 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
108 /* That also means we don't have to bother with the lookup. */
109 return NULL_TREE;
112 struct tree_type_map *h, in;
113 in.type.from = type;
115 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
116 return h ? h->decl : NULL_TREE;
119 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
121 static void
122 decl_for_type_insert (tree type, tree decl)
124 struct tree_type_map *h;
126 h = ggc_alloc<tree_type_map> ();
127 h->type.from = type;
128 h->decl = decl;
129 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
132 /* Helper routine, which encodes a value in the pointer_sized_int_node.
133 Arguments with precision <= POINTER_SIZE are passed directly,
134 the rest is passed by reference. T is a value we are to encode.
135 IN_EXPAND_P is true if this function is called during expansion. */
137 tree
138 ubsan_encode_value (tree t, bool in_expand_p)
140 tree type = TREE_TYPE (t);
141 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
142 if (bitsize <= POINTER_SIZE)
143 switch (TREE_CODE (type))
145 case BOOLEAN_TYPE:
146 case ENUMERAL_TYPE:
147 case INTEGER_TYPE:
148 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
149 case REAL_TYPE:
151 tree itype = build_nonstandard_integer_type (bitsize, true);
152 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
153 return fold_convert (pointer_sized_int_node, t);
155 default:
156 gcc_unreachable ();
158 else
160 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
162 /* The reason for this is that we don't want to pessimize
163 code by making vars unnecessarily addressable. */
164 tree var = create_tmp_var (type);
165 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
166 if (in_expand_p)
168 rtx mem
169 = assign_stack_temp_for_type (TYPE_MODE (type),
170 GET_MODE_SIZE (TYPE_MODE (type)),
171 type);
172 SET_DECL_RTL (var, mem);
173 expand_assignment (var, t, false);
174 return build_fold_addr_expr (var);
176 t = build_fold_addr_expr (var);
177 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
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 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
325 if (TREE_CODE (type) == REAL_TYPE)
326 return tree_to_uhwi (TYPE_SIZE (type));
327 else if (INTEGRAL_TYPE_P (type))
329 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
330 gcc_assert (prec != -1);
331 return (prec << 1) | !TYPE_UNSIGNED (type);
333 else
334 return 0;
337 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
338 descriptor. It first looks into the hash table; if not found,
339 create the VAR_DECL, put it into the hash table and return the
340 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
341 an enum controlling how we want to print the type. */
343 tree
344 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
346 /* See through any typedefs. */
347 type = TYPE_MAIN_VARIANT (type);
349 tree decl = decl_for_type_lookup (type);
350 /* It is possible that some of the earlier created DECLs were found
351 unused, in that case they weren't emitted and varpool_node::get
352 returns NULL node on them. But now we really need them. Thus,
353 renew them here. */
354 if (decl != NULL_TREE && varpool_node::get (decl))
355 return build_fold_addr_expr (decl);
357 tree dtype = ubsan_get_type_descriptor_type ();
358 tree type2 = type;
359 const char *tname = NULL;
360 pretty_printer pretty_name;
361 unsigned char deref_depth = 0;
362 unsigned short tkind, tinfo;
364 /* Get the name of the type, or the name of the pointer type. */
365 if (pstyle == UBSAN_PRINT_POINTER)
367 gcc_assert (POINTER_TYPE_P (type));
368 type2 = TREE_TYPE (type);
370 /* Remove any '*' operators from TYPE. */
371 while (POINTER_TYPE_P (type2))
372 deref_depth++, type2 = TREE_TYPE (type2);
374 if (TREE_CODE (type2) == METHOD_TYPE)
375 type2 = TYPE_METHOD_BASETYPE (type2);
378 /* If an array, get its type. */
379 type2 = strip_array_types (type2);
381 if (pstyle == UBSAN_PRINT_ARRAY)
383 while (POINTER_TYPE_P (type2))
384 deref_depth++, type2 = TREE_TYPE (type2);
387 if (TYPE_NAME (type2) != NULL)
389 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
390 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
391 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
392 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
395 if (tname == NULL)
396 /* We weren't able to determine the type name. */
397 tname = "<unknown>";
399 if (pstyle == UBSAN_PRINT_POINTER)
401 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
402 TYPE_VOLATILE (type2) ? "volatile " : "",
403 TYPE_READONLY (type2) ? "const " : "",
404 TYPE_RESTRICT (type2) ? "restrict " : "",
405 TYPE_ATOMIC (type2) ? "_Atomic " : "",
406 TREE_CODE (type2) == RECORD_TYPE
407 ? "struct "
408 : TREE_CODE (type2) == UNION_TYPE
409 ? "union " : "", tname,
410 deref_depth == 0 ? "" : " ");
411 while (deref_depth-- > 0)
412 pp_star (&pretty_name);
413 pp_quote (&pretty_name);
415 else if (pstyle == UBSAN_PRINT_ARRAY)
417 /* Pretty print the array dimensions. */
418 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
419 tree t = type;
420 pp_printf (&pretty_name, "'%s ", tname);
421 while (deref_depth-- > 0)
422 pp_star (&pretty_name);
423 while (TREE_CODE (t) == ARRAY_TYPE)
425 pp_left_bracket (&pretty_name);
426 tree dom = TYPE_DOMAIN (t);
427 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
429 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
430 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
431 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
432 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
433 else
434 pp_wide_int (&pretty_name,
435 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
436 TYPE_SIGN (TREE_TYPE (dom)));
438 else
439 /* ??? We can't determine the variable name; print VLA unspec. */
440 pp_star (&pretty_name);
441 pp_right_bracket (&pretty_name);
442 t = TREE_TYPE (t);
444 pp_quote (&pretty_name);
446 /* Save the tree with stripped types. */
447 type = t;
449 else
450 pp_printf (&pretty_name, "'%s'", tname);
452 switch (TREE_CODE (type))
454 case BOOLEAN_TYPE:
455 case ENUMERAL_TYPE:
456 case INTEGER_TYPE:
457 tkind = 0x0000;
458 break;
459 case REAL_TYPE:
460 /* FIXME: libubsan right now only supports float, double and
461 long double type formats. */
462 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
463 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
464 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
465 tkind = 0x0001;
466 else
467 tkind = 0xffff;
468 break;
469 default:
470 tkind = 0xffff;
471 break;
473 tinfo = get_ubsan_type_info_for_type (type);
475 /* Create a new VAR_DECL of type descriptor. */
476 const char *tmp = pp_formatted_text (&pretty_name);
477 size_t len = strlen (tmp) + 1;
478 tree str = build_string (len, tmp);
479 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
480 TREE_READONLY (str) = 1;
481 TREE_STATIC (str) = 1;
483 char tmp_name[32];
484 static unsigned int type_var_id_num;
485 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
486 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
487 dtype);
488 TREE_STATIC (decl) = 1;
489 TREE_PUBLIC (decl) = 0;
490 DECL_ARTIFICIAL (decl) = 1;
491 DECL_IGNORED_P (decl) = 1;
492 DECL_EXTERNAL (decl) = 0;
493 DECL_SIZE (decl)
494 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
495 DECL_SIZE_UNIT (decl)
496 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
497 TYPE_SIZE_UNIT (TREE_TYPE (str)));
499 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
500 build_int_cst (short_unsigned_type_node,
501 tkind), NULL_TREE,
502 build_int_cst (short_unsigned_type_node,
503 tinfo), NULL_TREE, str);
504 TREE_CONSTANT (ctor) = 1;
505 TREE_STATIC (ctor) = 1;
506 DECL_INITIAL (decl) = ctor;
507 varpool_node::finalize_decl (decl);
509 /* Save the VAR_DECL into the hash table. */
510 decl_for_type_insert (type, decl);
512 return build_fold_addr_expr (decl);
515 /* Create a structure for the ubsan library. NAME is a name of the new
516 structure. LOCCNT is number of locations, PLOC points to array of
517 locations. The arguments in ... are of __ubsan_type_descriptor type
518 and there are at most two of them, followed by NULL_TREE, followed
519 by optional extra arguments and another NULL_TREE. */
521 tree
522 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
524 va_list args;
525 tree ret, t;
526 tree fields[6];
527 vec<tree, va_gc> *saved_args = NULL;
528 size_t i = 0;
529 int j;
531 /* Firstly, create a pointer to type descriptor type. */
532 tree td_type = ubsan_get_type_descriptor_type ();
533 td_type = build_pointer_type (td_type);
535 /* Create the structure type. */
536 ret = make_node (RECORD_TYPE);
537 for (j = 0; j < loccnt; j++)
539 gcc_checking_assert (i < 2);
540 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
541 ubsan_get_source_location_type ());
542 DECL_CONTEXT (fields[i]) = ret;
543 if (i)
544 DECL_CHAIN (fields[i - 1]) = fields[i];
545 i++;
548 va_start (args, ploc);
549 for (t = va_arg (args, tree); t != NULL_TREE;
550 i++, t = va_arg (args, tree))
552 gcc_checking_assert (i < 4);
553 /* Save the tree arguments for later use. */
554 vec_safe_push (saved_args, t);
555 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
556 td_type);
557 DECL_CONTEXT (fields[i]) = ret;
558 if (i)
559 DECL_CHAIN (fields[i - 1]) = fields[i];
562 for (t = va_arg (args, tree); t != NULL_TREE;
563 i++, t = va_arg (args, tree))
565 gcc_checking_assert (i < 6);
566 /* Save the tree arguments for later use. */
567 vec_safe_push (saved_args, t);
568 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
569 TREE_TYPE (t));
570 DECL_CONTEXT (fields[i]) = ret;
571 if (i)
572 DECL_CHAIN (fields[i - 1]) = fields[i];
574 va_end (args);
576 tree type_decl = build_decl (input_location, TYPE_DECL,
577 get_identifier (name), ret);
578 DECL_IGNORED_P (type_decl) = 1;
579 DECL_ARTIFICIAL (type_decl) = 1;
580 TYPE_FIELDS (ret) = fields[0];
581 TYPE_NAME (ret) = type_decl;
582 TYPE_STUB_DECL (ret) = type_decl;
583 layout_type (ret);
585 /* Now, fill in the type. */
586 char tmp_name[32];
587 static unsigned int ubsan_var_id_num;
588 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
589 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
590 ret);
591 TREE_STATIC (var) = 1;
592 TREE_PUBLIC (var) = 0;
593 DECL_ARTIFICIAL (var) = 1;
594 DECL_IGNORED_P (var) = 1;
595 DECL_EXTERNAL (var) = 0;
597 vec<constructor_elt, va_gc> *v;
598 vec_alloc (v, i);
599 tree ctor = build_constructor (ret, v);
601 /* If desirable, set the __ubsan_source_location element. */
602 for (j = 0; j < loccnt; j++)
604 location_t loc = LOCATION_LOCUS (ploc[j]);
605 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
608 size_t nelts = vec_safe_length (saved_args);
609 for (i = 0; i < nelts; i++)
611 t = (*saved_args)[i];
612 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
615 TREE_CONSTANT (ctor) = 1;
616 TREE_STATIC (ctor) = 1;
617 DECL_INITIAL (var) = ctor;
618 varpool_node::finalize_decl (var);
620 return var;
623 /* Instrument the __builtin_unreachable call. We just call the libubsan
624 routine instead. */
626 bool
627 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
629 gimple *g;
630 location_t loc = gimple_location (gsi_stmt (*gsi));
632 if (flag_sanitize_undefined_trap_on_error)
633 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
634 else
636 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
637 NULL_TREE, NULL_TREE);
638 data = build_fold_addr_expr_loc (loc, data);
639 tree fn
640 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
641 g = gimple_build_call (fn, 1, data);
643 gimple_set_location (g, loc);
644 gsi_replace (gsi, g, false);
645 return false;
648 /* Return true if T is a call to a libubsan routine. */
650 bool
651 is_ubsan_builtin_p (tree t)
653 return TREE_CODE (t) == FUNCTION_DECL
654 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
655 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
656 "__builtin___ubsan_", 18) == 0;
659 /* Create a callgraph edge for statement STMT. */
661 static void
662 ubsan_create_edge (gimple *stmt)
664 gcall *call_stmt = dyn_cast <gcall *> (stmt);
665 basic_block bb = gimple_bb (stmt);
666 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
667 cgraph_node *node = cgraph_node::get (current_function_decl);
668 tree decl = gimple_call_fndecl (call_stmt);
669 if (decl)
670 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
671 freq);
674 /* Expand the UBSAN_BOUNDS special builtin function. */
676 bool
677 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
679 gimple *stmt = gsi_stmt (*gsi);
680 location_t loc = gimple_location (stmt);
681 gcc_assert (gimple_call_num_args (stmt) == 3);
683 /* Pick up the arguments of the UBSAN_BOUNDS call. */
684 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
685 tree index = gimple_call_arg (stmt, 1);
686 tree orig_index_type = TREE_TYPE (index);
687 tree bound = gimple_call_arg (stmt, 2);
689 gimple_stmt_iterator gsi_orig = *gsi;
691 /* Create condition "if (index > bound)". */
692 basic_block then_bb, fallthru_bb;
693 gimple_stmt_iterator cond_insert_point
694 = create_cond_insert_point (gsi, false, false, true,
695 &then_bb, &fallthru_bb);
696 index = fold_convert (TREE_TYPE (bound), index);
697 index = force_gimple_operand_gsi (&cond_insert_point, index,
698 true, NULL_TREE,
699 false, GSI_NEW_STMT);
700 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
701 gimple_set_location (g, loc);
702 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
704 /* Generate __ubsan_handle_out_of_bounds call. */
705 *gsi = gsi_after_labels (then_bb);
706 if (flag_sanitize_undefined_trap_on_error)
707 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
708 else
710 tree data
711 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
712 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
713 ubsan_type_descriptor (orig_index_type),
714 NULL_TREE, NULL_TREE);
715 data = build_fold_addr_expr_loc (loc, data);
716 enum built_in_function bcode
717 = (flag_sanitize_recover & SANITIZE_BOUNDS)
718 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
719 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
720 tree fn = builtin_decl_explicit (bcode);
721 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
722 true, NULL_TREE, true,
723 GSI_SAME_STMT);
724 g = gimple_build_call (fn, 2, data, val);
726 gimple_set_location (g, loc);
727 gsi_insert_before (gsi, g, GSI_SAME_STMT);
729 /* Get rid of the UBSAN_BOUNDS call from the IR. */
730 unlink_stmt_vdef (stmt);
731 gsi_remove (&gsi_orig, true);
733 /* Point GSI to next logical statement. */
734 *gsi = gsi_start_bb (fallthru_bb);
735 return true;
738 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
739 argument which is a constant, because the middle-end treats pointer
740 conversions as useless and therefore the type of the first argument
741 could be changed to any other pointer type. */
743 bool
744 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
746 gimple_stmt_iterator gsi = *gsip;
747 gimple *stmt = gsi_stmt (gsi);
748 location_t loc = gimple_location (stmt);
749 gcc_assert (gimple_call_num_args (stmt) == 3);
750 tree ptr = gimple_call_arg (stmt, 0);
751 tree ckind = gimple_call_arg (stmt, 1);
752 tree align = gimple_call_arg (stmt, 2);
753 tree check_align = NULL_TREE;
754 bool check_null;
756 basic_block cur_bb = gsi_bb (gsi);
758 gimple *g;
759 if (!integer_zerop (align))
761 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
762 if (compare_tree_int (align, ptralign) == 1)
764 check_align = make_ssa_name (pointer_sized_int_node);
765 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
766 gimple_set_location (g, loc);
767 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
770 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
772 if (check_align == NULL_TREE && !check_null)
774 gsi_remove (gsip, true);
775 /* Unlink the UBSAN_NULLs vops before replacing it. */
776 unlink_stmt_vdef (stmt);
777 return true;
780 /* Split the original block holding the pointer dereference. */
781 edge e = split_block (cur_bb, stmt);
783 /* Get a hold on the 'condition block', the 'then block' and the
784 'else block'. */
785 basic_block cond_bb = e->src;
786 basic_block fallthru_bb = e->dest;
787 basic_block then_bb = create_empty_bb (cond_bb);
788 add_bb_to_loop (then_bb, cond_bb->loop_father);
789 loops_state_set (LOOPS_NEED_FIXUP);
791 /* Make an edge coming from the 'cond block' into the 'then block';
792 this edge is unlikely taken, so set up the probability accordingly. */
793 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
794 e->probability = PROB_VERY_UNLIKELY;
796 /* Connect 'then block' with the 'else block'. This is needed
797 as the ubsan routines we call in the 'then block' are not noreturn.
798 The 'then block' only has one outcoming edge. */
799 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
801 /* Set up the fallthrough basic block. */
802 e = find_edge (cond_bb, fallthru_bb);
803 e->flags = EDGE_FALSE_VALUE;
804 e->count = cond_bb->count;
805 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
807 /* Update dominance info for the newly created then_bb; note that
808 fallthru_bb's dominance info has already been updated by
809 split_block. */
810 if (dom_info_available_p (CDI_DOMINATORS))
811 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
813 /* Put the ubsan builtin call into the newly created BB. */
814 if (flag_sanitize_undefined_trap_on_error)
815 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
816 else
818 enum built_in_function bcode
819 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
820 | (check_null ? SANITIZE_NULL : 0)))
821 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
822 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
823 tree fn = builtin_decl_implicit (bcode);
824 tree data
825 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
826 ubsan_type_descriptor (TREE_TYPE (ckind),
827 UBSAN_PRINT_POINTER),
828 NULL_TREE,
829 align,
830 fold_convert (unsigned_char_type_node, ckind),
831 NULL_TREE);
832 data = build_fold_addr_expr_loc (loc, data);
833 g = gimple_build_call (fn, 2, data,
834 check_align ? check_align
835 : build_zero_cst (pointer_sized_int_node));
837 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
838 gimple_set_location (g, loc);
839 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
841 /* Unlink the UBSAN_NULLs vops before replacing it. */
842 unlink_stmt_vdef (stmt);
844 if (check_null)
846 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
847 NULL_TREE, NULL_TREE);
848 gimple_set_location (g, loc);
850 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
851 gsi_replace (&gsi, g, false);
852 stmt = g;
855 if (check_align)
857 if (check_null)
859 /* Split the block with the condition again. */
860 e = split_block (cond_bb, stmt);
861 basic_block cond1_bb = e->src;
862 basic_block cond2_bb = e->dest;
864 /* Make an edge coming from the 'cond1 block' into the 'then block';
865 this edge is unlikely taken, so set up the probability
866 accordingly. */
867 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
868 e->probability = PROB_VERY_UNLIKELY;
870 /* Set up the fallthrough basic block. */
871 e = find_edge (cond1_bb, cond2_bb);
872 e->flags = EDGE_FALSE_VALUE;
873 e->count = cond1_bb->count;
874 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
876 /* Update dominance info. */
877 if (dom_info_available_p (CDI_DOMINATORS))
879 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
880 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
883 gsi2 = gsi_start_bb (cond2_bb);
886 tree mask = build_int_cst (pointer_sized_int_node,
887 tree_to_uhwi (align) - 1);
888 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
889 BIT_AND_EXPR, check_align, mask);
890 gimple_set_location (g, loc);
891 if (check_null)
892 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
893 else
894 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
896 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
897 build_int_cst (pointer_sized_int_node, 0),
898 NULL_TREE, NULL_TREE);
899 gimple_set_location (g, loc);
900 if (check_null)
901 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
902 else
903 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
904 gsi_replace (&gsi, g, false);
906 return false;
909 #define OBJSZ_MAX_OFFSET (1024 * 16)
911 /* Expand UBSAN_OBJECT_SIZE internal call. */
913 bool
914 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
916 gimple *stmt = gsi_stmt (*gsi);
917 location_t loc = gimple_location (stmt);
918 gcc_assert (gimple_call_num_args (stmt) == 4);
920 tree ptr = gimple_call_arg (stmt, 0);
921 tree offset = gimple_call_arg (stmt, 1);
922 tree size = gimple_call_arg (stmt, 2);
923 tree ckind = gimple_call_arg (stmt, 3);
924 gimple_stmt_iterator gsi_orig = *gsi;
925 gimple *g;
927 /* See if we can discard the check. */
928 if (TREE_CODE (size) != INTEGER_CST
929 || integer_all_onesp (size))
930 /* Yes, __builtin_object_size couldn't determine the
931 object size. */;
932 else if (TREE_CODE (offset) == INTEGER_CST
933 && wi::ges_p (wi::to_widest (offset), -OBJSZ_MAX_OFFSET)
934 && wi::les_p (wi::to_widest (offset), -1))
935 /* The offset is in range [-16K, -1]. */;
936 else
938 /* if (offset > objsize) */
939 basic_block then_bb, fallthru_bb;
940 gimple_stmt_iterator cond_insert_point
941 = create_cond_insert_point (gsi, false, false, true,
942 &then_bb, &fallthru_bb);
943 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
944 gimple_set_location (g, loc);
945 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
947 /* If the offset is small enough, we don't need the second
948 run-time check. */
949 if (TREE_CODE (offset) == INTEGER_CST
950 && wi::ges_p (wi::to_widest (offset), 0)
951 && wi::les_p (wi::to_widest (offset), OBJSZ_MAX_OFFSET))
952 *gsi = gsi_after_labels (then_bb);
953 else
955 /* Don't issue run-time error if (ptr > ptr + offset). That
956 may happen when computing a POINTER_PLUS_EXPR. */
957 basic_block then2_bb, fallthru2_bb;
959 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
960 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
961 true, &then2_bb,
962 &fallthru2_bb);
963 /* Convert the pointer to an integer type. */
964 tree p = make_ssa_name (pointer_sized_int_node);
965 g = gimple_build_assign (p, NOP_EXPR, ptr);
966 gimple_set_location (g, loc);
967 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
968 p = gimple_assign_lhs (g);
969 /* Compute ptr + offset. */
970 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
971 PLUS_EXPR, p, offset);
972 gimple_set_location (g, loc);
973 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
974 /* Now build the conditional and put it into the IR. */
975 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
976 NULL_TREE, NULL_TREE);
977 gimple_set_location (g, loc);
978 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
979 *gsi = gsi_after_labels (then2_bb);
982 /* Generate __ubsan_handle_type_mismatch call. */
983 if (flag_sanitize_undefined_trap_on_error)
984 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
985 else
987 tree data
988 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
989 ubsan_type_descriptor (TREE_TYPE (ptr),
990 UBSAN_PRINT_POINTER),
991 NULL_TREE,
992 build_zero_cst (pointer_sized_int_node),
993 ckind,
994 NULL_TREE);
995 data = build_fold_addr_expr_loc (loc, data);
996 enum built_in_function bcode
997 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
998 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
999 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
1000 tree p = make_ssa_name (pointer_sized_int_node);
1001 g = gimple_build_assign (p, NOP_EXPR, ptr);
1002 gimple_set_location (g, loc);
1003 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1004 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1006 gimple_set_location (g, loc);
1007 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1009 /* Point GSI to next logical statement. */
1010 *gsi = gsi_start_bb (fallthru_bb);
1012 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1013 unlink_stmt_vdef (stmt);
1014 gsi_remove (&gsi_orig, true);
1015 return true;
1018 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1019 unlink_stmt_vdef (stmt);
1020 gsi_remove (gsi, true);
1021 return true;
1024 /* Cached __ubsan_vptr_type_cache decl. */
1025 static GTY(()) tree ubsan_vptr_type_cache_decl;
1027 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1028 argument which is a constant, because the middle-end treats pointer
1029 conversions as useless and therefore the type of the first argument
1030 could be changed to any other pointer type. */
1032 bool
1033 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1035 gimple_stmt_iterator gsi = *gsip;
1036 gimple *stmt = gsi_stmt (gsi);
1037 location_t loc = gimple_location (stmt);
1038 gcc_assert (gimple_call_num_args (stmt) == 5);
1039 tree op = gimple_call_arg (stmt, 0);
1040 tree vptr = gimple_call_arg (stmt, 1);
1041 tree str_hash = gimple_call_arg (stmt, 2);
1042 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1043 tree ckind_tree = gimple_call_arg (stmt, 4);
1044 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1045 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1046 gimple *g;
1047 basic_block fallthru_bb = NULL;
1049 if (ckind == UBSAN_DOWNCAST_POINTER)
1051 /* Guard everything with if (op != NULL) { ... }. */
1052 basic_block then_bb;
1053 gimple_stmt_iterator cond_insert_point
1054 = create_cond_insert_point (gsip, false, false, true,
1055 &then_bb, &fallthru_bb);
1056 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1057 NULL_TREE, NULL_TREE);
1058 gimple_set_location (g, loc);
1059 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1060 *gsip = gsi_after_labels (then_bb);
1061 gsi_remove (&gsi, false);
1062 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1063 gsi = *gsip;
1066 tree htype = TREE_TYPE (str_hash);
1067 tree cst = wide_int_to_tree (htype,
1068 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1069 | 0xeb382d69, 64));
1070 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1071 vptr, str_hash);
1072 gimple_set_location (g, loc);
1073 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1074 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1075 gimple_assign_lhs (g), cst);
1076 gimple_set_location (g, loc);
1077 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1078 tree t1 = gimple_assign_lhs (g);
1079 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1080 t1, build_int_cst (integer_type_node, 47));
1081 gimple_set_location (g, loc);
1082 tree t2 = gimple_assign_lhs (g);
1083 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1084 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1085 vptr, t1);
1086 gimple_set_location (g, loc);
1087 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1088 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1089 t2, gimple_assign_lhs (g));
1090 gimple_set_location (g, loc);
1091 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1092 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1093 gimple_assign_lhs (g), cst);
1094 gimple_set_location (g, loc);
1095 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1096 tree t3 = gimple_assign_lhs (g);
1097 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1098 t3, build_int_cst (integer_type_node, 47));
1099 gimple_set_location (g, loc);
1100 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1101 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1102 t3, gimple_assign_lhs (g));
1103 gimple_set_location (g, loc);
1104 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1105 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1106 gimple_assign_lhs (g), cst);
1107 gimple_set_location (g, loc);
1108 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1109 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1111 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1112 NOP_EXPR, gimple_assign_lhs (g));
1113 gimple_set_location (g, loc);
1114 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1116 tree hash = gimple_assign_lhs (g);
1118 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1120 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1121 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1122 get_identifier ("__ubsan_vptr_type_cache"),
1123 atype);
1124 DECL_ARTIFICIAL (array) = 1;
1125 DECL_IGNORED_P (array) = 1;
1126 TREE_PUBLIC (array) = 1;
1127 TREE_STATIC (array) = 1;
1128 DECL_EXTERNAL (array) = 1;
1129 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1130 DECL_VISIBILITY_SPECIFIED (array) = 1;
1131 varpool_node::finalize_decl (array);
1132 ubsan_vptr_type_cache_decl = array;
1135 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1136 BIT_AND_EXPR, hash,
1137 build_int_cst (pointer_sized_int_node, 127));
1138 gimple_set_location (g, loc);
1139 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1141 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1142 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1143 NULL_TREE, NULL_TREE);
1144 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1145 ARRAY_REF, c);
1146 gimple_set_location (g, loc);
1147 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1149 basic_block then_bb, fallthru2_bb;
1150 gimple_stmt_iterator cond_insert_point
1151 = create_cond_insert_point (gsip, false, false, true,
1152 &then_bb, &fallthru2_bb);
1153 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1154 NULL_TREE, NULL_TREE);
1155 gimple_set_location (g, loc);
1156 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1157 *gsip = gsi_after_labels (then_bb);
1158 if (fallthru_bb == NULL)
1159 fallthru_bb = fallthru2_bb;
1161 tree data
1162 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1163 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1164 build_int_cst (unsigned_char_type_node, ckind),
1165 NULL_TREE);
1166 data = build_fold_addr_expr_loc (loc, data);
1167 enum built_in_function bcode
1168 = (flag_sanitize_recover & SANITIZE_VPTR)
1169 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1170 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1172 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1173 gimple_set_location (g, loc);
1174 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1176 /* Point GSI to next logical statement. */
1177 *gsip = gsi_start_bb (fallthru_bb);
1179 /* Get rid of the UBSAN_VPTR call from the IR. */
1180 unlink_stmt_vdef (stmt);
1181 gsi_remove (&gsi, true);
1182 return true;
1185 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1186 whether the pointer is on the left hand side of the assignment. */
1188 static void
1189 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1190 bool is_lhs)
1192 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1193 unsigned int align = 0;
1194 if (flag_sanitize & SANITIZE_ALIGNMENT)
1196 align = min_align_of_type (TREE_TYPE (base));
1197 if (align <= 1)
1198 align = 0;
1200 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1201 return;
1202 tree t = TREE_OPERAND (base, 0);
1203 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1204 return;
1205 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1206 ikind = UBSAN_MEMBER_ACCESS;
1207 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1208 tree alignt = build_int_cst (pointer_sized_int_node, align);
1209 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1210 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1211 gsi_insert_before (iter, g, GSI_SAME_STMT);
1214 /* Perform the pointer instrumentation. */
1216 static void
1217 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1219 gimple *stmt = gsi_stmt (gsi);
1220 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1221 tree base = get_base_address (t);
1222 const enum tree_code code = TREE_CODE (base);
1223 if (code == MEM_REF
1224 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1225 instrument_mem_ref (t, base, &gsi, is_lhs);
1228 /* Build an ubsan builtin call for the signed-integer-overflow
1229 sanitization. CODE says what kind of builtin are we building,
1230 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1231 are operands of the binary operation. */
1233 tree
1234 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1235 tree op0, tree op1)
1237 if (flag_sanitize_undefined_trap_on_error)
1238 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1240 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1241 ubsan_type_descriptor (lhstype), NULL_TREE,
1242 NULL_TREE);
1243 enum built_in_function fn_code;
1245 switch (code)
1247 case PLUS_EXPR:
1248 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1249 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1250 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1251 break;
1252 case MINUS_EXPR:
1253 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1254 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1255 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1256 break;
1257 case MULT_EXPR:
1258 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1259 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1260 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1261 break;
1262 case NEGATE_EXPR:
1263 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1264 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1265 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1266 break;
1267 default:
1268 gcc_unreachable ();
1270 tree fn = builtin_decl_explicit (fn_code);
1271 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1272 build_fold_addr_expr_loc (loc, data),
1273 ubsan_encode_value (op0, true),
1274 op1 ? ubsan_encode_value (op1, true)
1275 : NULL_TREE);
1278 /* Perform the signed integer instrumentation. GSI is the iterator
1279 pointing at statement we are trying to instrument. */
1281 static void
1282 instrument_si_overflow (gimple_stmt_iterator gsi)
1284 gimple *stmt = gsi_stmt (gsi);
1285 tree_code code = gimple_assign_rhs_code (stmt);
1286 tree lhs = gimple_assign_lhs (stmt);
1287 tree lhstype = TREE_TYPE (lhs);
1288 tree a, b;
1289 gimple *g;
1291 /* If this is not a signed operation, don't instrument anything here.
1292 Also punt on bit-fields. */
1293 if (!INTEGRAL_TYPE_P (lhstype)
1294 || TYPE_OVERFLOW_WRAPS (lhstype)
1295 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1296 return;
1298 switch (code)
1300 case MINUS_EXPR:
1301 case PLUS_EXPR:
1302 case MULT_EXPR:
1303 /* Transform
1304 i = u {+,-,*} 5;
1305 into
1306 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1307 a = gimple_assign_rhs1 (stmt);
1308 b = gimple_assign_rhs2 (stmt);
1309 g = gimple_build_call_internal (code == PLUS_EXPR
1310 ? IFN_UBSAN_CHECK_ADD
1311 : code == MINUS_EXPR
1312 ? IFN_UBSAN_CHECK_SUB
1313 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1314 gimple_call_set_lhs (g, lhs);
1315 gsi_replace (&gsi, g, false);
1316 break;
1317 case NEGATE_EXPR:
1318 /* Represent i = -u;
1320 i = UBSAN_CHECK_SUB (0, u); */
1321 a = build_int_cst (lhstype, 0);
1322 b = gimple_assign_rhs1 (stmt);
1323 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1324 gimple_call_set_lhs (g, lhs);
1325 gsi_replace (&gsi, g, false);
1326 break;
1327 case ABS_EXPR:
1328 /* Transform i = ABS_EXPR<u>;
1329 into
1330 _N = UBSAN_CHECK_SUB (0, u);
1331 i = ABS_EXPR<_N>; */
1332 a = build_int_cst (lhstype, 0);
1333 b = gimple_assign_rhs1 (stmt);
1334 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1335 a = make_ssa_name (lhstype);
1336 gimple_call_set_lhs (g, a);
1337 gimple_set_location (g, gimple_location (stmt));
1338 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1339 gimple_assign_set_rhs1 (stmt, a);
1340 update_stmt (stmt);
1341 break;
1342 default:
1343 break;
1347 /* Instrument loads from (non-bitfield) bool and C++ enum values
1348 to check if the memory value is outside of the range of the valid
1349 type values. */
1351 static void
1352 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1354 gimple *stmt = gsi_stmt (*gsi);
1355 tree rhs = gimple_assign_rhs1 (stmt);
1356 tree type = TREE_TYPE (rhs);
1357 tree minv = NULL_TREE, maxv = NULL_TREE;
1359 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1361 minv = boolean_false_node;
1362 maxv = boolean_true_node;
1364 else if (TREE_CODE (type) == ENUMERAL_TYPE
1365 && (flag_sanitize & SANITIZE_ENUM)
1366 && TREE_TYPE (type) != NULL_TREE
1367 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1368 && (TYPE_PRECISION (TREE_TYPE (type))
1369 < GET_MODE_PRECISION (TYPE_MODE (type))))
1371 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1372 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1374 else
1375 return;
1377 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1378 HOST_WIDE_INT bitsize, bitpos;
1379 tree offset;
1380 machine_mode mode;
1381 int volatilep = 0, unsignedp = 0;
1382 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1383 &unsignedp, &volatilep, false);
1384 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1386 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1387 || (bitpos % modebitsize) != 0
1388 || bitsize != modebitsize
1389 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1390 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1391 return;
1393 bool ends_bb = stmt_ends_bb_p (stmt);
1394 location_t loc = gimple_location (stmt);
1395 tree lhs = gimple_assign_lhs (stmt);
1396 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1397 tree atype = reference_alias_ptr_type (rhs);
1398 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1399 build_fold_addr_expr (rhs));
1400 gimple_set_location (g, loc);
1401 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1402 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1403 build_int_cst (atype, 0));
1404 tree urhs = make_ssa_name (utype);
1405 if (ends_bb)
1407 gimple_assign_set_lhs (stmt, urhs);
1408 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1409 gimple_set_location (g, loc);
1410 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1411 gsi_insert_on_edge_immediate (e, g);
1412 gimple_assign_set_rhs_from_tree (gsi, mem);
1413 update_stmt (stmt);
1414 *gsi = gsi_for_stmt (g);
1415 g = stmt;
1417 else
1419 g = gimple_build_assign (urhs, mem);
1420 gimple_set_location (g, loc);
1421 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1423 minv = fold_convert (utype, minv);
1424 maxv = fold_convert (utype, maxv);
1425 if (!integer_zerop (minv))
1427 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1428 gimple_set_location (g, loc);
1429 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1432 gimple_stmt_iterator gsi2 = *gsi;
1433 basic_block then_bb, fallthru_bb;
1434 *gsi = create_cond_insert_point (gsi, true, false, true,
1435 &then_bb, &fallthru_bb);
1436 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1437 int_const_binop (MINUS_EXPR, maxv, minv),
1438 NULL_TREE, NULL_TREE);
1439 gimple_set_location (g, loc);
1440 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1442 if (!ends_bb)
1444 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1445 update_stmt (stmt);
1448 gsi2 = gsi_after_labels (then_bb);
1449 if (flag_sanitize_undefined_trap_on_error)
1450 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1451 else
1453 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1454 ubsan_type_descriptor (type), NULL_TREE,
1455 NULL_TREE);
1456 data = build_fold_addr_expr_loc (loc, data);
1457 enum built_in_function bcode
1458 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1459 ? SANITIZE_BOOL : SANITIZE_ENUM))
1460 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1461 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1462 tree fn = builtin_decl_explicit (bcode);
1464 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1465 true, NULL_TREE, true,
1466 GSI_SAME_STMT);
1467 g = gimple_build_call (fn, 2, data, val);
1469 gimple_set_location (g, loc);
1470 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1471 ubsan_create_edge (g);
1472 *gsi = gsi_for_stmt (stmt);
1475 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1476 new style handlers. Libubsan uses heuristics to destinguish between old and
1477 new styles and relies on these properties for filename:
1479 a) Location's filename must not be NULL.
1480 b) Location's filename must not be equal to "".
1481 c) Location's filename must not be equal to "\1".
1482 d) First two bytes of filename must not contain '\xff' symbol. */
1484 static bool
1485 ubsan_use_new_style_p (location_t loc)
1487 if (loc == UNKNOWN_LOCATION)
1488 return false;
1490 expanded_location xloc = expand_location (loc);
1491 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1492 || xloc.file == '\0' || xloc.file[0] == '\xff'
1493 || xloc.file[1] == '\xff')
1494 return false;
1496 return true;
1499 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1500 destination, EXPR is floating-point expression. ARG is what to pass
1501 the libubsan call as value, often EXPR itself. */
1503 tree
1504 ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
1506 tree expr_type = TREE_TYPE (expr);
1507 tree t, tt, fn, min, max;
1508 machine_mode mode = TYPE_MODE (expr_type);
1509 int prec = TYPE_PRECISION (type);
1510 bool uns_p = TYPE_UNSIGNED (type);
1511 if (!loc) loc = input_location;
1513 /* Float to integer conversion first truncates toward zero, so
1514 even signed char c = 127.875f; is not problematic.
1515 Therefore, we should complain only if EXPR is unordered or smaller
1516 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1517 TYPE_MAX_VALUE + 1.0. */
1518 if (REAL_MODE_FORMAT (mode)->b == 2)
1520 /* For maximum, TYPE_MAX_VALUE might not be representable
1521 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1522 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1523 either representable or infinity. */
1524 REAL_VALUE_TYPE maxval = dconst1;
1525 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1526 real_convert (&maxval, mode, &maxval);
1527 max = build_real (expr_type, maxval);
1529 /* For unsigned, assume -1.0 is always representable. */
1530 if (uns_p)
1531 min = build_minus_one_cst (expr_type);
1532 else
1534 /* TYPE_MIN_VALUE is generally representable (or -inf),
1535 but TYPE_MIN_VALUE - 1.0 might not be. */
1536 REAL_VALUE_TYPE minval = dconstm1, minval2;
1537 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1538 real_convert (&minval, mode, &minval);
1539 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1540 real_convert (&minval2, mode, &minval2);
1541 if (real_compare (EQ_EXPR, &minval, &minval2)
1542 && !real_isinf (&minval))
1544 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1545 rounds to TYPE_MIN_VALUE, we need to subtract
1546 more. As REAL_MODE_FORMAT (mode)->p is the number
1547 of base digits, we want to subtract a number that
1548 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1549 times smaller than minval. */
1550 minval2 = dconst1;
1551 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1552 SET_REAL_EXP (&minval2,
1553 REAL_EXP (&minval2) + prec - 1
1554 - REAL_MODE_FORMAT (mode)->p + 1);
1555 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1556 real_convert (&minval2, mode, &minval2);
1558 min = build_real (expr_type, minval2);
1561 else if (REAL_MODE_FORMAT (mode)->b == 10)
1563 /* For _Decimal128 up to 34 decimal digits, - sign,
1564 dot, e, exponent. */
1565 char buf[64];
1566 mpfr_t m;
1567 int p = REAL_MODE_FORMAT (mode)->p;
1568 REAL_VALUE_TYPE maxval, minval;
1570 /* Use mpfr_snprintf rounding to compute the smallest
1571 representable decimal number greater or equal than
1572 1 << (prec - !uns_p). */
1573 mpfr_init2 (m, prec + 2);
1574 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1575 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1576 decimal_real_from_string (&maxval, buf);
1577 max = build_real (expr_type, maxval);
1579 /* For unsigned, assume -1.0 is always representable. */
1580 if (uns_p)
1581 min = build_minus_one_cst (expr_type);
1582 else
1584 /* Use mpfr_snprintf rounding to compute the largest
1585 representable decimal number less or equal than
1586 (-1 << (prec - 1)) - 1. */
1587 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1588 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1589 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1590 decimal_real_from_string (&minval, buf);
1591 min = build_real (expr_type, minval);
1593 mpfr_clear (m);
1595 else
1596 return NULL_TREE;
1598 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1599 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1600 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1601 if (integer_zerop (t))
1602 return NULL_TREE;
1604 if (flag_sanitize_undefined_trap_on_error)
1605 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1606 else
1608 location_t *loc_ptr = NULL;
1609 unsigned num_locations = 0;
1610 /* Figure out if we can propagate location to ubsan_data and use new
1611 style handlers in libubsan. */
1612 if (ubsan_use_new_style_p (loc))
1614 loc_ptr = &loc;
1615 num_locations = 1;
1617 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1618 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1619 num_locations, loc_ptr,
1620 ubsan_type_descriptor (expr_type),
1621 ubsan_type_descriptor (type), NULL_TREE,
1622 NULL_TREE);
1623 enum built_in_function bcode
1624 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1625 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1626 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1627 fn = builtin_decl_explicit (bcode);
1628 fn = build_call_expr_loc (loc, fn, 2,
1629 build_fold_addr_expr_loc (loc, data),
1630 ubsan_encode_value (arg, false));
1633 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1636 /* Instrument values passed to function arguments with nonnull attribute. */
1638 static void
1639 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1641 gimple *stmt = gsi_stmt (*gsi);
1642 location_t loc[2];
1643 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1644 while for nonnull sanitization it is clear. */
1645 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1646 flag_delete_null_pointer_checks = 1;
1647 loc[0] = gimple_location (stmt);
1648 loc[1] = UNKNOWN_LOCATION;
1649 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1651 tree arg = gimple_call_arg (stmt, i);
1652 if (POINTER_TYPE_P (TREE_TYPE (arg))
1653 && infer_nonnull_range_by_attribute (stmt, arg))
1655 gimple *g;
1656 if (!is_gimple_val (arg))
1658 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1659 gimple_set_location (g, loc[0]);
1660 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1661 arg = gimple_assign_lhs (g);
1664 basic_block then_bb, fallthru_bb;
1665 *gsi = create_cond_insert_point (gsi, true, false, true,
1666 &then_bb, &fallthru_bb);
1667 g = gimple_build_cond (EQ_EXPR, arg,
1668 build_zero_cst (TREE_TYPE (arg)),
1669 NULL_TREE, NULL_TREE);
1670 gimple_set_location (g, loc[0]);
1671 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1673 *gsi = gsi_after_labels (then_bb);
1674 if (flag_sanitize_undefined_trap_on_error)
1675 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1676 else
1678 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1679 2, loc, NULL_TREE,
1680 build_int_cst (integer_type_node,
1681 i + 1),
1682 NULL_TREE);
1683 data = build_fold_addr_expr_loc (loc[0], data);
1684 enum built_in_function bcode
1685 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1686 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1687 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1688 tree fn = builtin_decl_explicit (bcode);
1690 g = gimple_build_call (fn, 1, data);
1692 gimple_set_location (g, loc[0]);
1693 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1694 ubsan_create_edge (g);
1696 *gsi = gsi_for_stmt (stmt);
1698 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1701 /* Instrument returns in functions with returns_nonnull attribute. */
1703 static void
1704 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1706 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1707 location_t loc[2];
1708 tree arg = gimple_return_retval (stmt);
1709 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1710 while for nonnull return sanitization it is clear. */
1711 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1712 flag_delete_null_pointer_checks = 1;
1713 loc[0] = gimple_location (stmt);
1714 loc[1] = UNKNOWN_LOCATION;
1715 if (arg
1716 && POINTER_TYPE_P (TREE_TYPE (arg))
1717 && is_gimple_val (arg)
1718 && infer_nonnull_range_by_attribute (stmt, arg))
1720 basic_block then_bb, fallthru_bb;
1721 *gsi = create_cond_insert_point (gsi, true, false, true,
1722 &then_bb, &fallthru_bb);
1723 gimple *g = gimple_build_cond (EQ_EXPR, arg,
1724 build_zero_cst (TREE_TYPE (arg)),
1725 NULL_TREE, NULL_TREE);
1726 gimple_set_location (g, loc[0]);
1727 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1729 *gsi = gsi_after_labels (then_bb);
1730 if (flag_sanitize_undefined_trap_on_error)
1731 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1732 else
1734 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1735 2, loc, NULL_TREE, NULL_TREE);
1736 data = build_fold_addr_expr_loc (loc[0], data);
1737 enum built_in_function bcode
1738 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1739 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1740 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1741 tree fn = builtin_decl_explicit (bcode);
1743 g = gimple_build_call (fn, 1, data);
1745 gimple_set_location (g, loc[0]);
1746 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1747 ubsan_create_edge (g);
1748 *gsi = gsi_for_stmt (stmt);
1750 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1753 /* Instrument memory references. Here we check whether the pointer
1754 points to an out-of-bounds location. */
1756 static void
1757 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1759 gimple *stmt = gsi_stmt (*gsi);
1760 location_t loc = gimple_location (stmt);
1761 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1762 tree type;
1763 tree index = NULL_TREE;
1764 HOST_WIDE_INT size_in_bytes;
1766 type = TREE_TYPE (t);
1767 if (VOID_TYPE_P (type))
1768 return;
1770 switch (TREE_CODE (t))
1772 case COMPONENT_REF:
1773 if (TREE_CODE (t) == COMPONENT_REF
1774 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1776 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1777 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1778 repr, NULL_TREE);
1780 break;
1781 case ARRAY_REF:
1782 index = TREE_OPERAND (t, 1);
1783 break;
1784 case INDIRECT_REF:
1785 case MEM_REF:
1786 case VAR_DECL:
1787 case PARM_DECL:
1788 case RESULT_DECL:
1789 break;
1790 default:
1791 return;
1794 size_in_bytes = int_size_in_bytes (type);
1795 if (size_in_bytes <= 0)
1796 return;
1798 HOST_WIDE_INT bitsize, bitpos;
1799 tree offset;
1800 machine_mode mode;
1801 int volatilep = 0, unsignedp = 0;
1802 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1803 &unsignedp, &volatilep, false);
1805 if (bitpos % BITS_PER_UNIT != 0
1806 || bitsize != size_in_bytes * BITS_PER_UNIT)
1807 return;
1809 bool decl_p = DECL_P (inner);
1810 tree base;
1811 if (decl_p)
1812 base = inner;
1813 else if (TREE_CODE (inner) == MEM_REF)
1814 base = TREE_OPERAND (inner, 0);
1815 else
1816 return;
1817 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1819 while (TREE_CODE (base) == SSA_NAME)
1821 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
1822 if (gimple_assign_ssa_name_copy_p (def_stmt)
1823 || (gimple_assign_cast_p (def_stmt)
1824 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1825 || (is_gimple_assign (def_stmt)
1826 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1828 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1829 if (TREE_CODE (rhs1) == SSA_NAME
1830 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1831 break;
1832 else
1833 base = rhs1;
1835 else
1836 break;
1839 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1840 return;
1842 tree sizet;
1843 tree base_addr = base;
1844 gimple *bos_stmt = NULL;
1845 if (decl_p)
1846 base_addr = build1 (ADDR_EXPR,
1847 build_pointer_type (TREE_TYPE (base)), base);
1848 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1849 if (size != (unsigned HOST_WIDE_INT) -1)
1850 sizet = build_int_cst (sizetype, size);
1851 else if (optimize)
1853 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1854 loc = input_location;
1855 /* Generate __builtin_object_size call. */
1856 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1857 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1858 integer_zero_node);
1859 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1860 GSI_SAME_STMT);
1861 /* If the call above didn't end up being an integer constant, go one
1862 statement back and get the __builtin_object_size stmt. Save it,
1863 we might need it later. */
1864 if (SSA_VAR_P (sizet))
1866 gsi_prev (gsi);
1867 bos_stmt = gsi_stmt (*gsi);
1869 /* Move on to where we were. */
1870 gsi_next (gsi);
1873 else
1874 return;
1876 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1877 call. */
1878 /* ptr + sizeof (*ptr) - base */
1879 t = fold_build2 (MINUS_EXPR, sizetype,
1880 fold_convert (pointer_sized_int_node, ptr),
1881 fold_convert (pointer_sized_int_node, base_addr));
1882 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1884 /* Perhaps we can omit the check. */
1885 if (TREE_CODE (t) == INTEGER_CST
1886 && TREE_CODE (sizet) == INTEGER_CST
1887 && tree_int_cst_le (t, sizet))
1888 return;
1890 if (index != NULL_TREE
1891 && TREE_CODE (index) == SSA_NAME
1892 && TREE_CODE (sizet) == INTEGER_CST)
1894 gimple *def = SSA_NAME_DEF_STMT (index);
1895 if (is_gimple_assign (def)
1896 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1897 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1899 tree cst = gimple_assign_rhs2 (def);
1900 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1901 TYPE_SIZE_UNIT (type));
1902 if (tree_int_cst_sgn (cst) >= 0
1903 && tree_int_cst_lt (cst, sz))
1904 return;
1908 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1909 ubsan_create_edge (bos_stmt);
1911 /* We have to emit the check. */
1912 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1913 GSI_SAME_STMT);
1914 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1915 GSI_SAME_STMT);
1916 tree ckind = build_int_cst (unsigned_char_type_node,
1917 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1918 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1919 ptr, t, sizet, ckind);
1920 gimple_set_location (g, loc);
1921 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1924 /* True if we want to play UBSan games in the current function. */
1926 bool
1927 do_ubsan_in_current_function ()
1929 return (current_function_decl != NULL_TREE
1930 && !lookup_attribute ("no_sanitize_undefined",
1931 DECL_ATTRIBUTES (current_function_decl)));
1934 namespace {
1936 const pass_data pass_data_ubsan =
1938 GIMPLE_PASS, /* type */
1939 "ubsan", /* name */
1940 OPTGROUP_NONE, /* optinfo_flags */
1941 TV_TREE_UBSAN, /* tv_id */
1942 ( PROP_cfg | PROP_ssa ), /* properties_required */
1943 0, /* properties_provided */
1944 0, /* properties_destroyed */
1945 0, /* todo_flags_start */
1946 TODO_update_ssa, /* todo_flags_finish */
1949 class pass_ubsan : public gimple_opt_pass
1951 public:
1952 pass_ubsan (gcc::context *ctxt)
1953 : gimple_opt_pass (pass_data_ubsan, ctxt)
1956 /* opt_pass methods: */
1957 virtual bool gate (function *)
1959 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1960 | SANITIZE_BOOL | SANITIZE_ENUM
1961 | SANITIZE_ALIGNMENT
1962 | SANITIZE_NONNULL_ATTRIBUTE
1963 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1964 | SANITIZE_OBJECT_SIZE)
1965 && do_ubsan_in_current_function ();
1968 virtual unsigned int execute (function *);
1970 }; // class pass_ubsan
1972 unsigned int
1973 pass_ubsan::execute (function *fun)
1975 basic_block bb;
1976 gimple_stmt_iterator gsi;
1978 initialize_sanitizer_builtins ();
1980 FOR_EACH_BB_FN (bb, fun)
1982 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1984 gimple *stmt = gsi_stmt (gsi);
1985 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1987 gsi_next (&gsi);
1988 continue;
1991 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1992 && is_gimple_assign (stmt))
1993 instrument_si_overflow (gsi);
1995 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1997 if (gimple_store_p (stmt))
1998 instrument_null (gsi, true);
1999 if (gimple_assign_load_p (stmt))
2000 instrument_null (gsi, false);
2003 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
2004 && gimple_assign_load_p (stmt))
2006 instrument_bool_enum_load (&gsi);
2007 bb = gimple_bb (stmt);
2010 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
2011 && is_gimple_call (stmt)
2012 && !gimple_call_internal_p (stmt))
2014 instrument_nonnull_arg (&gsi);
2015 bb = gimple_bb (stmt);
2018 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2019 && gimple_code (stmt) == GIMPLE_RETURN)
2021 instrument_nonnull_return (&gsi);
2022 bb = gimple_bb (stmt);
2025 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2027 if (gimple_store_p (stmt))
2028 instrument_object_size (&gsi, true);
2029 if (gimple_assign_load_p (stmt))
2030 instrument_object_size (&gsi, false);
2033 gsi_next (&gsi);
2036 return 0;
2039 } // anon namespace
2041 gimple_opt_pass *
2042 make_pass_ubsan (gcc::context *ctxt)
2044 return new pass_ubsan (ctxt);
2047 #include "gt-ubsan.h"