PR middle-end/81005
[official-gcc.git] / gcc / ubsan.c
blob133409a7813d8e3f1ec2d7323ce8e878f76c6f29
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2017 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "rtl.h"
26 #include "c-family/c-common.h"
27 #include "gimple.h"
28 #include "cfghooks.h"
29 #include "tree-pass.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "ssa.h"
33 #include "cgraph.h"
34 #include "tree-pretty-print.h"
35 #include "stor-layout.h"
36 #include "cfganal.h"
37 #include "gimple-iterator.h"
38 #include "output.h"
39 #include "cfgloop.h"
40 #include "ubsan.h"
41 #include "expr.h"
42 #include "asan.h"
43 #include "gimplify-me.h"
44 #include "dfp.h"
45 #include "builtins.h"
46 #include "tree-object-size.h"
47 #include "tree-cfg.h"
49 /* Map from a tree to a VAR_DECL tree. */
51 struct GTY((for_user)) tree_type_map {
52 struct tree_map_base type;
53 tree decl;
56 struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
58 static inline hashval_t
59 hash (tree_type_map *t)
61 return TYPE_UID (t->type.from);
64 static inline bool
65 equal (tree_type_map *a, tree_type_map *b)
67 return a->type.from == b->type.from;
70 static int
71 keep_cache_entry (tree_type_map *&m)
73 return ggc_marked_p (m->type.from);
77 static GTY ((cache))
78 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
80 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
82 static tree
83 decl_for_type_lookup (tree type)
85 /* If the hash table is not initialized yet, create it now. */
86 if (decl_tree_for_type == NULL)
88 decl_tree_for_type
89 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
90 /* That also means we don't have to bother with the lookup. */
91 return NULL_TREE;
94 struct tree_type_map *h, in;
95 in.type.from = type;
97 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
98 return h ? h->decl : NULL_TREE;
101 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
103 static void
104 decl_for_type_insert (tree type, tree decl)
106 struct tree_type_map *h;
108 h = ggc_alloc<tree_type_map> ();
109 h->type.from = type;
110 h->decl = decl;
111 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
114 /* Helper routine, which encodes a value in the pointer_sized_int_node.
115 Arguments with precision <= POINTER_SIZE are passed directly,
116 the rest is passed by reference. T is a value we are to encode.
117 IN_EXPAND_P is true if this function is called during expansion. */
119 tree
120 ubsan_encode_value (tree t, bool in_expand_p)
122 tree type = TREE_TYPE (t);
123 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
124 if (bitsize <= POINTER_SIZE)
125 switch (TREE_CODE (type))
127 case BOOLEAN_TYPE:
128 case ENUMERAL_TYPE:
129 case INTEGER_TYPE:
130 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
131 case REAL_TYPE:
133 tree itype = build_nonstandard_integer_type (bitsize, true);
134 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
135 return fold_convert (pointer_sized_int_node, t);
137 default:
138 gcc_unreachable ();
140 else
142 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
144 /* The reason for this is that we don't want to pessimize
145 code by making vars unnecessarily addressable. */
146 tree var = create_tmp_var (type);
147 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
148 mark_addressable (var);
149 if (in_expand_p)
151 rtx mem
152 = assign_stack_temp_for_type (TYPE_MODE (type),
153 GET_MODE_SIZE (TYPE_MODE (type)),
154 type);
155 SET_DECL_RTL (var, mem);
156 expand_assignment (var, t, false);
157 return build_fold_addr_expr (var);
159 t = build_fold_addr_expr (var);
160 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
162 else
163 return build_fold_addr_expr (t);
167 /* Cached ubsan_get_type_descriptor_type () return value. */
168 static GTY(()) tree ubsan_type_descriptor_type;
170 /* Build
171 struct __ubsan_type_descriptor
173 unsigned short __typekind;
174 unsigned short __typeinfo;
175 char __typename[];
177 type. */
179 static tree
180 ubsan_get_type_descriptor_type (void)
182 static const char *field_names[3]
183 = { "__typekind", "__typeinfo", "__typename" };
184 tree fields[3], ret;
186 if (ubsan_type_descriptor_type)
187 return ubsan_type_descriptor_type;
189 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
190 tree flex_arr_type = build_array_type (char_type_node, itype);
192 ret = make_node (RECORD_TYPE);
193 for (int i = 0; i < 3; i++)
195 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
196 get_identifier (field_names[i]),
197 (i == 2) ? flex_arr_type
198 : short_unsigned_type_node);
199 DECL_CONTEXT (fields[i]) = ret;
200 if (i)
201 DECL_CHAIN (fields[i - 1]) = fields[i];
203 tree type_decl = build_decl (input_location, TYPE_DECL,
204 get_identifier ("__ubsan_type_descriptor"),
205 ret);
206 DECL_IGNORED_P (type_decl) = 1;
207 DECL_ARTIFICIAL (type_decl) = 1;
208 TYPE_FIELDS (ret) = fields[0];
209 TYPE_NAME (ret) = type_decl;
210 TYPE_STUB_DECL (ret) = type_decl;
211 layout_type (ret);
212 ubsan_type_descriptor_type = ret;
213 return ret;
216 /* Cached ubsan_get_source_location_type () return value. */
217 static GTY(()) tree ubsan_source_location_type;
219 /* Build
220 struct __ubsan_source_location
222 const char *__filename;
223 unsigned int __line;
224 unsigned int __column;
226 type. */
228 tree
229 ubsan_get_source_location_type (void)
231 static const char *field_names[3]
232 = { "__filename", "__line", "__column" };
233 tree fields[3], ret;
234 if (ubsan_source_location_type)
235 return ubsan_source_location_type;
237 tree const_char_type = build_qualified_type (char_type_node,
238 TYPE_QUAL_CONST);
240 ret = make_node (RECORD_TYPE);
241 for (int i = 0; i < 3; i++)
243 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
244 get_identifier (field_names[i]),
245 (i == 0) ? build_pointer_type (const_char_type)
246 : unsigned_type_node);
247 DECL_CONTEXT (fields[i]) = ret;
248 if (i)
249 DECL_CHAIN (fields[i - 1]) = fields[i];
251 tree type_decl = build_decl (input_location, TYPE_DECL,
252 get_identifier ("__ubsan_source_location"),
253 ret);
254 DECL_IGNORED_P (type_decl) = 1;
255 DECL_ARTIFICIAL (type_decl) = 1;
256 TYPE_FIELDS (ret) = fields[0];
257 TYPE_NAME (ret) = type_decl;
258 TYPE_STUB_DECL (ret) = type_decl;
259 layout_type (ret);
260 ubsan_source_location_type = ret;
261 return ret;
264 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
265 type with its fields filled from a location_t LOC. */
267 static tree
268 ubsan_source_location (location_t loc)
270 expanded_location xloc;
271 tree type = ubsan_get_source_location_type ();
273 xloc = expand_location (loc);
274 tree str;
275 if (xloc.file == NULL)
277 str = build_int_cst (ptr_type_node, 0);
278 xloc.line = 0;
279 xloc.column = 0;
281 else
283 /* Fill in the values from LOC. */
284 size_t len = strlen (xloc.file) + 1;
285 str = build_string (len, xloc.file);
286 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
287 TREE_READONLY (str) = 1;
288 TREE_STATIC (str) = 1;
289 str = build_fold_addr_expr (str);
291 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
292 build_int_cst (unsigned_type_node,
293 xloc.line), NULL_TREE,
294 build_int_cst (unsigned_type_node,
295 xloc.column));
296 TREE_CONSTANT (ctor) = 1;
297 TREE_STATIC (ctor) = 1;
299 return ctor;
302 /* This routine returns a magic number for TYPE. */
304 static unsigned short
305 get_ubsan_type_info_for_type (tree type)
307 if (TREE_CODE (type) == REAL_TYPE)
308 return tree_to_uhwi (TYPE_SIZE (type));
309 else if (INTEGRAL_TYPE_P (type))
311 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
312 gcc_assert (prec != -1);
313 return (prec << 1) | !TYPE_UNSIGNED (type);
315 else
316 return 0;
319 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
320 ubsan_ids[1] for Lubsan_data labels. */
321 static GTY(()) unsigned int ubsan_ids[2];
323 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
324 descriptor. It first looks into the hash table; if not found,
325 create the VAR_DECL, put it into the hash table and return the
326 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
327 an enum controlling how we want to print the type. */
329 tree
330 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
332 /* See through any typedefs. */
333 type = TYPE_MAIN_VARIANT (type);
335 tree decl = decl_for_type_lookup (type);
336 /* It is possible that some of the earlier created DECLs were found
337 unused, in that case they weren't emitted and varpool_node::get
338 returns NULL node on them. But now we really need them. Thus,
339 renew them here. */
340 if (decl != NULL_TREE && varpool_node::get (decl))
341 return build_fold_addr_expr (decl);
343 tree dtype = ubsan_get_type_descriptor_type ();
344 tree type2 = type;
345 const char *tname = NULL;
346 pretty_printer pretty_name;
347 unsigned char deref_depth = 0;
348 unsigned short tkind, tinfo;
350 /* Get the name of the type, or the name of the pointer type. */
351 if (pstyle == UBSAN_PRINT_POINTER)
353 gcc_assert (POINTER_TYPE_P (type));
354 type2 = TREE_TYPE (type);
356 /* Remove any '*' operators from TYPE. */
357 while (POINTER_TYPE_P (type2))
358 deref_depth++, type2 = TREE_TYPE (type2);
360 if (TREE_CODE (type2) == METHOD_TYPE)
361 type2 = TYPE_METHOD_BASETYPE (type2);
364 /* If an array, get its type. */
365 type2 = strip_array_types (type2);
367 if (pstyle == UBSAN_PRINT_ARRAY)
369 while (POINTER_TYPE_P (type2))
370 deref_depth++, type2 = TREE_TYPE (type2);
373 if (TYPE_NAME (type2) != NULL)
375 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
376 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
377 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
378 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
381 if (tname == NULL)
382 /* We weren't able to determine the type name. */
383 tname = "<unknown>";
385 if (pstyle == UBSAN_PRINT_POINTER)
387 pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
388 TYPE_VOLATILE (type2) ? "volatile " : "",
389 TYPE_READONLY (type2) ? "const " : "",
390 TYPE_RESTRICT (type2) ? "restrict " : "",
391 TYPE_ATOMIC (type2) ? "_Atomic " : "",
392 TREE_CODE (type2) == RECORD_TYPE
393 ? "struct "
394 : TREE_CODE (type2) == UNION_TYPE
395 ? "union " : "", tname,
396 deref_depth == 0 ? "" : " ");
397 while (deref_depth-- > 0)
398 pp_star (&pretty_name);
399 pp_quote (&pretty_name);
401 else if (pstyle == UBSAN_PRINT_ARRAY)
403 /* Pretty print the array dimensions. */
404 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
405 tree t = type;
406 pp_printf (&pretty_name, "'%s ", tname);
407 while (deref_depth-- > 0)
408 pp_star (&pretty_name);
409 while (TREE_CODE (t) == ARRAY_TYPE)
411 pp_left_bracket (&pretty_name);
412 tree dom = TYPE_DOMAIN (t);
413 if (dom != NULL_TREE
414 && TYPE_MAX_VALUE (dom) != NULL_TREE
415 && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
417 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
418 && tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1 != 0)
419 pp_printf (&pretty_name, HOST_WIDE_INT_PRINT_DEC,
420 tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
421 else
422 pp_wide_int (&pretty_name,
423 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
424 TYPE_SIGN (TREE_TYPE (dom)));
426 else
427 /* ??? We can't determine the variable name; print VLA unspec. */
428 pp_star (&pretty_name);
429 pp_right_bracket (&pretty_name);
430 t = TREE_TYPE (t);
432 pp_quote (&pretty_name);
434 /* Save the tree with stripped types. */
435 type = t;
437 else
438 pp_printf (&pretty_name, "'%s'", tname);
440 switch (TREE_CODE (type))
442 case BOOLEAN_TYPE:
443 case ENUMERAL_TYPE:
444 case INTEGER_TYPE:
445 tkind = 0x0000;
446 break;
447 case REAL_TYPE:
448 /* FIXME: libubsan right now only supports float, double and
449 long double type formats. */
450 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
451 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
452 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
453 tkind = 0x0001;
454 else
455 tkind = 0xffff;
456 break;
457 default:
458 tkind = 0xffff;
459 break;
461 tinfo = get_ubsan_type_info_for_type (type);
463 /* Create a new VAR_DECL of type descriptor. */
464 const char *tmp = pp_formatted_text (&pretty_name);
465 size_t len = strlen (tmp) + 1;
466 tree str = build_string (len, tmp);
467 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
468 TREE_READONLY (str) = 1;
469 TREE_STATIC (str) = 1;
471 char tmp_name[32];
472 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
473 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
474 dtype);
475 TREE_STATIC (decl) = 1;
476 TREE_PUBLIC (decl) = 0;
477 DECL_ARTIFICIAL (decl) = 1;
478 DECL_IGNORED_P (decl) = 1;
479 DECL_EXTERNAL (decl) = 0;
480 DECL_SIZE (decl)
481 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
482 DECL_SIZE_UNIT (decl)
483 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
484 TYPE_SIZE_UNIT (TREE_TYPE (str)));
486 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
487 build_int_cst (short_unsigned_type_node,
488 tkind), NULL_TREE,
489 build_int_cst (short_unsigned_type_node,
490 tinfo), NULL_TREE, str);
491 TREE_CONSTANT (ctor) = 1;
492 TREE_STATIC (ctor) = 1;
493 DECL_INITIAL (decl) = ctor;
494 varpool_node::finalize_decl (decl);
496 /* Save the VAR_DECL into the hash table. */
497 decl_for_type_insert (type, decl);
499 return build_fold_addr_expr (decl);
502 /* Create a structure for the ubsan library. NAME is a name of the new
503 structure. LOCCNT is number of locations, PLOC points to array of
504 locations. The arguments in ... are of __ubsan_type_descriptor type
505 and there are at most two of them, followed by NULL_TREE, followed
506 by optional extra arguments and another NULL_TREE. */
508 tree
509 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
511 va_list args;
512 tree ret, t;
513 tree fields[6];
514 vec<tree, va_gc> *saved_args = NULL;
515 size_t i = 0;
516 int j;
518 /* It is possible that PCH zapped table with definitions of sanitizer
519 builtins. Reinitialize them if needed. */
520 initialize_sanitizer_builtins ();
522 /* Firstly, create a pointer to type descriptor type. */
523 tree td_type = ubsan_get_type_descriptor_type ();
524 td_type = build_pointer_type (td_type);
526 /* Create the structure type. */
527 ret = make_node (RECORD_TYPE);
528 for (j = 0; j < loccnt; j++)
530 gcc_checking_assert (i < 2);
531 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
532 ubsan_get_source_location_type ());
533 DECL_CONTEXT (fields[i]) = ret;
534 if (i)
535 DECL_CHAIN (fields[i - 1]) = fields[i];
536 i++;
539 va_start (args, ploc);
540 for (t = va_arg (args, tree); t != NULL_TREE;
541 i++, t = va_arg (args, tree))
543 gcc_checking_assert (i < 4);
544 /* Save the tree arguments for later use. */
545 vec_safe_push (saved_args, t);
546 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
547 td_type);
548 DECL_CONTEXT (fields[i]) = ret;
549 if (i)
550 DECL_CHAIN (fields[i - 1]) = fields[i];
553 for (t = va_arg (args, tree); t != NULL_TREE;
554 i++, t = va_arg (args, tree))
556 gcc_checking_assert (i < 6);
557 /* Save the tree arguments for later use. */
558 vec_safe_push (saved_args, t);
559 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
560 TREE_TYPE (t));
561 DECL_CONTEXT (fields[i]) = ret;
562 if (i)
563 DECL_CHAIN (fields[i - 1]) = fields[i];
565 va_end (args);
567 tree type_decl = build_decl (input_location, TYPE_DECL,
568 get_identifier (name), ret);
569 DECL_IGNORED_P (type_decl) = 1;
570 DECL_ARTIFICIAL (type_decl) = 1;
571 TYPE_FIELDS (ret) = fields[0];
572 TYPE_NAME (ret) = type_decl;
573 TYPE_STUB_DECL (ret) = type_decl;
574 layout_type (ret);
576 /* Now, fill in the type. */
577 char tmp_name[32];
578 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
579 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
580 ret);
581 TREE_STATIC (var) = 1;
582 TREE_PUBLIC (var) = 0;
583 DECL_ARTIFICIAL (var) = 1;
584 DECL_IGNORED_P (var) = 1;
585 DECL_EXTERNAL (var) = 0;
587 vec<constructor_elt, va_gc> *v;
588 vec_alloc (v, i);
589 tree ctor = build_constructor (ret, v);
591 /* If desirable, set the __ubsan_source_location element. */
592 for (j = 0; j < loccnt; j++)
594 location_t loc = LOCATION_LOCUS (ploc[j]);
595 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
598 size_t nelts = vec_safe_length (saved_args);
599 for (i = 0; i < nelts; i++)
601 t = (*saved_args)[i];
602 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
605 TREE_CONSTANT (ctor) = 1;
606 TREE_STATIC (ctor) = 1;
607 DECL_INITIAL (var) = ctor;
608 varpool_node::finalize_decl (var);
610 return var;
613 /* Instrument the __builtin_unreachable call. We just call the libubsan
614 routine instead. */
616 bool
617 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
619 gimple *g;
620 location_t loc = gimple_location (gsi_stmt (*gsi));
622 if (flag_sanitize_undefined_trap_on_error)
623 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
624 else
626 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
627 NULL_TREE, NULL_TREE);
628 data = build_fold_addr_expr_loc (loc, data);
629 tree fn
630 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
631 g = gimple_build_call (fn, 1, data);
633 gimple_set_location (g, loc);
634 gsi_replace (gsi, g, false);
635 return false;
638 /* Return true if T is a call to a libubsan routine. */
640 bool
641 is_ubsan_builtin_p (tree t)
643 return TREE_CODE (t) == FUNCTION_DECL
644 && DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
645 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
646 "__builtin___ubsan_", 18) == 0;
649 /* Create a callgraph edge for statement STMT. */
651 static void
652 ubsan_create_edge (gimple *stmt)
654 gcall *call_stmt = dyn_cast <gcall *> (stmt);
655 basic_block bb = gimple_bb (stmt);
656 int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
657 cgraph_node *node = cgraph_node::get (current_function_decl);
658 tree decl = gimple_call_fndecl (call_stmt);
659 if (decl)
660 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
661 freq);
664 /* Expand the UBSAN_BOUNDS special builtin function. */
666 bool
667 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
669 gimple *stmt = gsi_stmt (*gsi);
670 location_t loc = gimple_location (stmt);
671 gcc_assert (gimple_call_num_args (stmt) == 3);
673 /* Pick up the arguments of the UBSAN_BOUNDS call. */
674 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
675 tree index = gimple_call_arg (stmt, 1);
676 tree orig_index = index;
677 tree bound = gimple_call_arg (stmt, 2);
679 gimple_stmt_iterator gsi_orig = *gsi;
681 /* Create condition "if (index > bound)". */
682 basic_block then_bb, fallthru_bb;
683 gimple_stmt_iterator cond_insert_point
684 = create_cond_insert_point (gsi, false, false, true,
685 &then_bb, &fallthru_bb);
686 index = fold_convert (TREE_TYPE (bound), index);
687 index = force_gimple_operand_gsi (&cond_insert_point, index,
688 true, NULL_TREE,
689 false, GSI_NEW_STMT);
690 gimple *g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
691 gimple_set_location (g, loc);
692 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
694 /* Generate __ubsan_handle_out_of_bounds call. */
695 *gsi = gsi_after_labels (then_bb);
696 if (flag_sanitize_undefined_trap_on_error)
697 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
698 else
700 tree data
701 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
702 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
703 ubsan_type_descriptor (TREE_TYPE (orig_index)),
704 NULL_TREE, NULL_TREE);
705 data = build_fold_addr_expr_loc (loc, data);
706 enum built_in_function bcode
707 = (flag_sanitize_recover & SANITIZE_BOUNDS)
708 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
709 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
710 tree fn = builtin_decl_explicit (bcode);
711 tree val
712 = force_gimple_operand_gsi (gsi, ubsan_encode_value (orig_index), true,
713 NULL_TREE, true, GSI_SAME_STMT);
714 g = gimple_build_call (fn, 2, data, val);
716 gimple_set_location (g, loc);
717 gsi_insert_before (gsi, g, GSI_SAME_STMT);
719 /* Get rid of the UBSAN_BOUNDS call from the IR. */
720 unlink_stmt_vdef (stmt);
721 gsi_remove (&gsi_orig, true);
723 /* Point GSI to next logical statement. */
724 *gsi = gsi_start_bb (fallthru_bb);
725 return true;
728 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
729 argument which is a constant, because the middle-end treats pointer
730 conversions as useless and therefore the type of the first argument
731 could be changed to any other pointer type. */
733 bool
734 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
736 gimple_stmt_iterator gsi = *gsip;
737 gimple *stmt = gsi_stmt (gsi);
738 location_t loc = gimple_location (stmt);
739 gcc_assert (gimple_call_num_args (stmt) == 3);
740 tree ptr = gimple_call_arg (stmt, 0);
741 tree ckind = gimple_call_arg (stmt, 1);
742 tree align = gimple_call_arg (stmt, 2);
743 tree check_align = NULL_TREE;
744 bool check_null;
746 basic_block cur_bb = gsi_bb (gsi);
748 gimple *g;
749 if (!integer_zerop (align))
751 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
752 if (compare_tree_int (align, ptralign) == 1)
754 check_align = make_ssa_name (pointer_sized_int_node);
755 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
756 gimple_set_location (g, loc);
757 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
760 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
762 if (check_align == NULL_TREE && !check_null)
764 gsi_remove (gsip, true);
765 /* Unlink the UBSAN_NULLs vops before replacing it. */
766 unlink_stmt_vdef (stmt);
767 return true;
770 /* Split the original block holding the pointer dereference. */
771 edge e = split_block (cur_bb, stmt);
773 /* Get a hold on the 'condition block', the 'then block' and the
774 'else block'. */
775 basic_block cond_bb = e->src;
776 basic_block fallthru_bb = e->dest;
777 basic_block then_bb = create_empty_bb (cond_bb);
778 add_bb_to_loop (then_bb, cond_bb->loop_father);
779 loops_state_set (LOOPS_NEED_FIXUP);
781 /* Make an edge coming from the 'cond block' into the 'then block';
782 this edge is unlikely taken, so set up the probability accordingly. */
783 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
784 e->probability = PROB_VERY_UNLIKELY;
786 /* Connect 'then block' with the 'else block'. This is needed
787 as the ubsan routines we call in the 'then block' are not noreturn.
788 The 'then block' only has one outcoming edge. */
789 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
791 /* Set up the fallthrough basic block. */
792 e = find_edge (cond_bb, fallthru_bb);
793 e->flags = EDGE_FALSE_VALUE;
794 e->count = cond_bb->count;
795 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
797 /* Update dominance info for the newly created then_bb; note that
798 fallthru_bb's dominance info has already been updated by
799 split_block. */
800 if (dom_info_available_p (CDI_DOMINATORS))
801 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
803 /* Put the ubsan builtin call into the newly created BB. */
804 if (flag_sanitize_undefined_trap_on_error)
805 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
806 else
808 enum built_in_function bcode
809 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT : 0)
810 | (check_null ? SANITIZE_NULL : 0)))
811 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
812 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
813 tree fn = builtin_decl_implicit (bcode);
814 tree data
815 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
816 ubsan_type_descriptor (TREE_TYPE (ckind),
817 UBSAN_PRINT_POINTER),
818 NULL_TREE,
819 align,
820 fold_convert (unsigned_char_type_node, ckind),
821 NULL_TREE);
822 data = build_fold_addr_expr_loc (loc, data);
823 g = gimple_build_call (fn, 2, data,
824 check_align ? check_align
825 : build_zero_cst (pointer_sized_int_node));
827 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
828 gimple_set_location (g, loc);
829 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
831 /* Unlink the UBSAN_NULLs vops before replacing it. */
832 unlink_stmt_vdef (stmt);
834 if (check_null)
836 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
837 NULL_TREE, NULL_TREE);
838 gimple_set_location (g, loc);
840 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
841 gsi_replace (&gsi, g, false);
842 stmt = g;
845 if (check_align)
847 if (check_null)
849 /* Split the block with the condition again. */
850 e = split_block (cond_bb, stmt);
851 basic_block cond1_bb = e->src;
852 basic_block cond2_bb = e->dest;
854 /* Make an edge coming from the 'cond1 block' into the 'then block';
855 this edge is unlikely taken, so set up the probability
856 accordingly. */
857 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
858 e->probability = PROB_VERY_UNLIKELY;
860 /* Set up the fallthrough basic block. */
861 e = find_edge (cond1_bb, cond2_bb);
862 e->flags = EDGE_FALSE_VALUE;
863 e->count = cond1_bb->count;
864 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
866 /* Update dominance info. */
867 if (dom_info_available_p (CDI_DOMINATORS))
869 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
870 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
873 gsi2 = gsi_start_bb (cond2_bb);
876 tree mask = build_int_cst (pointer_sized_int_node,
877 tree_to_uhwi (align) - 1);
878 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
879 BIT_AND_EXPR, check_align, mask);
880 gimple_set_location (g, loc);
881 if (check_null)
882 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
883 else
884 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
886 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
887 build_int_cst (pointer_sized_int_node, 0),
888 NULL_TREE, NULL_TREE);
889 gimple_set_location (g, loc);
890 if (check_null)
891 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
892 else
893 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
894 gsi_replace (&gsi, g, false);
896 return false;
899 #define OBJSZ_MAX_OFFSET (1024 * 16)
901 /* Expand UBSAN_OBJECT_SIZE internal call. */
903 bool
904 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
906 gimple *stmt = gsi_stmt (*gsi);
907 location_t loc = gimple_location (stmt);
908 gcc_assert (gimple_call_num_args (stmt) == 4);
910 tree ptr = gimple_call_arg (stmt, 0);
911 tree offset = gimple_call_arg (stmt, 1);
912 tree size = gimple_call_arg (stmt, 2);
913 tree ckind = gimple_call_arg (stmt, 3);
914 gimple_stmt_iterator gsi_orig = *gsi;
915 gimple *g;
917 /* See if we can discard the check. */
918 if (TREE_CODE (size) != INTEGER_CST
919 || integer_all_onesp (size))
920 /* Yes, __builtin_object_size couldn't determine the
921 object size. */;
922 else if (TREE_CODE (offset) == INTEGER_CST
923 && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
924 && wi::to_widest (offset) <= -1)
925 /* The offset is in range [-16K, -1]. */;
926 else
928 /* if (offset > objsize) */
929 basic_block then_bb, fallthru_bb;
930 gimple_stmt_iterator cond_insert_point
931 = create_cond_insert_point (gsi, false, false, true,
932 &then_bb, &fallthru_bb);
933 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
934 gimple_set_location (g, loc);
935 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
937 /* If the offset is small enough, we don't need the second
938 run-time check. */
939 if (TREE_CODE (offset) == INTEGER_CST
940 && wi::to_widest (offset) >= 0
941 && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
942 *gsi = gsi_after_labels (then_bb);
943 else
945 /* Don't issue run-time error if (ptr > ptr + offset). That
946 may happen when computing a POINTER_PLUS_EXPR. */
947 basic_block then2_bb, fallthru2_bb;
949 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
950 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
951 true, &then2_bb,
952 &fallthru2_bb);
953 /* Convert the pointer to an integer type. */
954 tree p = make_ssa_name (pointer_sized_int_node);
955 g = gimple_build_assign (p, NOP_EXPR, ptr);
956 gimple_set_location (g, loc);
957 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
958 p = gimple_assign_lhs (g);
959 /* Compute ptr + offset. */
960 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
961 PLUS_EXPR, p, offset);
962 gimple_set_location (g, loc);
963 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
964 /* Now build the conditional and put it into the IR. */
965 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
966 NULL_TREE, NULL_TREE);
967 gimple_set_location (g, loc);
968 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
969 *gsi = gsi_after_labels (then2_bb);
972 /* Generate __ubsan_handle_type_mismatch call. */
973 if (flag_sanitize_undefined_trap_on_error)
974 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
975 else
977 tree data
978 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
979 ubsan_type_descriptor (TREE_TYPE (ptr),
980 UBSAN_PRINT_POINTER),
981 NULL_TREE,
982 build_zero_cst (pointer_sized_int_node),
983 ckind,
984 NULL_TREE);
985 data = build_fold_addr_expr_loc (loc, data);
986 enum built_in_function bcode
987 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
988 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
989 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
990 tree p = make_ssa_name (pointer_sized_int_node);
991 g = gimple_build_assign (p, NOP_EXPR, ptr);
992 gimple_set_location (g, loc);
993 gsi_insert_before (gsi, g, GSI_SAME_STMT);
994 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
996 gimple_set_location (g, loc);
997 gsi_insert_before (gsi, g, GSI_SAME_STMT);
999 /* Point GSI to next logical statement. */
1000 *gsi = gsi_start_bb (fallthru_bb);
1002 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1003 unlink_stmt_vdef (stmt);
1004 gsi_remove (&gsi_orig, true);
1005 return true;
1008 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1009 unlink_stmt_vdef (stmt);
1010 gsi_remove (gsi, true);
1011 return true;
1014 /* Cached __ubsan_vptr_type_cache decl. */
1015 static GTY(()) tree ubsan_vptr_type_cache_decl;
1017 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1018 argument which is a constant, because the middle-end treats pointer
1019 conversions as useless and therefore the type of the first argument
1020 could be changed to any other pointer type. */
1022 bool
1023 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1025 gimple_stmt_iterator gsi = *gsip;
1026 gimple *stmt = gsi_stmt (gsi);
1027 location_t loc = gimple_location (stmt);
1028 gcc_assert (gimple_call_num_args (stmt) == 5);
1029 tree op = gimple_call_arg (stmt, 0);
1030 tree vptr = gimple_call_arg (stmt, 1);
1031 tree str_hash = gimple_call_arg (stmt, 2);
1032 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1033 tree ckind_tree = gimple_call_arg (stmt, 4);
1034 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1035 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1036 gimple *g;
1037 basic_block fallthru_bb = NULL;
1039 if (ckind == UBSAN_DOWNCAST_POINTER)
1041 /* Guard everything with if (op != NULL) { ... }. */
1042 basic_block then_bb;
1043 gimple_stmt_iterator cond_insert_point
1044 = create_cond_insert_point (gsip, false, false, true,
1045 &then_bb, &fallthru_bb);
1046 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1047 NULL_TREE, NULL_TREE);
1048 gimple_set_location (g, loc);
1049 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1050 *gsip = gsi_after_labels (then_bb);
1051 gsi_remove (&gsi, false);
1052 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1053 gsi = *gsip;
1056 tree htype = TREE_TYPE (str_hash);
1057 tree cst = wide_int_to_tree (htype,
1058 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1059 | 0xeb382d69, 64));
1060 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1061 vptr, str_hash);
1062 gimple_set_location (g, loc);
1063 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1064 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1065 gimple_assign_lhs (g), cst);
1066 gimple_set_location (g, loc);
1067 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1068 tree t1 = gimple_assign_lhs (g);
1069 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1070 t1, build_int_cst (integer_type_node, 47));
1071 gimple_set_location (g, loc);
1072 tree t2 = gimple_assign_lhs (g);
1073 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1074 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1075 vptr, t1);
1076 gimple_set_location (g, loc);
1077 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1078 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1079 t2, gimple_assign_lhs (g));
1080 gimple_set_location (g, loc);
1081 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1082 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1083 gimple_assign_lhs (g), cst);
1084 gimple_set_location (g, loc);
1085 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1086 tree t3 = gimple_assign_lhs (g);
1087 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1088 t3, build_int_cst (integer_type_node, 47));
1089 gimple_set_location (g, loc);
1090 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1091 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1092 t3, gimple_assign_lhs (g));
1093 gimple_set_location (g, loc);
1094 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1095 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1096 gimple_assign_lhs (g), cst);
1097 gimple_set_location (g, loc);
1098 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1099 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1101 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1102 NOP_EXPR, gimple_assign_lhs (g));
1103 gimple_set_location (g, loc);
1104 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1106 tree hash = gimple_assign_lhs (g);
1108 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1110 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1111 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1112 get_identifier ("__ubsan_vptr_type_cache"),
1113 atype);
1114 DECL_ARTIFICIAL (array) = 1;
1115 DECL_IGNORED_P (array) = 1;
1116 TREE_PUBLIC (array) = 1;
1117 TREE_STATIC (array) = 1;
1118 DECL_EXTERNAL (array) = 1;
1119 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1120 DECL_VISIBILITY_SPECIFIED (array) = 1;
1121 varpool_node::finalize_decl (array);
1122 ubsan_vptr_type_cache_decl = array;
1125 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1126 BIT_AND_EXPR, hash,
1127 build_int_cst (pointer_sized_int_node, 127));
1128 gimple_set_location (g, loc);
1129 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1131 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1132 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1133 NULL_TREE, NULL_TREE);
1134 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1135 ARRAY_REF, c);
1136 gimple_set_location (g, loc);
1137 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1139 basic_block then_bb, fallthru2_bb;
1140 gimple_stmt_iterator cond_insert_point
1141 = create_cond_insert_point (gsip, false, false, true,
1142 &then_bb, &fallthru2_bb);
1143 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1144 NULL_TREE, NULL_TREE);
1145 gimple_set_location (g, loc);
1146 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1147 *gsip = gsi_after_labels (then_bb);
1148 if (fallthru_bb == NULL)
1149 fallthru_bb = fallthru2_bb;
1151 tree data
1152 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1153 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1154 build_int_cst (unsigned_char_type_node, ckind),
1155 NULL_TREE);
1156 data = build_fold_addr_expr_loc (loc, data);
1157 enum built_in_function bcode
1158 = (flag_sanitize_recover & SANITIZE_VPTR)
1159 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1160 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1162 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1163 gimple_set_location (g, loc);
1164 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1166 /* Point GSI to next logical statement. */
1167 *gsip = gsi_start_bb (fallthru_bb);
1169 /* Get rid of the UBSAN_VPTR call from the IR. */
1170 unlink_stmt_vdef (stmt);
1171 gsi_remove (&gsi, true);
1172 return true;
1175 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1176 whether the pointer is on the left hand side of the assignment. */
1178 static void
1179 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1180 bool is_lhs)
1182 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1183 unsigned int align = 0;
1184 if (flag_sanitize & SANITIZE_ALIGNMENT)
1186 align = min_align_of_type (TREE_TYPE (base));
1187 if (align <= 1)
1188 align = 0;
1190 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
1191 return;
1192 tree t = TREE_OPERAND (base, 0);
1193 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1194 return;
1195 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1196 ikind = UBSAN_MEMBER_ACCESS;
1197 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1198 tree alignt = build_int_cst (pointer_sized_int_node, align);
1199 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1200 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1201 gsi_insert_before (iter, g, GSI_SAME_STMT);
1204 /* Perform the pointer instrumentation. */
1206 static void
1207 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
1209 gimple *stmt = gsi_stmt (gsi);
1210 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1211 /* Handle also e.g. &s->i. */
1212 if (TREE_CODE (t) == ADDR_EXPR)
1213 t = TREE_OPERAND (t, 0);
1214 tree base = get_base_address (t);
1215 if (TREE_CODE (base) == MEM_REF
1216 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1217 instrument_mem_ref (t, base, &gsi, is_lhs);
1220 /* Build an ubsan builtin call for the signed-integer-overflow
1221 sanitization. CODE says what kind of builtin are we building,
1222 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1223 are operands of the binary operation. */
1225 tree
1226 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1227 tree op0, tree op1, tree *datap)
1229 if (flag_sanitize_undefined_trap_on_error)
1230 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1232 tree data;
1233 if (datap && *datap)
1234 data = *datap;
1235 else
1236 data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1237 ubsan_type_descriptor (lhstype), NULL_TREE,
1238 NULL_TREE);
1239 if (datap)
1240 *datap = data;
1241 enum built_in_function fn_code;
1243 switch (code)
1245 case PLUS_EXPR:
1246 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1247 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1248 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1249 break;
1250 case MINUS_EXPR:
1251 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1252 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1253 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1254 break;
1255 case MULT_EXPR:
1256 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1257 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1258 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1259 break;
1260 case NEGATE_EXPR:
1261 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1262 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1263 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1264 break;
1265 default:
1266 gcc_unreachable ();
1268 tree fn = builtin_decl_explicit (fn_code);
1269 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1270 build_fold_addr_expr_loc (loc, data),
1271 ubsan_encode_value (op0, true),
1272 op1 ? ubsan_encode_value (op1, true)
1273 : NULL_TREE);
1276 /* Perform the signed integer instrumentation. GSI is the iterator
1277 pointing at statement we are trying to instrument. */
1279 static void
1280 instrument_si_overflow (gimple_stmt_iterator gsi)
1282 gimple *stmt = gsi_stmt (gsi);
1283 tree_code code = gimple_assign_rhs_code (stmt);
1284 tree lhs = gimple_assign_lhs (stmt);
1285 tree lhstype = TREE_TYPE (lhs);
1286 tree lhsinner = VECTOR_TYPE_P (lhstype) ? TREE_TYPE (lhstype) : lhstype;
1287 tree a, b;
1288 gimple *g;
1290 /* If this is not a signed operation, don't instrument anything here.
1291 Also punt on bit-fields. */
1292 if (!INTEGRAL_TYPE_P (lhsinner)
1293 || TYPE_OVERFLOW_WRAPS (lhsinner)
1294 || GET_MODE_BITSIZE (TYPE_MODE (lhsinner)) != TYPE_PRECISION (lhsinner))
1295 return;
1297 switch (code)
1299 case MINUS_EXPR:
1300 case PLUS_EXPR:
1301 case MULT_EXPR:
1302 /* Transform
1303 i = u {+,-,*} 5;
1304 into
1305 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1306 a = gimple_assign_rhs1 (stmt);
1307 b = gimple_assign_rhs2 (stmt);
1308 g = gimple_build_call_internal (code == PLUS_EXPR
1309 ? IFN_UBSAN_CHECK_ADD
1310 : code == MINUS_EXPR
1311 ? IFN_UBSAN_CHECK_SUB
1312 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1313 gimple_call_set_lhs (g, lhs);
1314 gsi_replace (&gsi, g, true);
1315 break;
1316 case NEGATE_EXPR:
1317 /* Represent i = -u;
1319 i = UBSAN_CHECK_SUB (0, u); */
1320 a = build_zero_cst (lhstype);
1321 b = gimple_assign_rhs1 (stmt);
1322 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1323 gimple_call_set_lhs (g, lhs);
1324 gsi_replace (&gsi, g, true);
1325 break;
1326 case ABS_EXPR:
1327 /* Transform i = ABS_EXPR<u>;
1328 into
1329 _N = UBSAN_CHECK_SUB (0, u);
1330 i = ABS_EXPR<_N>; */
1331 a = build_zero_cst (lhstype);
1332 b = gimple_assign_rhs1 (stmt);
1333 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1334 a = make_ssa_name (lhstype);
1335 gimple_call_set_lhs (g, a);
1336 gimple_set_location (g, gimple_location (stmt));
1337 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1338 gimple_assign_set_rhs1 (stmt, a);
1339 update_stmt (stmt);
1340 break;
1341 default:
1342 break;
1346 /* Instrument loads from (non-bitfield) bool and C++ enum values
1347 to check if the memory value is outside of the range of the valid
1348 type values. */
1350 static void
1351 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1353 gimple *stmt = gsi_stmt (*gsi);
1354 tree rhs = gimple_assign_rhs1 (stmt);
1355 tree type = TREE_TYPE (rhs);
1356 tree minv = NULL_TREE, maxv = NULL_TREE;
1358 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1360 minv = boolean_false_node;
1361 maxv = boolean_true_node;
1363 else if (TREE_CODE (type) == ENUMERAL_TYPE
1364 && (flag_sanitize & SANITIZE_ENUM)
1365 && TREE_TYPE (type) != NULL_TREE
1366 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1367 && (TYPE_PRECISION (TREE_TYPE (type))
1368 < GET_MODE_PRECISION (TYPE_MODE (type))))
1370 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1371 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1373 else
1374 return;
1376 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1377 HOST_WIDE_INT bitsize, bitpos;
1378 tree offset;
1379 machine_mode mode;
1380 int volatilep = 0, reversep, unsignedp = 0;
1381 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1382 &unsignedp, &reversep, &volatilep);
1383 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1385 if ((VAR_P (base) && DECL_HARD_REGISTER (base))
1386 || (bitpos % modebitsize) != 0
1387 || bitsize != modebitsize
1388 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1389 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1390 return;
1392 bool ends_bb = stmt_ends_bb_p (stmt);
1393 location_t loc = gimple_location (stmt);
1394 tree lhs = gimple_assign_lhs (stmt);
1395 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1396 tree atype = reference_alias_ptr_type (rhs);
1397 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1398 build_fold_addr_expr (rhs));
1399 gimple_set_location (g, loc);
1400 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1401 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1402 build_int_cst (atype, 0));
1403 tree urhs = make_ssa_name (utype);
1404 if (ends_bb)
1406 gimple_assign_set_lhs (stmt, urhs);
1407 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1408 gimple_set_location (g, loc);
1409 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1410 gsi_insert_on_edge_immediate (e, g);
1411 gimple_assign_set_rhs_from_tree (gsi, mem);
1412 update_stmt (stmt);
1413 *gsi = gsi_for_stmt (g);
1414 g = stmt;
1416 else
1418 g = gimple_build_assign (urhs, mem);
1419 gimple_set_location (g, loc);
1420 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1422 minv = fold_convert (utype, minv);
1423 maxv = fold_convert (utype, maxv);
1424 if (!integer_zerop (minv))
1426 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1427 gimple_set_location (g, loc);
1428 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1431 gimple_stmt_iterator gsi2 = *gsi;
1432 basic_block then_bb, fallthru_bb;
1433 *gsi = create_cond_insert_point (gsi, true, false, true,
1434 &then_bb, &fallthru_bb);
1435 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1436 int_const_binop (MINUS_EXPR, maxv, minv),
1437 NULL_TREE, NULL_TREE);
1438 gimple_set_location (g, loc);
1439 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1441 if (!ends_bb)
1443 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1444 update_stmt (stmt);
1447 gsi2 = gsi_after_labels (then_bb);
1448 if (flag_sanitize_undefined_trap_on_error)
1449 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1450 else
1452 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1453 ubsan_type_descriptor (type), NULL_TREE,
1454 NULL_TREE);
1455 data = build_fold_addr_expr_loc (loc, data);
1456 enum built_in_function bcode
1457 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1458 ? SANITIZE_BOOL : SANITIZE_ENUM))
1459 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1460 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1461 tree fn = builtin_decl_explicit (bcode);
1463 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1464 true, NULL_TREE, true,
1465 GSI_SAME_STMT);
1466 g = gimple_build_call (fn, 2, data, val);
1468 gimple_set_location (g, loc);
1469 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1470 ubsan_create_edge (g);
1471 *gsi = gsi_for_stmt (stmt);
1474 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1475 new style handlers. Libubsan uses heuristics to destinguish between old and
1476 new styles and relies on these properties for filename:
1478 a) Location's filename must not be NULL.
1479 b) Location's filename must not be equal to "".
1480 c) Location's filename must not be equal to "\1".
1481 d) First two bytes of filename must not contain '\xff' symbol. */
1483 static bool
1484 ubsan_use_new_style_p (location_t loc)
1486 if (loc == UNKNOWN_LOCATION)
1487 return false;
1489 expanded_location xloc = expand_location (loc);
1490 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
1491 || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1492 || xloc.file[1] == '\xff')
1493 return false;
1495 return true;
1498 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1499 destination, EXPR is floating-point expression. */
1501 tree
1502 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1504 tree expr_type = TREE_TYPE (expr);
1505 tree t, tt, fn, min, max;
1506 machine_mode mode = TYPE_MODE (expr_type);
1507 int prec = TYPE_PRECISION (type);
1508 bool uns_p = TYPE_UNSIGNED (type);
1509 if (loc == UNKNOWN_LOCATION)
1510 loc = input_location;
1512 /* Float to integer conversion first truncates toward zero, so
1513 even signed char c = 127.875f; is not problematic.
1514 Therefore, we should complain only if EXPR is unordered or smaller
1515 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1516 TYPE_MAX_VALUE + 1.0. */
1517 if (REAL_MODE_FORMAT (mode)->b == 2)
1519 /* For maximum, TYPE_MAX_VALUE might not be representable
1520 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1521 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1522 either representable or infinity. */
1523 REAL_VALUE_TYPE maxval = dconst1;
1524 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1525 real_convert (&maxval, mode, &maxval);
1526 max = build_real (expr_type, maxval);
1528 /* For unsigned, assume -1.0 is always representable. */
1529 if (uns_p)
1530 min = build_minus_one_cst (expr_type);
1531 else
1533 /* TYPE_MIN_VALUE is generally representable (or -inf),
1534 but TYPE_MIN_VALUE - 1.0 might not be. */
1535 REAL_VALUE_TYPE minval = dconstm1, minval2;
1536 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1537 real_convert (&minval, mode, &minval);
1538 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1539 real_convert (&minval2, mode, &minval2);
1540 if (real_compare (EQ_EXPR, &minval, &minval2)
1541 && !real_isinf (&minval))
1543 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1544 rounds to TYPE_MIN_VALUE, we need to subtract
1545 more. As REAL_MODE_FORMAT (mode)->p is the number
1546 of base digits, we want to subtract a number that
1547 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1548 times smaller than minval. */
1549 minval2 = dconst1;
1550 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1551 SET_REAL_EXP (&minval2,
1552 REAL_EXP (&minval2) + prec - 1
1553 - REAL_MODE_FORMAT (mode)->p + 1);
1554 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1555 real_convert (&minval2, mode, &minval2);
1557 min = build_real (expr_type, minval2);
1560 else if (REAL_MODE_FORMAT (mode)->b == 10)
1562 /* For _Decimal128 up to 34 decimal digits, - sign,
1563 dot, e, exponent. */
1564 char buf[64];
1565 mpfr_t m;
1566 int p = REAL_MODE_FORMAT (mode)->p;
1567 REAL_VALUE_TYPE maxval, minval;
1569 /* Use mpfr_snprintf rounding to compute the smallest
1570 representable decimal number greater or equal than
1571 1 << (prec - !uns_p). */
1572 mpfr_init2 (m, prec + 2);
1573 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1574 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1575 decimal_real_from_string (&maxval, buf);
1576 max = build_real (expr_type, maxval);
1578 /* For unsigned, assume -1.0 is always representable. */
1579 if (uns_p)
1580 min = build_minus_one_cst (expr_type);
1581 else
1583 /* Use mpfr_snprintf rounding to compute the largest
1584 representable decimal number less or equal than
1585 (-1 << (prec - 1)) - 1. */
1586 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1587 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1588 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1589 decimal_real_from_string (&minval, buf);
1590 min = build_real (expr_type, minval);
1592 mpfr_clear (m);
1594 else
1595 return NULL_TREE;
1597 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1598 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1599 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1600 if (integer_zerop (t))
1601 return NULL_TREE;
1603 if (flag_sanitize_undefined_trap_on_error)
1604 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1605 else
1607 location_t *loc_ptr = NULL;
1608 unsigned num_locations = 0;
1609 /* Figure out if we can propagate location to ubsan_data and use new
1610 style handlers in libubsan. */
1611 if (ubsan_use_new_style_p (loc))
1613 loc_ptr = &loc;
1614 num_locations = 1;
1616 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1617 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
1618 num_locations, loc_ptr,
1619 ubsan_type_descriptor (expr_type),
1620 ubsan_type_descriptor (type), NULL_TREE,
1621 NULL_TREE);
1622 enum built_in_function bcode
1623 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
1624 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1625 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1626 fn = builtin_decl_explicit (bcode);
1627 fn = build_call_expr_loc (loc, fn, 2,
1628 build_fold_addr_expr_loc (loc, data),
1629 ubsan_encode_value (expr, false));
1632 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
1635 /* Instrument values passed to function arguments with nonnull attribute. */
1637 static void
1638 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1640 gimple *stmt = gsi_stmt (*gsi);
1641 location_t loc[2];
1642 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1643 while for nonnull sanitization it is clear. */
1644 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1645 flag_delete_null_pointer_checks = 1;
1646 loc[0] = gimple_location (stmt);
1647 loc[1] = UNKNOWN_LOCATION;
1648 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1650 tree arg = gimple_call_arg (stmt, i);
1651 if (POINTER_TYPE_P (TREE_TYPE (arg))
1652 && infer_nonnull_range_by_attribute (stmt, arg))
1654 gimple *g;
1655 if (!is_gimple_val (arg))
1657 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
1658 gimple_set_location (g, loc[0]);
1659 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1660 arg = gimple_assign_lhs (g);
1663 basic_block then_bb, fallthru_bb;
1664 *gsi = create_cond_insert_point (gsi, true, false, true,
1665 &then_bb, &fallthru_bb);
1666 g = gimple_build_cond (EQ_EXPR, arg,
1667 build_zero_cst (TREE_TYPE (arg)),
1668 NULL_TREE, NULL_TREE);
1669 gimple_set_location (g, loc[0]);
1670 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1672 *gsi = gsi_after_labels (then_bb);
1673 if (flag_sanitize_undefined_trap_on_error)
1674 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1675 else
1677 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1678 2, loc, NULL_TREE,
1679 build_int_cst (integer_type_node,
1680 i + 1),
1681 NULL_TREE);
1682 data = build_fold_addr_expr_loc (loc[0], data);
1683 enum built_in_function bcode
1684 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
1685 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1686 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1687 tree fn = builtin_decl_explicit (bcode);
1689 g = gimple_build_call (fn, 1, data);
1691 gimple_set_location (g, loc[0]);
1692 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1693 ubsan_create_edge (g);
1695 *gsi = gsi_for_stmt (stmt);
1697 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1700 /* Instrument returns in functions with returns_nonnull attribute. */
1702 static void
1703 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1705 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
1706 location_t loc[2];
1707 tree arg = gimple_return_retval (stmt);
1708 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1709 while for nonnull return sanitization it is clear. */
1710 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1711 flag_delete_null_pointer_checks = 1;
1712 loc[0] = gimple_location (stmt);
1713 loc[1] = UNKNOWN_LOCATION;
1714 if (arg
1715 && POINTER_TYPE_P (TREE_TYPE (arg))
1716 && is_gimple_val (arg)
1717 && infer_nonnull_range_by_attribute (stmt, arg))
1719 basic_block then_bb, fallthru_bb;
1720 *gsi = create_cond_insert_point (gsi, true, false, true,
1721 &then_bb, &fallthru_bb);
1722 gimple *g = gimple_build_cond (EQ_EXPR, arg,
1723 build_zero_cst (TREE_TYPE (arg)),
1724 NULL_TREE, NULL_TREE);
1725 gimple_set_location (g, loc[0]);
1726 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1728 *gsi = gsi_after_labels (then_bb);
1729 if (flag_sanitize_undefined_trap_on_error)
1730 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1731 else
1733 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1734 2, loc, NULL_TREE, NULL_TREE);
1735 data = build_fold_addr_expr_loc (loc[0], data);
1736 enum built_in_function bcode
1737 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1738 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1739 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1740 tree fn = builtin_decl_explicit (bcode);
1742 g = gimple_build_call (fn, 1, data);
1744 gimple_set_location (g, loc[0]);
1745 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1746 ubsan_create_edge (g);
1747 *gsi = gsi_for_stmt (stmt);
1749 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1752 /* Instrument memory references. Here we check whether the pointer
1753 points to an out-of-bounds location. */
1755 static void
1756 instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs)
1758 gimple *stmt = gsi_stmt (*gsi);
1759 location_t loc = gimple_location (stmt);
1760 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
1761 tree type;
1762 tree index = NULL_TREE;
1763 HOST_WIDE_INT size_in_bytes;
1765 type = TREE_TYPE (t);
1766 if (VOID_TYPE_P (type))
1767 return;
1769 switch (TREE_CODE (t))
1771 case COMPONENT_REF:
1772 if (TREE_CODE (t) == COMPONENT_REF
1773 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
1775 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
1776 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
1777 repr, TREE_OPERAND (t, 2));
1779 break;
1780 case ARRAY_REF:
1781 index = TREE_OPERAND (t, 1);
1782 break;
1783 case INDIRECT_REF:
1784 case MEM_REF:
1785 case VAR_DECL:
1786 case PARM_DECL:
1787 case RESULT_DECL:
1788 break;
1789 default:
1790 return;
1793 size_in_bytes = int_size_in_bytes (type);
1794 if (size_in_bytes <= 0)
1795 return;
1797 HOST_WIDE_INT bitsize, bitpos;
1798 tree offset;
1799 machine_mode mode;
1800 int volatilep = 0, reversep, unsignedp = 0;
1801 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1802 &unsignedp, &reversep, &volatilep);
1804 if (bitpos % BITS_PER_UNIT != 0
1805 || bitsize != size_in_bytes * BITS_PER_UNIT)
1806 return;
1808 bool decl_p = DECL_P (inner);
1809 tree base;
1810 if (decl_p)
1812 if (DECL_REGISTER (inner))
1813 return;
1814 base = inner;
1816 else if (TREE_CODE (inner) == MEM_REF)
1817 base = TREE_OPERAND (inner, 0);
1818 else
1819 return;
1820 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
1822 while (TREE_CODE (base) == SSA_NAME)
1824 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
1825 if (gimple_assign_ssa_name_copy_p (def_stmt)
1826 || (gimple_assign_cast_p (def_stmt)
1827 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
1828 || (is_gimple_assign (def_stmt)
1829 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
1831 tree rhs1 = gimple_assign_rhs1 (def_stmt);
1832 if (TREE_CODE (rhs1) == SSA_NAME
1833 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
1834 break;
1835 else
1836 base = rhs1;
1838 else
1839 break;
1842 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1843 return;
1845 tree sizet;
1846 tree base_addr = base;
1847 gimple *bos_stmt = NULL;
1848 if (decl_p)
1849 base_addr = build1 (ADDR_EXPR,
1850 build_pointer_type (TREE_TYPE (base)), base);
1851 unsigned HOST_WIDE_INT size;
1852 if (compute_builtin_object_size (base_addr, 0, &size))
1853 sizet = build_int_cst (sizetype, size);
1854 else if (optimize)
1856 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
1857 loc = input_location;
1858 /* Generate __builtin_object_size call. */
1859 sizet = builtin_decl_explicit (BUILT_IN_OBJECT_SIZE);
1860 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
1861 integer_zero_node);
1862 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
1863 GSI_SAME_STMT);
1864 /* If the call above didn't end up being an integer constant, go one
1865 statement back and get the __builtin_object_size stmt. Save it,
1866 we might need it later. */
1867 if (SSA_VAR_P (sizet))
1869 gsi_prev (gsi);
1870 bos_stmt = gsi_stmt (*gsi);
1872 /* Move on to where we were. */
1873 gsi_next (gsi);
1876 else
1877 return;
1879 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1880 call. */
1881 /* ptr + sizeof (*ptr) - base */
1882 t = fold_build2 (MINUS_EXPR, sizetype,
1883 fold_convert (pointer_sized_int_node, ptr),
1884 fold_convert (pointer_sized_int_node, base_addr));
1885 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
1887 /* Perhaps we can omit the check. */
1888 if (TREE_CODE (t) == INTEGER_CST
1889 && TREE_CODE (sizet) == INTEGER_CST
1890 && tree_int_cst_le (t, sizet))
1891 return;
1893 if (index != NULL_TREE
1894 && TREE_CODE (index) == SSA_NAME
1895 && TREE_CODE (sizet) == INTEGER_CST)
1897 gimple *def = SSA_NAME_DEF_STMT (index);
1898 if (is_gimple_assign (def)
1899 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
1900 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
1902 tree cst = gimple_assign_rhs2 (def);
1903 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
1904 TYPE_SIZE_UNIT (type));
1905 if (tree_int_cst_sgn (cst) >= 0
1906 && tree_int_cst_lt (cst, sz))
1907 return;
1911 if (bos_stmt && gimple_call_builtin_p (bos_stmt, BUILT_IN_OBJECT_SIZE))
1912 ubsan_create_edge (bos_stmt);
1914 /* We have to emit the check. */
1915 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1916 GSI_SAME_STMT);
1917 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
1918 GSI_SAME_STMT);
1919 tree ckind = build_int_cst (unsigned_char_type_node,
1920 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
1921 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
1922 ptr, t, sizet, ckind);
1923 gimple_set_location (g, loc);
1924 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1927 /* True if we want to play UBSan games in the current function. */
1929 bool
1930 do_ubsan_in_current_function ()
1932 return (current_function_decl != NULL_TREE
1933 && !lookup_attribute ("no_sanitize_undefined",
1934 DECL_ATTRIBUTES (current_function_decl)));
1937 namespace {
1939 const pass_data pass_data_ubsan =
1941 GIMPLE_PASS, /* type */
1942 "ubsan", /* name */
1943 OPTGROUP_NONE, /* optinfo_flags */
1944 TV_TREE_UBSAN, /* tv_id */
1945 ( PROP_cfg | PROP_ssa ), /* properties_required */
1946 0, /* properties_provided */
1947 0, /* properties_destroyed */
1948 0, /* todo_flags_start */
1949 TODO_update_ssa, /* todo_flags_finish */
1952 class pass_ubsan : public gimple_opt_pass
1954 public:
1955 pass_ubsan (gcc::context *ctxt)
1956 : gimple_opt_pass (pass_data_ubsan, ctxt)
1959 /* opt_pass methods: */
1960 virtual bool gate (function *)
1962 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1963 | SANITIZE_BOOL | SANITIZE_ENUM
1964 | SANITIZE_ALIGNMENT
1965 | SANITIZE_NONNULL_ATTRIBUTE
1966 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1967 | SANITIZE_OBJECT_SIZE)
1968 && do_ubsan_in_current_function ();
1971 virtual unsigned int execute (function *);
1973 }; // class pass_ubsan
1975 unsigned int
1976 pass_ubsan::execute (function *fun)
1978 basic_block bb;
1979 gimple_stmt_iterator gsi;
1980 unsigned int ret = 0;
1982 initialize_sanitizer_builtins ();
1984 FOR_EACH_BB_FN (bb, fun)
1986 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1988 gimple *stmt = gsi_stmt (gsi);
1989 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1991 gsi_next (&gsi);
1992 continue;
1995 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1996 && is_gimple_assign (stmt))
1997 instrument_si_overflow (gsi);
1999 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
2001 if (gimple_store_p (stmt))
2002 instrument_null (gsi, true);
2003 if (gimple_assign_single_p (stmt))
2004 instrument_null (gsi, false);
2005 if (is_gimple_call (stmt))
2007 unsigned args_num = gimple_call_num_args (stmt);
2008 for (unsigned i = 0; i < args_num; ++i)
2010 tree arg = gimple_call_arg (stmt, i);
2011 if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2012 continue;
2013 tree base = get_base_address (arg);
2014 if (TREE_CODE (base) == MEM_REF
2015 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
2016 instrument_mem_ref (arg, base, &gsi, false);
2021 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
2022 && gimple_assign_load_p (stmt))
2024 instrument_bool_enum_load (&gsi);
2025 bb = gimple_bb (stmt);
2028 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
2029 && is_gimple_call (stmt)
2030 && !gimple_call_internal_p (stmt))
2032 instrument_nonnull_arg (&gsi);
2033 bb = gimple_bb (stmt);
2036 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2037 && gimple_code (stmt) == GIMPLE_RETURN)
2039 instrument_nonnull_return (&gsi);
2040 bb = gimple_bb (stmt);
2043 if (flag_sanitize & SANITIZE_OBJECT_SIZE)
2045 if (gimple_store_p (stmt))
2046 instrument_object_size (&gsi, true);
2047 if (gimple_assign_load_p (stmt))
2048 instrument_object_size (&gsi, false);
2051 gsi_next (&gsi);
2053 if (gimple_purge_dead_eh_edges (bb))
2054 ret = TODO_cleanup_cfg;
2056 return ret;
2059 } // anon namespace
2061 gimple_opt_pass *
2062 make_pass_ubsan (gcc::context *ctxt)
2064 return new pass_ubsan (ctxt);
2067 #include "gt-ubsan.h"