2015-03-21 Sandra Loosemore <sandra@codesourcery.com>
[official-gcc.git] / gcc / ubsan.c
blob0e23d919744de85acd93193db5ae3ad79013c73f
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 "hash-set.h"
25 #include "machmode.h"
26 #include "vec.h"
27 #include "double-int.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "options.h"
32 #include "wide-int.h"
33 #include "inchash.h"
34 #include "tree.h"
35 #include "fold-const.h"
36 #include "stor-layout.h"
37 #include "stringpool.h"
38 #include "predict.h"
39 #include "dominance.h"
40 #include "cfg.h"
41 #include "cfganal.h"
42 #include "basic-block.h"
43 #include "hash-map.h"
44 #include "is-a.h"
45 #include "plugin-api.h"
46 #include "tm.h"
47 #include "hard-reg-set.h"
48 #include "function.h"
49 #include "ipa-ref.h"
50 #include "cgraph.h"
51 #include "tree-pass.h"
52 #include "tree-ssa-alias.h"
53 #include "tree-pretty-print.h"
54 #include "internal-fn.h"
55 #include "gimple-expr.h"
56 #include "gimple.h"
57 #include "gimple-iterator.h"
58 #include "gimple-ssa.h"
59 #include "gimple-walk.h"
60 #include "output.h"
61 #include "tm_p.h"
62 #include "toplev.h"
63 #include "cfgloop.h"
64 #include "ubsan.h"
65 #include "c-family/c-common.h"
66 #include "rtl.h"
67 #include "hashtab.h"
68 #include "flags.h"
69 #include "statistics.h"
70 #include "real.h"
71 #include "fixed-value.h"
72 #include "insn-config.h"
73 #include "expmed.h"
74 #include "dojump.h"
75 #include "explow.h"
76 #include "calls.h"
77 #include "emit-rtl.h"
78 #include "varasm.h"
79 #include "stmt.h"
80 #include "expr.h"
81 #include "tree-ssanames.h"
82 #include "asan.h"
83 #include "gimplify-me.h"
84 #include "intl.h"
85 #include "realmpfr.h"
86 #include "dfp.h"
87 #include "builtins.h"
88 #include "tree-object-size.h"
89 #include "tree-eh.h"
91 /* Map from a tree to a VAR_DECL tree. */
93 struct GTY((for_user)) tree_type_map {
94 struct tree_map_base type;
95 tree decl;
98 struct tree_type_map_cache_hasher : ggc_cache_hasher<tree_type_map *>
100 static inline hashval_t
101 hash (tree_type_map *t)
103 return TYPE_UID (t->type.from);
106 static inline bool
107 equal (tree_type_map *a, tree_type_map *b)
109 return a->type.from == b->type.from;
112 static void
113 handle_cache_entry (tree_type_map *&m)
115 extern void gt_ggc_mx (tree_type_map *&);
116 if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
117 return;
118 else if (ggc_marked_p (m->type.from))
119 gt_ggc_mx (m);
120 else
121 m = static_cast<tree_type_map *> (HTAB_DELETED_ENTRY);
125 static GTY ((cache))
126 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
128 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
130 static tree
131 decl_for_type_lookup (tree type)
133 /* If the hash table is not initialized yet, create it now. */
134 if (decl_tree_for_type == NULL)
136 decl_tree_for_type
137 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
138 /* That also means we don't have to bother with the lookup. */
139 return NULL_TREE;
142 struct tree_type_map *h, in;
143 in.type.from = type;
145 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
146 return h ? h->decl : NULL_TREE;
149 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
151 static void
152 decl_for_type_insert (tree type, tree decl)
154 struct tree_type_map *h;
156 h = ggc_alloc<tree_type_map> ();
157 h->type.from = type;
158 h->decl = decl;
159 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
162 /* Helper routine, which encodes a value in the pointer_sized_int_node.
163 Arguments with precision <= POINTER_SIZE are passed directly,
164 the rest is passed by reference. T is a value we are to encode.
165 IN_EXPAND_P is true if this function is called during expansion. */
167 tree
168 ubsan_encode_value (tree t, bool in_expand_p)
170 tree type = TREE_TYPE (t);
171 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
172 if (bitsize <= POINTER_SIZE)
173 switch (TREE_CODE (type))
175 case BOOLEAN_TYPE:
176 case ENUMERAL_TYPE:
177 case INTEGER_TYPE:
178 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
179 case REAL_TYPE:
181 tree itype = build_nonstandard_integer_type (bitsize, true);
182 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
183 return fold_convert (pointer_sized_int_node, t);
185 default:
186 gcc_unreachable ();
188 else
190 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
192 /* The reason for this is that we don't want to pessimize
193 code by making vars unnecessarily addressable. */
194 tree var = create_tmp_var (type);
195 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
196 if (in_expand_p)
198 rtx mem
199 = assign_stack_temp_for_type (TYPE_MODE (type),
200 GET_MODE_SIZE (TYPE_MODE (type)),
201 type);
202 SET_DECL_RTL (var, mem);
203 expand_assignment (var, t, false);
204 return build_fold_addr_expr (var);
206 t = build_fold_addr_expr (var);
207 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
209 else
210 return build_fold_addr_expr (t);
214 /* Cached ubsan_get_type_descriptor_type () return value. */
215 static GTY(()) tree ubsan_type_descriptor_type;
217 /* Build
218 struct __ubsan_type_descriptor
220 unsigned short __typekind;
221 unsigned short __typeinfo;
222 char __typename[];
224 type. */
226 static tree
227 ubsan_get_type_descriptor_type (void)
229 static const char *field_names[3]
230 = { "__typekind", "__typeinfo", "__typename" };
231 tree fields[3], ret;
233 if (ubsan_type_descriptor_type)
234 return ubsan_type_descriptor_type;
236 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
237 tree flex_arr_type = build_array_type (char_type_node, itype);
239 ret = make_node (RECORD_TYPE);
240 for (int i = 0; i < 3; i++)
242 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
243 get_identifier (field_names[i]),
244 (i == 2) ? flex_arr_type
245 : short_unsigned_type_node);
246 DECL_CONTEXT (fields[i]) = ret;
247 if (i)
248 DECL_CHAIN (fields[i - 1]) = fields[i];
250 tree type_decl = build_decl (input_location, TYPE_DECL,
251 get_identifier ("__ubsan_type_descriptor"),
252 ret);
253 DECL_IGNORED_P (type_decl) = 1;
254 DECL_ARTIFICIAL (type_decl) = 1;
255 TYPE_FIELDS (ret) = fields[0];
256 TYPE_NAME (ret) = type_decl;
257 TYPE_STUB_DECL (ret) = type_decl;
258 layout_type (ret);
259 ubsan_type_descriptor_type = ret;
260 return ret;
263 /* Cached ubsan_get_source_location_type () return value. */
264 static GTY(()) tree ubsan_source_location_type;
266 /* Build
267 struct __ubsan_source_location
269 const char *__filename;
270 unsigned int __line;
271 unsigned int __column;
273 type. */
275 tree
276 ubsan_get_source_location_type (void)
278 static const char *field_names[3]
279 = { "__filename", "__line", "__column" };
280 tree fields[3], ret;
281 if (ubsan_source_location_type)
282 return ubsan_source_location_type;
284 tree const_char_type = build_qualified_type (char_type_node,
285 TYPE_QUAL_CONST);
287 ret = make_node (RECORD_TYPE);
288 for (int i = 0; i < 3; i++)
290 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
291 get_identifier (field_names[i]),
292 (i == 0) ? build_pointer_type (const_char_type)
293 : unsigned_type_node);
294 DECL_CONTEXT (fields[i]) = ret;
295 if (i)
296 DECL_CHAIN (fields[i - 1]) = fields[i];
298 tree type_decl = build_decl (input_location, TYPE_DECL,
299 get_identifier ("__ubsan_source_location"),
300 ret);
301 DECL_IGNORED_P (type_decl) = 1;
302 DECL_ARTIFICIAL (type_decl) = 1;
303 TYPE_FIELDS (ret) = fields[0];
304 TYPE_NAME (ret) = type_decl;
305 TYPE_STUB_DECL (ret) = type_decl;
306 layout_type (ret);
307 ubsan_source_location_type = ret;
308 return ret;
311 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
312 type with its fields filled from a location_t LOC. */
314 static tree
315 ubsan_source_location (location_t loc)
317 expanded_location xloc;
318 tree type = ubsan_get_source_location_type ();
320 xloc = expand_location (loc);
321 tree str;
322 if (xloc.file == NULL)
324 str = build_int_cst (ptr_type_node, 0);
325 xloc.line = 0;
326 xloc.column = 0;
328 else
330 /* Fill in the values from LOC. */
331 size_t len = strlen (xloc.file) + 1;
332 str = build_string (len, xloc.file);
333 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
334 TREE_READONLY (str) = 1;
335 TREE_STATIC (str) = 1;
336 str = build_fold_addr_expr (str);
338 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
339 build_int_cst (unsigned_type_node,
340 xloc.line), NULL_TREE,
341 build_int_cst (unsigned_type_node,
342 xloc.column));
343 TREE_CONSTANT (ctor) = 1;
344 TREE_STATIC (ctor) = 1;
346 return ctor;
349 /* This routine returns a magic number for TYPE. */
351 static unsigned short
352 get_ubsan_type_info_for_type (tree type)
354 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
355 if (TREE_CODE (type) == REAL_TYPE)
356 return tree_to_uhwi (TYPE_SIZE (type));
357 else if (INTEGRAL_TYPE_P (type))
359 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
360 gcc_assert (prec != -1);
361 return (prec << 1) | !TYPE_UNSIGNED (type);
363 else
364 return 0;
367 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
368 descriptor. It first looks into the hash table; if not found,
369 create the VAR_DECL, put it into the hash table and return the
370 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
371 an enum controlling how we want to print the type. */
373 tree
374 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
376 /* See through any typedefs. */
377 type = TYPE_MAIN_VARIANT (type);
379 tree decl = decl_for_type_lookup (type);
380 /* It is possible that some of the earlier created DECLs were found
381 unused, in that case they weren't emitted and varpool_node::get
382 returns NULL node on them. But now we really need them. Thus,
383 renew them here. */
384 if (decl != NULL_TREE && varpool_node::get (decl))
385 return build_fold_addr_expr (decl);
387 tree dtype = ubsan_get_type_descriptor_type ();
388 tree type2 = type;
389 const char *tname = NULL;
390 pretty_printer pretty_name;
391 unsigned char deref_depth = 0;
392 unsigned short tkind, tinfo;
394 /* Get the name of the type, or the name of the pointer type. */
395 if (pstyle == UBSAN_PRINT_POINTER)
397 gcc_assert (POINTER_TYPE_P (type));
398 type2 = TREE_TYPE (type);
400 /* Remove any '*' operators from TYPE. */
401 while (POINTER_TYPE_P (type2))
402 deref_depth++, type2 = TREE_TYPE (type2);
404 if (TREE_CODE (type2) == METHOD_TYPE)
405 type2 = TYPE_METHOD_BASETYPE (type2);
408 /* If an array, get its type. */
409 type2 = strip_array_types (type2);
411 if (pstyle == UBSAN_PRINT_ARRAY)
413 while (POINTER_TYPE_P (type2))
414 deref_depth++, type2 = TREE_TYPE (type2);
417 if (TYPE_NAME (type2) != NULL)
419 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
420 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
421 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
422 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
425 if (tname == NULL)
426 /* We weren't able to determine the type name. */
427 tname = "<unknown>";
429 if (pstyle == UBSAN_PRINT_POINTER)
431 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
432 TYPE_VOLATILE (type2) ? "volatile " : "",
433 TYPE_READONLY (type2) ? "const " : "",
434 TYPE_RESTRICT (type2) ? "restrict " : "",
435 TYPE_ATOMIC (type2) ? "_Atomic " : "",
436 TREE_CODE (type2) == RECORD_TYPE
437 ? "struct "
438 : TREE_CODE (type2) == UNION_TYPE
439 ? "union " : "", tname,
440 deref_depth == 0 ? "" : " ");
441 while (deref_depth-- > 0)
442 pp_star (&pretty_name);
443 pp_quote (&pretty_name);
445 else if (pstyle == UBSAN_PRINT_ARRAY)
447 /* Pretty print the array dimensions. */
448 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
449 tree t = type;
450 pp_printf (&pretty_name, "'%s ", tname);
451 while (deref_depth-- > 0)
452 pp_star (&pretty_name);
453 while (TREE_CODE (t) == ARRAY_TYPE)
455 pp_left_bracket (&pretty_name);
456 tree dom = TYPE_DOMAIN (t);
457 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
459 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
460 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
461 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
462 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
463 else
464 pp_wide_int (&pretty_name,
465 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
466 TYPE_SIGN (TREE_TYPE (dom)));
468 else
469 /* ??? We can't determine the variable name; print VLA unspec. */
470 pp_star (&pretty_name);
471 pp_right_bracket (&pretty_name);
472 t = TREE_TYPE (t);
474 pp_quote (&pretty_name);
476 /* Save the tree with stripped types. */
477 type = t;
479 else
480 pp_printf (&pretty_name, "'%s'", tname);
482 switch (TREE_CODE (type))
484 case BOOLEAN_TYPE:
485 case ENUMERAL_TYPE:
486 case INTEGER_TYPE:
487 tkind = 0x0000;
488 break;
489 case REAL_TYPE:
490 /* FIXME: libubsan right now only supports float, double and
491 long double type formats. */
492 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
493 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
494 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
495 tkind = 0x0001;
496 else
497 tkind = 0xffff;
498 break;
499 default:
500 tkind = 0xffff;
501 break;
503 tinfo = get_ubsan_type_info_for_type (type);
505 /* Create a new VAR_DECL of type descriptor. */
506 const char *tmp = pp_formatted_text (&pretty_name);
507 size_t len = strlen (tmp) + 1;
508 tree str = build_string (len, tmp);
509 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
510 TREE_READONLY (str) = 1;
511 TREE_STATIC (str) = 1;
513 char tmp_name[32];
514 static unsigned int type_var_id_num;
515 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
516 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
517 dtype);
518 TREE_STATIC (decl) = 1;
519 TREE_PUBLIC (decl) = 0;
520 DECL_ARTIFICIAL (decl) = 1;
521 DECL_IGNORED_P (decl) = 1;
522 DECL_EXTERNAL (decl) = 0;
523 DECL_SIZE (decl)
524 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
525 DECL_SIZE_UNIT (decl)
526 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
527 TYPE_SIZE_UNIT (TREE_TYPE (str)));
529 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
530 build_int_cst (short_unsigned_type_node,
531 tkind), NULL_TREE,
532 build_int_cst (short_unsigned_type_node,
533 tinfo), NULL_TREE, str);
534 TREE_CONSTANT (ctor) = 1;
535 TREE_STATIC (ctor) = 1;
536 DECL_INITIAL (decl) = ctor;
537 varpool_node::finalize_decl (decl);
539 /* Save the VAR_DECL into the hash table. */
540 decl_for_type_insert (type, decl);
542 return build_fold_addr_expr (decl);
545 /* Create a structure for the ubsan library. NAME is a name of the new
546 structure. LOCCNT is number of locations, PLOC points to array of
547 locations. The arguments in ... are of __ubsan_type_descriptor type
548 and there are at most two of them, followed by NULL_TREE, followed
549 by optional extra arguments and another NULL_TREE. */
551 tree
552 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
554 va_list args;
555 tree ret, t;
556 tree fields[6];
557 vec<tree, va_gc> *saved_args = NULL;
558 size_t i = 0;
559 int j;
561 /* Firstly, create a pointer to type descriptor type. */
562 tree td_type = ubsan_get_type_descriptor_type ();
563 td_type = build_pointer_type (td_type);
565 /* Create the structure type. */
566 ret = make_node (RECORD_TYPE);
567 for (j = 0; j < loccnt; j++)
569 gcc_checking_assert (i < 2);
570 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
571 ubsan_get_source_location_type ());
572 DECL_CONTEXT (fields[i]) = ret;
573 if (i)
574 DECL_CHAIN (fields[i - 1]) = fields[i];
575 i++;
578 va_start (args, ploc);
579 for (t = va_arg (args, tree); t != NULL_TREE;
580 i++, t = va_arg (args, tree))
582 gcc_checking_assert (i < 4);
583 /* Save the tree arguments for later use. */
584 vec_safe_push (saved_args, t);
585 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
586 td_type);
587 DECL_CONTEXT (fields[i]) = ret;
588 if (i)
589 DECL_CHAIN (fields[i - 1]) = fields[i];
592 for (t = va_arg (args, tree); t != NULL_TREE;
593 i++, t = va_arg (args, tree))
595 gcc_checking_assert (i < 6);
596 /* Save the tree arguments for later use. */
597 vec_safe_push (saved_args, t);
598 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
599 TREE_TYPE (t));
600 DECL_CONTEXT (fields[i]) = ret;
601 if (i)
602 DECL_CHAIN (fields[i - 1]) = fields[i];
604 va_end (args);
606 tree type_decl = build_decl (input_location, TYPE_DECL,
607 get_identifier (name), ret);
608 DECL_IGNORED_P (type_decl) = 1;
609 DECL_ARTIFICIAL (type_decl) = 1;
610 TYPE_FIELDS (ret) = fields[0];
611 TYPE_NAME (ret) = type_decl;
612 TYPE_STUB_DECL (ret) = type_decl;
613 layout_type (ret);
615 /* Now, fill in the type. */
616 char tmp_name[32];
617 static unsigned int ubsan_var_id_num;
618 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
619 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
620 ret);
621 TREE_STATIC (var) = 1;
622 TREE_PUBLIC (var) = 0;
623 DECL_ARTIFICIAL (var) = 1;
624 DECL_IGNORED_P (var) = 1;
625 DECL_EXTERNAL (var) = 0;
627 vec<constructor_elt, va_gc> *v;
628 vec_alloc (v, i);
629 tree ctor = build_constructor (ret, v);
631 /* If desirable, set the __ubsan_source_location element. */
632 for (j = 0; j < loccnt; j++)
634 location_t loc = LOCATION_LOCUS (ploc[j]);
635 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
638 size_t nelts = vec_safe_length (saved_args);
639 for (i = 0; i < nelts; i++)
641 t = (*saved_args)[i];
642 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
645 TREE_CONSTANT (ctor) = 1;
646 TREE_STATIC (ctor) = 1;
647 DECL_INITIAL (var) = ctor;
648 varpool_node::finalize_decl (var);
650 return var;
653 /* Instrument the __builtin_unreachable call. We just call the libubsan
654 routine instead. */
656 bool
657 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
659 gimple g;
660 location_t loc = gimple_location (gsi_stmt (*gsi));
662 if (flag_sanitize_undefined_trap_on_error)
663 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
664 else
666 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
667 NULL_TREE, NULL_TREE);
668 data = build_fold_addr_expr_loc (loc, data);
669 tree fn
670 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
671 g = gimple_build_call (fn, 1, data);
673 gimple_set_location (g, loc);
674 gsi_replace (gsi, g, false);
675 return false;
678 /* Return true if T is a call to a libubsan routine. */
680 bool
681 is_ubsan_builtin_p (tree t)
683 return TREE_CODE (t) == FUNCTION_DECL
684 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
685 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
686 "__builtin___ubsan_", 18) == 0;
689 /* Expand the UBSAN_BOUNDS special builtin function. */
691 bool
692 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
694 gimple stmt = gsi_stmt (*gsi);
695 location_t loc = gimple_location (stmt);
696 gcc_assert (gimple_call_num_args (stmt) == 3);
698 /* Pick up the arguments of the UBSAN_BOUNDS call. */
699 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
700 tree index = gimple_call_arg (stmt, 1);
701 tree orig_index_type = TREE_TYPE (index);
702 tree bound = gimple_call_arg (stmt, 2);
704 gimple_stmt_iterator gsi_orig = *gsi;
706 /* Create condition "if (index > bound)". */
707 basic_block then_bb, fallthru_bb;
708 gimple_stmt_iterator cond_insert_point
709 = create_cond_insert_point (gsi, false, false, true,
710 &then_bb, &fallthru_bb);
711 index = fold_convert (TREE_TYPE (bound), index);
712 index = force_gimple_operand_gsi (&cond_insert_point, index,
713 true, NULL_TREE,
714 false, GSI_NEW_STMT);
715 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
716 gimple_set_location (g, loc);
717 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
719 /* Generate __ubsan_handle_out_of_bounds call. */
720 *gsi = gsi_after_labels (then_bb);
721 if (flag_sanitize_undefined_trap_on_error)
722 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
723 else
725 tree data
726 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
727 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
728 ubsan_type_descriptor (orig_index_type),
729 NULL_TREE, NULL_TREE);
730 data = build_fold_addr_expr_loc (loc, data);
731 enum built_in_function bcode
732 = (flag_sanitize_recover & SANITIZE_BOUNDS)
733 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
734 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
735 tree fn = builtin_decl_explicit (bcode);
736 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
737 true, NULL_TREE, true,
738 GSI_SAME_STMT);
739 g = gimple_build_call (fn, 2, data, val);
741 gimple_set_location (g, loc);
742 gsi_insert_before (gsi, g, GSI_SAME_STMT);
744 /* Get rid of the UBSAN_BOUNDS call from the IR. */
745 unlink_stmt_vdef (stmt);
746 gsi_remove (&gsi_orig, true);
748 /* Point GSI to next logical statement. */
749 *gsi = gsi_start_bb (fallthru_bb);
750 return true;
753 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
754 argument which is a constant, because the middle-end treats pointer
755 conversions as useless and therefore the type of the first argument
756 could be changed to any other pointer type. */
758 bool
759 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
761 gimple_stmt_iterator gsi = *gsip;
762 gimple stmt = gsi_stmt (gsi);
763 location_t loc = gimple_location (stmt);
764 gcc_assert (gimple_call_num_args (stmt) == 3);
765 tree ptr = gimple_call_arg (stmt, 0);
766 tree ckind = gimple_call_arg (stmt, 1);
767 tree align = gimple_call_arg (stmt, 2);
768 tree check_align = NULL_TREE;
769 bool check_null;
771 basic_block cur_bb = gsi_bb (gsi);
773 gimple g;
774 if (!integer_zerop (align))
776 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
777 if (compare_tree_int (align, ptralign) == 1)
779 check_align = make_ssa_name (pointer_sized_int_node);
780 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
781 gimple_set_location (g, loc);
782 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
785 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
787 if (check_align == NULL_TREE && !check_null)
789 gsi_remove (gsip, true);
790 /* Unlink the UBSAN_NULLs vops before replacing it. */
791 unlink_stmt_vdef (stmt);
792 return true;
795 /* Split the original block holding the pointer dereference. */
796 edge e = split_block (cur_bb, stmt);
798 /* Get a hold on the 'condition block', the 'then block' and the
799 'else block'. */
800 basic_block cond_bb = e->src;
801 basic_block fallthru_bb = e->dest;
802 basic_block then_bb = create_empty_bb (cond_bb);
803 add_bb_to_loop (then_bb, cond_bb->loop_father);
804 loops_state_set (LOOPS_NEED_FIXUP);
806 /* Make an edge coming from the 'cond block' into the 'then block';
807 this edge is unlikely taken, so set up the probability accordingly. */
808 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
809 e->probability = PROB_VERY_UNLIKELY;
811 /* Connect 'then block' with the 'else block'. This is needed
812 as the ubsan routines we call in the 'then block' are not noreturn.
813 The 'then block' only has one outcoming edge. */
814 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
816 /* Set up the fallthrough basic block. */
817 e = find_edge (cond_bb, fallthru_bb);
818 e->flags = EDGE_FALSE_VALUE;
819 e->count = cond_bb->count;
820 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
822 /* Update dominance info for the newly created then_bb; note that
823 fallthru_bb's dominance info has already been updated by
824 split_block. */
825 if (dom_info_available_p (CDI_DOMINATORS))
826 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
828 /* Put the ubsan builtin call into the newly created BB. */
829 if (flag_sanitize_undefined_trap_on_error)
830 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
831 else
833 enum built_in_function bcode
834 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
835 | (check_null ? SANITIZE_NULL : 0)))
836 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
837 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
838 tree fn = builtin_decl_implicit (bcode);
839 tree data
840 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
841 ubsan_type_descriptor (TREE_TYPE (ckind),
842 UBSAN_PRINT_POINTER),
843 NULL_TREE,
844 align,
845 fold_convert (unsigned_char_type_node, ckind),
846 NULL_TREE);
847 data = build_fold_addr_expr_loc (loc, data);
848 g = gimple_build_call (fn, 2, data,
849 check_align ? check_align
850 : build_zero_cst (pointer_sized_int_node));
852 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
853 gimple_set_location (g, loc);
854 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
856 /* Unlink the UBSAN_NULLs vops before replacing it. */
857 unlink_stmt_vdef (stmt);
859 if (check_null)
861 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
862 NULL_TREE, NULL_TREE);
863 gimple_set_location (g, loc);
865 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
866 gsi_replace (&gsi, g, false);
867 stmt = g;
870 if (check_align)
872 if (check_null)
874 /* Split the block with the condition again. */
875 e = split_block (cond_bb, stmt);
876 basic_block cond1_bb = e->src;
877 basic_block cond2_bb = e->dest;
879 /* Make an edge coming from the 'cond1 block' into the 'then block';
880 this edge is unlikely taken, so set up the probability
881 accordingly. */
882 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
883 e->probability = PROB_VERY_UNLIKELY;
885 /* Set up the fallthrough basic block. */
886 e = find_edge (cond1_bb, cond2_bb);
887 e->flags = EDGE_FALSE_VALUE;
888 e->count = cond1_bb->count;
889 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
891 /* Update dominance info. */
892 if (dom_info_available_p (CDI_DOMINATORS))
894 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
895 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
898 gsi2 = gsi_start_bb (cond2_bb);
901 tree mask = build_int_cst (pointer_sized_int_node,
902 tree_to_uhwi (align) - 1);
903 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
904 BIT_AND_EXPR, check_align, mask);
905 gimple_set_location (g, loc);
906 if (check_null)
907 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
908 else
909 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
911 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
912 build_int_cst (pointer_sized_int_node, 0),
913 NULL_TREE, NULL_TREE);
914 gimple_set_location (g, loc);
915 if (check_null)
916 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
917 else
918 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
919 gsi_replace (&gsi, g, false);
921 return false;
924 #define OBJSZ_MAX_OFFSET (1024 * 16)
926 /* Expand UBSAN_OBJECT_SIZE internal call. */
928 bool
929 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
931 gimple stmt = gsi_stmt (*gsi);
932 location_t loc = gimple_location (stmt);
933 gcc_assert (gimple_call_num_args (stmt) == 4);
935 tree ptr = gimple_call_arg (stmt, 0);
936 tree offset = gimple_call_arg (stmt, 1);
937 tree size = gimple_call_arg (stmt, 2);
938 tree ckind = gimple_call_arg (stmt, 3);
939 gimple_stmt_iterator gsi_orig = *gsi;
940 gimple g;
942 /* See if we can discard the check. */
943 if (TREE_CODE (size) != INTEGER_CST
944 || integer_all_onesp (size))
945 /* Yes, __builtin_object_size couldn't determine the
946 object size. */;
947 else if (TREE_CODE (offset) == INTEGER_CST
948 && wi::ges_p (wi::to_widest (offset), -OBJSZ_MAX_OFFSET)
949 && wi::les_p (wi::to_widest (offset), -1))
950 /* The offset is in range [-16K, -1]. */;
951 else
953 /* if (offset > objsize) */
954 basic_block then_bb, fallthru_bb;
955 gimple_stmt_iterator cond_insert_point
956 = create_cond_insert_point (gsi, false, false, true,
957 &then_bb, &fallthru_bb);
958 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
959 gimple_set_location (g, loc);
960 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
962 /* If the offset is small enough, we don't need the second
963 run-time check. */
964 if (TREE_CODE (offset) == INTEGER_CST
965 && wi::ges_p (wi::to_widest (offset), 0)
966 && wi::les_p (wi::to_widest (offset), OBJSZ_MAX_OFFSET))
967 *gsi = gsi_after_labels (then_bb);
968 else
970 /* Don't issue run-time error if (ptr > ptr + offset). That
971 may happen when computing a POINTER_PLUS_EXPR. */
972 basic_block then2_bb, fallthru2_bb;
974 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
975 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
976 true, &then2_bb,
977 &fallthru2_bb);
978 /* Convert the pointer to an integer type. */
979 tree p = make_ssa_name (pointer_sized_int_node);
980 g = gimple_build_assign (p, NOP_EXPR, ptr);
981 gimple_set_location (g, loc);
982 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
983 p = gimple_assign_lhs (g);
984 /* Compute ptr + offset. */
985 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
986 PLUS_EXPR, p, offset);
987 gimple_set_location (g, loc);
988 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
989 /* Now build the conditional and put it into the IR. */
990 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
991 NULL_TREE, NULL_TREE);
992 gimple_set_location (g, loc);
993 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
994 *gsi = gsi_after_labels (then2_bb);
997 /* Generate __ubsan_handle_type_mismatch call. */
998 if (flag_sanitize_undefined_trap_on_error)
999 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1000 else
1002 tree data
1003 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
1004 ubsan_type_descriptor (TREE_TYPE (ptr),
1005 UBSAN_PRINT_POINTER),
1006 NULL_TREE,
1007 build_zero_cst (pointer_sized_int_node),
1008 ckind,
1009 NULL_TREE);
1010 data = build_fold_addr_expr_loc (loc, data);
1011 enum built_in_function bcode
1012 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1013 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1014 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
1015 tree p = make_ssa_name (pointer_sized_int_node);
1016 g = gimple_build_assign (p, NOP_EXPR, ptr);
1017 gimple_set_location (g, loc);
1018 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1019 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1021 gimple_set_location (g, loc);
1022 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1024 /* Point GSI to next logical statement. */
1025 *gsi = gsi_start_bb (fallthru_bb);
1027 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1028 unlink_stmt_vdef (stmt);
1029 gsi_remove (&gsi_orig, true);
1030 return true;
1033 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1034 unlink_stmt_vdef (stmt);
1035 gsi_remove (gsi, true);
1036 return true;
1039 /* Cached __ubsan_vptr_type_cache decl. */
1040 static GTY(()) tree ubsan_vptr_type_cache_decl;
1042 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1043 argument which is a constant, because the middle-end treats pointer
1044 conversions as useless and therefore the type of the first argument
1045 could be changed to any other pointer type. */
1047 bool
1048 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1050 gimple_stmt_iterator gsi = *gsip;
1051 gimple stmt = gsi_stmt (gsi);
1052 location_t loc = gimple_location (stmt);
1053 gcc_assert (gimple_call_num_args (stmt) == 5);
1054 tree op = gimple_call_arg (stmt, 0);
1055 tree vptr = gimple_call_arg (stmt, 1);
1056 tree str_hash = gimple_call_arg (stmt, 2);
1057 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1058 tree ckind_tree = gimple_call_arg (stmt, 4);
1059 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1060 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1061 gimple g;
1062 basic_block fallthru_bb = NULL;
1064 if (ckind == UBSAN_DOWNCAST_POINTER)
1066 /* Guard everything with if (op != NULL) { ... }. */
1067 basic_block then_bb;
1068 gimple_stmt_iterator cond_insert_point
1069 = create_cond_insert_point (gsip, false, false, true,
1070 &then_bb, &fallthru_bb);
1071 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1072 NULL_TREE, NULL_TREE);
1073 gimple_set_location (g, loc);
1074 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1075 *gsip = gsi_after_labels (then_bb);
1076 gsi_remove (&gsi, false);
1077 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1078 gsi = *gsip;
1081 tree htype = TREE_TYPE (str_hash);
1082 tree cst = wide_int_to_tree (htype,
1083 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1084 | 0xeb382d69, 64));
1085 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1086 vptr, str_hash);
1087 gimple_set_location (g, loc);
1088 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1089 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1090 gimple_assign_lhs (g), cst);
1091 gimple_set_location (g, loc);
1092 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1093 tree t1 = gimple_assign_lhs (g);
1094 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1095 t1, build_int_cst (integer_type_node, 47));
1096 gimple_set_location (g, loc);
1097 tree t2 = gimple_assign_lhs (g);
1098 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1099 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1100 vptr, t1);
1101 gimple_set_location (g, loc);
1102 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1103 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1104 t2, gimple_assign_lhs (g));
1105 gimple_set_location (g, loc);
1106 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1107 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1108 gimple_assign_lhs (g), cst);
1109 gimple_set_location (g, loc);
1110 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1111 tree t3 = gimple_assign_lhs (g);
1112 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1113 t3, build_int_cst (integer_type_node, 47));
1114 gimple_set_location (g, loc);
1115 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1116 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1117 t3, gimple_assign_lhs (g));
1118 gimple_set_location (g, loc);
1119 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1120 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1121 gimple_assign_lhs (g), cst);
1122 gimple_set_location (g, loc);
1123 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1124 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1126 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1127 NOP_EXPR, gimple_assign_lhs (g));
1128 gimple_set_location (g, loc);
1129 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1131 tree hash = gimple_assign_lhs (g);
1133 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1135 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1136 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1137 get_identifier ("__ubsan_vptr_type_cache"),
1138 atype);
1139 DECL_ARTIFICIAL (array) = 1;
1140 DECL_IGNORED_P (array) = 1;
1141 TREE_PUBLIC (array) = 1;
1142 TREE_STATIC (array) = 1;
1143 DECL_EXTERNAL (array) = 1;
1144 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1145 DECL_VISIBILITY_SPECIFIED (array) = 1;
1146 varpool_node::finalize_decl (array);
1147 ubsan_vptr_type_cache_decl = array;
1150 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1151 BIT_AND_EXPR, hash,
1152 build_int_cst (pointer_sized_int_node, 127));
1153 gimple_set_location (g, loc);
1154 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1156 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1157 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1158 NULL_TREE, NULL_TREE);
1159 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1160 ARRAY_REF, c);
1161 gimple_set_location (g, loc);
1162 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1164 basic_block then_bb, fallthru2_bb;
1165 gimple_stmt_iterator cond_insert_point
1166 = create_cond_insert_point (gsip, false, false, true,
1167 &then_bb, &fallthru2_bb);
1168 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1169 NULL_TREE, NULL_TREE);
1170 gimple_set_location (g, loc);
1171 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1172 *gsip = gsi_after_labels (then_bb);
1173 if (fallthru_bb == NULL)
1174 fallthru_bb = fallthru2_bb;
1176 tree data
1177 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1178 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1179 build_int_cst (unsigned_char_type_node, ckind),
1180 NULL_TREE);
1181 data = build_fold_addr_expr_loc (loc, data);
1182 enum built_in_function bcode
1183 = (flag_sanitize_recover & SANITIZE_VPTR)
1184 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1185 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1187 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1188 gimple_set_location (g, loc);
1189 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1191 /* Point GSI to next logical statement. */
1192 *gsip = gsi_start_bb (fallthru_bb);
1194 /* Get rid of the UBSAN_VPTR call from the IR. */
1195 unlink_stmt_vdef (stmt);
1196 gsi_remove (&gsi, true);
1197 return true;
1200 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1201 whether the pointer is on the left hand side of the assignment. */
1203 static void
1204 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1205 bool is_lhs)
1207 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1208 unsigned int align = 0;
1209 if (flag_sanitize & SANITIZE_ALIGNMENT)
1211 align = min_align_of_type (TREE_TYPE (base));
1212 if (align <= 1)
1213 align = 0;
1215 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1216 return;
1217 tree t = TREE_OPERAND (base, 0);
1218 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1219 return;
1220 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && mem != base)
1221 ikind = UBSAN_MEMBER_ACCESS;
1222 tree kind = build_int_cst (TREE_TYPE (t), ikind);
1223 tree alignt = build_int_cst (pointer_sized_int_node, align);
1224 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1225 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1226 gsi_insert_before (iter, g, GSI_SAME_STMT);
1229 /* Perform the pointer instrumentation. */
1231 static void
1232 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1234 gimple stmt = gsi_stmt (gsi);
1235 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1236 tree base = get_base_address (t);
1237 const enum tree_code code = TREE_CODE (base);
1238 if (code == MEM_REF
1239 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1240 instrument_mem_ref (t, base, &gsi, is_lhs);
1243 /* Build an ubsan builtin call for the signed-integer-overflow
1244 sanitization. CODE says what kind of builtin are we building,
1245 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1246 are operands of the binary operation. */
1248 tree
1249 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1250 tree op0, tree op1)
1252 if (flag_sanitize_undefined_trap_on_error)
1253 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1255 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1256 ubsan_type_descriptor (lhstype), NULL_TREE,
1257 NULL_TREE);
1258 enum built_in_function fn_code;
1260 switch (code)
1262 case PLUS_EXPR:
1263 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1264 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1265 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1266 break;
1267 case MINUS_EXPR:
1268 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1269 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1270 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1271 break;
1272 case MULT_EXPR:
1273 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1274 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1275 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1276 break;
1277 case NEGATE_EXPR:
1278 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1279 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1280 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1281 break;
1282 default:
1283 gcc_unreachable ();
1285 tree fn = builtin_decl_explicit (fn_code);
1286 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1287 build_fold_addr_expr_loc (loc, data),
1288 ubsan_encode_value (op0, true),
1289 op1 ? ubsan_encode_value (op1, true)
1290 : NULL_TREE);
1293 /* Perform the signed integer instrumentation. GSI is the iterator
1294 pointing at statement we are trying to instrument. */
1296 static void
1297 instrument_si_overflow (gimple_stmt_iterator gsi)
1299 gimple stmt = gsi_stmt (gsi);
1300 tree_code code = gimple_assign_rhs_code (stmt);
1301 tree lhs = gimple_assign_lhs (stmt);
1302 tree lhstype = TREE_TYPE (lhs);
1303 tree a, b;
1304 gimple g;
1306 /* If this is not a signed operation, don't instrument anything here.
1307 Also punt on bit-fields. */
1308 if (!INTEGRAL_TYPE_P (lhstype)
1309 || TYPE_OVERFLOW_WRAPS (lhstype)
1310 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
1311 return;
1313 switch (code)
1315 case MINUS_EXPR:
1316 case PLUS_EXPR:
1317 case MULT_EXPR:
1318 /* Transform
1319 i = u {+,-,*} 5;
1320 into
1321 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1322 a = gimple_assign_rhs1 (stmt);
1323 b = gimple_assign_rhs2 (stmt);
1324 g = gimple_build_call_internal (code == PLUS_EXPR
1325 ? IFN_UBSAN_CHECK_ADD
1326 : code == MINUS_EXPR
1327 ? IFN_UBSAN_CHECK_SUB
1328 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1329 gimple_call_set_lhs (g, lhs);
1330 gsi_replace (&gsi, g, false);
1331 break;
1332 case NEGATE_EXPR:
1333 /* Represent i = -u;
1335 i = UBSAN_CHECK_SUB (0, u); */
1336 a = build_int_cst (lhstype, 0);
1337 b = gimple_assign_rhs1 (stmt);
1338 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1339 gimple_call_set_lhs (g, lhs);
1340 gsi_replace (&gsi, g, false);
1341 break;
1342 case ABS_EXPR:
1343 /* Transform i = ABS_EXPR<u>;
1344 into
1345 _N = UBSAN_CHECK_SUB (0, u);
1346 i = ABS_EXPR<_N>; */
1347 a = build_int_cst (lhstype, 0);
1348 b = gimple_assign_rhs1 (stmt);
1349 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1350 a = make_ssa_name (lhstype);
1351 gimple_call_set_lhs (g, a);
1352 gimple_set_location (g, gimple_location (stmt));
1353 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1354 gimple_assign_set_rhs1 (stmt, a);
1355 update_stmt (stmt);
1356 break;
1357 default:
1358 break;
1362 /* Instrument loads from (non-bitfield) bool and C++ enum values
1363 to check if the memory value is outside of the range of the valid
1364 type values. */
1366 static void
1367 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1369 gimple stmt = gsi_stmt (*gsi);
1370 tree rhs = gimple_assign_rhs1 (stmt);
1371 tree type = TREE_TYPE (rhs);
1372 tree minv = NULL_TREE, maxv = NULL_TREE;
1374 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1376 minv = boolean_false_node;
1377 maxv = boolean_true_node;
1379 else if (TREE_CODE (type) == ENUMERAL_TYPE
1380 && (flag_sanitize & SANITIZE_ENUM)
1381 && TREE_TYPE (type) != NULL_TREE
1382 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1383 && (TYPE_PRECISION (TREE_TYPE (type))
1384 < GET_MODE_PRECISION (TYPE_MODE (type))))
1386 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1387 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1389 else
1390 return;
1392 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1393 HOST_WIDE_INT bitsize, bitpos;
1394 tree offset;
1395 machine_mode mode;
1396 int volatilep = 0, unsignedp = 0;
1397 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1398 &unsignedp, &volatilep, false);
1399 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1401 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1402 || (bitpos % modebitsize) != 0
1403 || bitsize != modebitsize
1404 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1405 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1406 return;
1408 bool can_throw = stmt_could_throw_p (stmt);
1409 location_t loc = gimple_location (stmt);
1410 tree lhs = gimple_assign_lhs (stmt);
1411 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1412 tree atype = reference_alias_ptr_type (rhs);
1413 gimple g = gimple_build_assign (make_ssa_name (ptype),
1414 build_fold_addr_expr (rhs));
1415 gimple_set_location (g, loc);
1416 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1417 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1418 build_int_cst (atype, 0));
1419 tree urhs = make_ssa_name (utype);
1420 if (can_throw)
1422 gimple_assign_set_lhs (stmt, urhs);
1423 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1424 gimple_set_location (g, loc);
1425 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1426 gsi_insert_on_edge_immediate (e, g);
1427 gimple_assign_set_rhs_from_tree (gsi, mem);
1428 update_stmt (stmt);
1429 *gsi = gsi_for_stmt (g);
1430 g = stmt;
1432 else
1434 g = gimple_build_assign (urhs, mem);
1435 gimple_set_location (g, loc);
1436 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1438 minv = fold_convert (utype, minv);
1439 maxv = fold_convert (utype, maxv);
1440 if (!integer_zerop (minv))
1442 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1443 gimple_set_location (g, loc);
1444 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1447 gimple_stmt_iterator gsi2 = *gsi;
1448 basic_block then_bb, fallthru_bb;
1449 *gsi = create_cond_insert_point (gsi, true, false, true,
1450 &then_bb, &fallthru_bb);
1451 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1452 int_const_binop (MINUS_EXPR, maxv, minv),
1453 NULL_TREE, NULL_TREE);
1454 gimple_set_location (g, loc);
1455 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1457 if (!can_throw)
1459 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1460 update_stmt (stmt);
1463 gsi2 = gsi_after_labels (then_bb);
1464 if (flag_sanitize_undefined_trap_on_error)
1465 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1466 else
1468 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1469 ubsan_type_descriptor (type), NULL_TREE,
1470 NULL_TREE);
1471 data = build_fold_addr_expr_loc (loc, data);
1472 enum built_in_function bcode
1473 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1474 ? SANITIZE_BOOL : SANITIZE_ENUM))
1475 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1476 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1477 tree fn = builtin_decl_explicit (bcode);
1479 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1480 true, NULL_TREE, true,
1481 GSI_SAME_STMT);
1482 g = gimple_build_call (fn, 2, data, val);
1484 gimple_set_location (g, loc);
1485 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1486 *gsi = gsi_for_stmt (stmt);
1489 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1490 destination, EXPR is floating-point expression. ARG is what to pass
1491 the libubsan call as value, often EXPR itself. */
1493 tree
1494 ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
1496 tree expr_type = TREE_TYPE (expr);
1497 tree t, tt, fn, min, max;
1498 machine_mode mode = TYPE_MODE (expr_type);
1499 int prec = TYPE_PRECISION (type);
1500 bool uns_p = TYPE_UNSIGNED (type);
1502 /* Float to integer conversion first truncates toward zero, so
1503 even signed char c = 127.875f; is not problematic.
1504 Therefore, we should complain only if EXPR is unordered or smaller
1505 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1506 TYPE_MAX_VALUE + 1.0. */
1507 if (REAL_MODE_FORMAT (mode)->b == 2)
1509 /* For maximum, TYPE_MAX_VALUE might not be representable
1510 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1511 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1512 either representable or infinity. */
1513 REAL_VALUE_TYPE maxval = dconst1;
1514 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1515 real_convert (&maxval, mode, &maxval);
1516 max = build_real (expr_type, maxval);
1518 /* For unsigned, assume -1.0 is always representable. */
1519 if (uns_p)
1520 min = build_minus_one_cst (expr_type);
1521 else
1523 /* TYPE_MIN_VALUE is generally representable (or -inf),
1524 but TYPE_MIN_VALUE - 1.0 might not be. */
1525 REAL_VALUE_TYPE minval = dconstm1, minval2;
1526 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1527 real_convert (&minval, mode, &minval);
1528 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1529 real_convert (&minval2, mode, &minval2);
1530 if (real_compare (EQ_EXPR, &minval, &minval2)
1531 && !real_isinf (&minval))
1533 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1534 rounds to TYPE_MIN_VALUE, we need to subtract
1535 more. As REAL_MODE_FORMAT (mode)->p is the number
1536 of base digits, we want to subtract a number that
1537 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1538 times smaller than minval. */
1539 minval2 = dconst1;
1540 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1541 SET_REAL_EXP (&minval2,
1542 REAL_EXP (&minval2) + prec - 1
1543 - REAL_MODE_FORMAT (mode)->p + 1);
1544 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1545 real_convert (&minval2, mode, &minval2);
1547 min = build_real (expr_type, minval2);
1550 else if (REAL_MODE_FORMAT (mode)->b == 10)
1552 /* For _Decimal128 up to 34 decimal digits, - sign,
1553 dot, e, exponent. */
1554 char buf[64];
1555 mpfr_t m;
1556 int p = REAL_MODE_FORMAT (mode)->p;
1557 REAL_VALUE_TYPE maxval, minval;
1559 /* Use mpfr_snprintf rounding to compute the smallest
1560 representable decimal number greater or equal than
1561 1 << (prec - !uns_p). */
1562 mpfr_init2 (m, prec + 2);
1563 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1564 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1565 decimal_real_from_string (&maxval, buf);
1566 max = build_real (expr_type, maxval);
1568 /* For unsigned, assume -1.0 is always representable. */
1569 if (uns_p)
1570 min = build_minus_one_cst (expr_type);
1571 else
1573 /* Use mpfr_snprintf rounding to compute the largest
1574 representable decimal number less or equal than
1575 (-1 << (prec - 1)) - 1. */
1576 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1577 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1578 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1579 decimal_real_from_string (&minval, buf);
1580 min = build_real (expr_type, minval);
1582 mpfr_clear (m);
1584 else
1585 return NULL_TREE;
1587 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1588 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1589 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1590 if (integer_zerop (t))
1591 return NULL_TREE;
1593 if (flag_sanitize_undefined_trap_on_error)
1594 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1595 else
1597 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1598 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1599 NULL, ubsan_type_descriptor (expr_type),
1600 ubsan_type_descriptor (type), NULL_TREE,
1601 NULL_TREE);
1602 enum built_in_function bcode
1603 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1604 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1605 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1606 fn = builtin_decl_explicit (bcode);
1607 fn = build_call_expr_loc (loc, fn, 2,
1608 build_fold_addr_expr_loc (loc, data),
1609 ubsan_encode_value (arg, false));
1612 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1615 /* Instrument values passed to function arguments with nonnull attribute. */
1617 static void
1618 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1620 gimple stmt = gsi_stmt (*gsi);
1621 location_t loc[2];
1622 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1623 while for nonnull sanitization it is clear. */
1624 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1625 flag_delete_null_pointer_checks = 1;
1626 loc[0] = gimple_location (stmt);
1627 loc[1] = UNKNOWN_LOCATION;
1628 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1630 tree arg = gimple_call_arg (stmt, i);
1631 if (POINTER_TYPE_P (TREE_TYPE (arg))
1632 && infer_nonnull_range (stmt, arg, false, true))
1634 gimple g;
1635 if (!is_gimple_val (arg))
1637 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1638 gimple_set_location (g, loc[0]);
1639 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1640 arg = gimple_assign_lhs (g);
1643 basic_block then_bb, fallthru_bb;
1644 *gsi = create_cond_insert_point (gsi, true, false, true,
1645 &then_bb, &fallthru_bb);
1646 g = gimple_build_cond (EQ_EXPR, arg,
1647 build_zero_cst (TREE_TYPE (arg)),
1648 NULL_TREE, NULL_TREE);
1649 gimple_set_location (g, loc[0]);
1650 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1652 *gsi = gsi_after_labels (then_bb);
1653 if (flag_sanitize_undefined_trap_on_error)
1654 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1655 else
1657 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1658 2, loc, NULL_TREE,
1659 build_int_cst (integer_type_node,
1660 i + 1),
1661 NULL_TREE);
1662 data = build_fold_addr_expr_loc (loc[0], data);
1663 enum built_in_function bcode
1664 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1665 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1666 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1667 tree fn = builtin_decl_explicit (bcode);
1669 g = gimple_build_call (fn, 1, data);
1671 gimple_set_location (g, loc[0]);
1672 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1674 *gsi = gsi_for_stmt (stmt);
1676 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1679 /* Instrument returns in functions with returns_nonnull attribute. */
1681 static void
1682 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1684 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1685 location_t loc[2];
1686 tree arg = gimple_return_retval (stmt);
1687 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1688 while for nonnull return sanitization it is clear. */
1689 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1690 flag_delete_null_pointer_checks = 1;
1691 loc[0] = gimple_location (stmt);
1692 loc[1] = UNKNOWN_LOCATION;
1693 if (arg
1694 && POINTER_TYPE_P (TREE_TYPE (arg))
1695 && is_gimple_val (arg)
1696 && infer_nonnull_range (stmt, arg, false, true))
1698 basic_block then_bb, fallthru_bb;
1699 *gsi = create_cond_insert_point (gsi, true, false, true,
1700 &then_bb, &fallthru_bb);
1701 gimple g = gimple_build_cond (EQ_EXPR, arg,
1702 build_zero_cst (TREE_TYPE (arg)),
1703 NULL_TREE, NULL_TREE);
1704 gimple_set_location (g, loc[0]);
1705 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1707 *gsi = gsi_after_labels (then_bb);
1708 if (flag_sanitize_undefined_trap_on_error)
1709 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1710 else
1712 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1713 2, loc, NULL_TREE, NULL_TREE);
1714 data = build_fold_addr_expr_loc (loc[0], data);
1715 enum built_in_function bcode
1716 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1717 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1718 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1719 tree fn = builtin_decl_explicit (bcode);
1721 g = gimple_build_call (fn, 1, data);
1723 gimple_set_location (g, loc[0]);
1724 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1725 *gsi = gsi_for_stmt (stmt);
1727 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1730 /* Instrument memory references. Here we check whether the pointer
1731 points to an out-of-bounds location. */
1733 static void
1734 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1736 gimple stmt = gsi_stmt (*gsi);
1737 location_t loc = gimple_location (stmt);
1738 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1739 tree type;
1740 tree index = NULL_TREE;
1741 HOST_WIDE_INT size_in_bytes;
1743 type = TREE_TYPE (t);
1744 if (VOID_TYPE_P (type))
1745 return;
1747 switch (TREE_CODE (t))
1749 case COMPONENT_REF:
1750 if (TREE_CODE (t) == COMPONENT_REF
1751 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1753 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1754 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1755 repr, NULL_TREE);
1757 break;
1758 case ARRAY_REF:
1759 index = TREE_OPERAND (t, 1);
1760 break;
1761 case INDIRECT_REF:
1762 case MEM_REF:
1763 case VAR_DECL:
1764 case PARM_DECL:
1765 case RESULT_DECL:
1766 break;
1767 default:
1768 return;
1771 size_in_bytes = int_size_in_bytes (type);
1772 if (size_in_bytes <= 0)
1773 return;
1775 HOST_WIDE_INT bitsize, bitpos;
1776 tree offset;
1777 machine_mode mode;
1778 int volatilep = 0, unsignedp = 0;
1779 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1780 &unsignedp, &volatilep, false);
1782 if (bitpos % BITS_PER_UNIT != 0
1783 || bitsize != size_in_bytes * BITS_PER_UNIT)
1784 return;
1786 bool decl_p = DECL_P (inner);
1787 tree base;
1788 if (decl_p)
1789 base = inner;
1790 else if (TREE_CODE (inner) == MEM_REF)
1791 base = TREE_OPERAND (inner, 0);
1792 else
1793 return;
1794 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1796 while (TREE_CODE (base) == SSA_NAME)
1798 gimple def_stmt = SSA_NAME_DEF_STMT (base);
1799 if (gimple_assign_ssa_name_copy_p (def_stmt)
1800 || (gimple_assign_cast_p (def_stmt)
1801 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1802 || (is_gimple_assign (def_stmt)
1803 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1805 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1806 if (TREE_CODE (rhs1) == SSA_NAME
1807 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1808 break;
1809 else
1810 base = rhs1;
1812 else
1813 break;
1816 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1817 return;
1819 tree sizet;
1820 tree base_addr = base;
1821 if (decl_p)
1822 base_addr = build1 (ADDR_EXPR,
1823 build_pointer_type (TREE_TYPE (base)), base);
1824 unsigned HOST_WIDE_INT size = compute_builtin_object_size (base_addr, 0);
1825 if (size != (unsigned HOST_WIDE_INT) -1)
1826 sizet = build_int_cst (sizetype, size);
1827 else if (optimize)
1829 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1830 loc = input_location;
1831 /* Generate __builtin_object_size call. */
1832 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1833 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1834 integer_zero_node);
1835 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1836 GSI_SAME_STMT);
1838 else
1839 return;
1841 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1842 call. */
1843 /* ptr + sizeof (*ptr) - base */
1844 t = fold_build2 (MINUS_EXPR, sizetype,
1845 fold_convert (pointer_sized_int_node, ptr),
1846 fold_convert (pointer_sized_int_node, base_addr));
1847 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1849 /* Perhaps we can omit the check. */
1850 if (TREE_CODE (t) == INTEGER_CST
1851 && TREE_CODE (sizet) == INTEGER_CST
1852 && tree_int_cst_le (t, sizet))
1853 return;
1855 if (index != NULL_TREE
1856 && TREE_CODE (index) == SSA_NAME
1857 && TREE_CODE (sizet) == INTEGER_CST)
1859 gimple def = SSA_NAME_DEF_STMT (index);
1860 if (is_gimple_assign (def)
1861 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1862 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1864 tree cst = gimple_assign_rhs2 (def);
1865 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1866 TYPE_SIZE_UNIT (type));
1867 if (tree_int_cst_sgn (cst) >= 0
1868 && tree_int_cst_lt (cst, sz))
1869 return;
1873 /* Nope. Emit the check. */
1874 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1875 GSI_SAME_STMT);
1876 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1877 GSI_SAME_STMT);
1878 tree ckind = build_int_cst (unsigned_char_type_node,
1879 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1880 gimple g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1881 ptr, t, sizet, ckind);
1882 gimple_set_location (g, loc);
1883 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1886 /* True if we want to play UBSan games in the current function. */
1888 bool
1889 do_ubsan_in_current_function ()
1891 return (current_function_decl != NULL_TREE
1892 && !lookup_attribute ("no_sanitize_undefined",
1893 DECL_ATTRIBUTES (current_function_decl)));
1896 namespace {
1898 const pass_data pass_data_ubsan =
1900 GIMPLE_PASS, /* type */
1901 "ubsan", /* name */
1902 OPTGROUP_NONE, /* optinfo_flags */
1903 TV_TREE_UBSAN, /* tv_id */
1904 ( PROP_cfg | PROP_ssa ), /* properties_required */
1905 0, /* properties_provided */
1906 0, /* properties_destroyed */
1907 0, /* todo_flags_start */
1908 TODO_update_ssa, /* todo_flags_finish */
1911 class pass_ubsan : public gimple_opt_pass
1913 public:
1914 pass_ubsan (gcc::context *ctxt)
1915 : gimple_opt_pass (pass_data_ubsan, ctxt)
1918 /* opt_pass methods: */
1919 virtual bool gate (function *)
1921 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1922 | SANITIZE_BOOL | SANITIZE_ENUM
1923 | SANITIZE_ALIGNMENT
1924 | SANITIZE_NONNULL_ATTRIBUTE
1925 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1926 | SANITIZE_OBJECT_SIZE)
1927 && do_ubsan_in_current_function ();
1930 virtual unsigned int execute (function *);
1932 }; // class pass_ubsan
1934 unsigned int
1935 pass_ubsan::execute (function *fun)
1937 basic_block bb;
1938 gimple_stmt_iterator gsi;
1940 initialize_sanitizer_builtins ();
1942 FOR_EACH_BB_FN (bb, fun)
1944 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1946 gimple stmt = gsi_stmt (gsi);
1947 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1949 gsi_next (&gsi);
1950 continue;
1953 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1954 && is_gimple_assign (stmt))
1955 instrument_si_overflow (gsi);
1957 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1959 if (gimple_store_p (stmt))
1960 instrument_null (gsi, true);
1961 if (gimple_assign_load_p (stmt))
1962 instrument_null (gsi, false);
1965 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1966 && gimple_assign_load_p (stmt))
1968 instrument_bool_enum_load (&gsi);
1969 bb = gimple_bb (stmt);
1972 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1973 && is_gimple_call (stmt)
1974 && !gimple_call_internal_p (stmt))
1976 instrument_nonnull_arg (&gsi);
1977 bb = gimple_bb (stmt);
1980 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1981 && gimple_code (stmt) == GIMPLE_RETURN)
1983 instrument_nonnull_return (&gsi);
1984 bb = gimple_bb (stmt);
1987 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
1989 if (gimple_store_p (stmt))
1990 instrument_object_size (&gsi, true);
1991 if (gimple_assign_load_p (stmt))
1992 instrument_object_size (&gsi, false);
1995 gsi_next (&gsi);
1998 return 0;
2001 } // anon namespace
2003 gimple_opt_pass *
2004 make_pass_ubsan (gcc::context *ctxt)
2006 return new pass_ubsan (ctxt);
2009 #include "gt-ubsan.h"