Skip gcc.target/i386/shrink_wrap_1.c on ia32
[official-gcc.git] / gcc / ubsan.c
blobe3128ad6177027f75f3c036abcebd674a33d61dd
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2014 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 "tree.h"
25 #include "stor-layout.h"
26 #include "stringpool.h"
27 #include "cgraph.h"
28 #include "tree-pass.h"
29 #include "tree-ssa-alias.h"
30 #include "tree-pretty-print.h"
31 #include "internal-fn.h"
32 #include "gimple-expr.h"
33 #include "gimple.h"
34 #include "gimple-iterator.h"
35 #include "gimple-ssa.h"
36 #include "gimple-walk.h"
37 #include "hashtab.h"
38 #include "output.h"
39 #include "tm_p.h"
40 #include "toplev.h"
41 #include "cfgloop.h"
42 #include "ubsan.h"
43 #include "c-family/c-common.h"
44 #include "rtl.h"
45 #include "expr.h"
46 #include "tree-ssanames.h"
47 #include "asan.h"
48 #include "gimplify-me.h"
49 #include "intl.h"
50 #include "realmpfr.h"
51 #include "dfp.h"
52 #include "builtins.h"
54 /* Map from a tree to a VAR_DECL tree. */
56 struct GTY(()) tree_type_map {
57 struct tree_map_base type;
58 tree decl;
61 #define tree_type_map_eq tree_map_base_eq
62 #define tree_type_map_marked_p tree_map_base_marked_p
64 /* Hash from a tree in a tree_type_map. */
66 unsigned int
67 tree_type_map_hash (const void *item)
69 return TYPE_UID (((const struct tree_type_map *)item)->type.from);
72 static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map)))
73 htab_t decl_tree_for_type;
75 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
77 static tree
78 decl_for_type_lookup (tree type)
80 /* If the hash table is not initialized yet, create it now. */
81 if (decl_tree_for_type == NULL)
83 decl_tree_for_type = htab_create_ggc (10, tree_type_map_hash,
84 tree_type_map_eq, 0);
85 /* That also means we don't have to bother with the lookup. */
86 return NULL_TREE;
89 struct tree_type_map *h, in;
90 in.type.from = type;
92 h = (struct tree_type_map *)
93 htab_find_with_hash (decl_tree_for_type, &in, TYPE_UID (type));
94 return h ? h->decl : NULL_TREE;
97 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
99 static void
100 decl_for_type_insert (tree type, tree decl)
102 struct tree_type_map *h;
103 void **slot;
105 h = ggc_alloc<tree_type_map> ();
106 h->type.from = type;
107 h->decl = decl;
108 slot = htab_find_slot_with_hash (decl_tree_for_type, h, TYPE_UID (type),
109 INSERT);
110 *(struct tree_type_map **) slot = h;
113 /* Helper routine, which encodes a value in the pointer_sized_int_node.
114 Arguments with precision <= POINTER_SIZE are passed directly,
115 the rest is passed by reference. T is a value we are to encode.
116 IN_EXPAND_P is true if this function is called during expansion. */
118 tree
119 ubsan_encode_value (tree t, bool in_expand_p)
121 tree type = TREE_TYPE (t);
122 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
123 if (bitsize <= POINTER_SIZE)
124 switch (TREE_CODE (type))
126 case BOOLEAN_TYPE:
127 case ENUMERAL_TYPE:
128 case INTEGER_TYPE:
129 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
130 case REAL_TYPE:
132 tree itype = build_nonstandard_integer_type (bitsize, true);
133 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
134 return fold_convert (pointer_sized_int_node, t);
136 default:
137 gcc_unreachable ();
139 else
141 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
143 /* The reason for this is that we don't want to pessimize
144 code by making vars unnecessarily addressable. */
145 tree var = create_tmp_var (type, NULL);
146 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
147 if (in_expand_p)
149 rtx mem
150 = assign_stack_temp_for_type (TYPE_MODE (type),
151 GET_MODE_SIZE (TYPE_MODE (type)),
152 type);
153 SET_DECL_RTL (var, mem);
154 expand_assignment (var, t, false);
155 return build_fold_addr_expr (var);
157 t = build_fold_addr_expr (var);
158 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
160 else
161 return build_fold_addr_expr (t);
165 /* Build
166 struct __ubsan_type_descriptor
168 unsigned short __typekind;
169 unsigned short __typeinfo;
170 char __typename[];
172 type. */
174 static tree
175 ubsan_type_descriptor_type (void)
177 static const char *field_names[3]
178 = { "__typekind", "__typeinfo", "__typename" };
179 tree fields[3], ret;
180 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
181 tree flex_arr_type = build_array_type (char_type_node, itype);
183 ret = make_node (RECORD_TYPE);
184 for (int i = 0; i < 3; i++)
186 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
187 get_identifier (field_names[i]),
188 (i == 2) ? flex_arr_type
189 : short_unsigned_type_node);
190 DECL_CONTEXT (fields[i]) = ret;
191 if (i)
192 DECL_CHAIN (fields[i - 1]) = fields[i];
194 TYPE_FIELDS (ret) = fields[0];
195 TYPE_NAME (ret) = get_identifier ("__ubsan_type_descriptor");
196 layout_type (ret);
197 return ret;
200 /* Build
201 struct __ubsan_source_location
203 const char *__filename;
204 unsigned int __line;
205 unsigned int __column;
207 type. */
209 static tree
210 ubsan_source_location_type (void)
212 static const char *field_names[3]
213 = { "__filename", "__line", "__column" };
214 tree fields[3], ret;
215 tree const_char_type = build_qualified_type (char_type_node,
216 TYPE_QUAL_CONST);
218 ret = make_node (RECORD_TYPE);
219 for (int i = 0; i < 3; i++)
221 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
222 get_identifier (field_names[i]),
223 (i == 0) ? build_pointer_type (const_char_type)
224 : unsigned_type_node);
225 DECL_CONTEXT (fields[i]) = ret;
226 if (i)
227 DECL_CHAIN (fields[i - 1]) = fields[i];
229 TYPE_FIELDS (ret) = fields[0];
230 TYPE_NAME (ret) = get_identifier ("__ubsan_source_location");
231 layout_type (ret);
232 return ret;
235 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
236 type with its fields filled from a location_t LOC. */
238 static tree
239 ubsan_source_location (location_t loc)
241 expanded_location xloc;
242 tree type = ubsan_source_location_type ();
244 xloc = expand_location (loc);
245 tree str;
246 if (xloc.file == NULL)
248 str = build_int_cst (ptr_type_node, 0);
249 xloc.line = 0;
250 xloc.column = 0;
252 else
254 /* Fill in the values from LOC. */
255 size_t len = strlen (xloc.file);
256 str = build_string (len + 1, xloc.file);
257 TREE_TYPE (str) = build_array_type (char_type_node,
258 build_index_type (size_int (len)));
259 TREE_READONLY (str) = 1;
260 TREE_STATIC (str) = 1;
261 str = build_fold_addr_expr (str);
263 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
264 build_int_cst (unsigned_type_node,
265 xloc.line), NULL_TREE,
266 build_int_cst (unsigned_type_node,
267 xloc.column));
268 TREE_CONSTANT (ctor) = 1;
269 TREE_STATIC (ctor) = 1;
271 return ctor;
274 /* This routine returns a magic number for TYPE. */
276 static unsigned short
277 get_ubsan_type_info_for_type (tree type)
279 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
280 if (TREE_CODE (type) == REAL_TYPE)
281 return tree_to_uhwi (TYPE_SIZE (type));
282 else if (INTEGRAL_TYPE_P (type))
284 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
285 gcc_assert (prec != -1);
286 return (prec << 1) | !TYPE_UNSIGNED (type);
288 else
289 return 0;
292 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
293 descriptor. It first looks into the hash table; if not found,
294 create the VAR_DECL, put it into the hash table and return the
295 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
296 an enum controlling how we want to print the type. */
298 tree
299 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
301 /* See through any typedefs. */
302 type = TYPE_MAIN_VARIANT (type);
304 tree decl = decl_for_type_lookup (type);
305 /* It is possible that some of the earlier created DECLs were found
306 unused, in that case they weren't emitted and varpool_node::get
307 returns NULL node on them. But now we really need them. Thus,
308 renew them here. */
309 if (decl != NULL_TREE && varpool_node::get (decl))
310 return build_fold_addr_expr (decl);
312 tree dtype = ubsan_type_descriptor_type ();
313 tree type2 = type;
314 const char *tname = NULL;
315 char *pretty_name;
316 unsigned char deref_depth = 0;
317 unsigned short tkind, tinfo;
319 /* Get the name of the type, or the name of the pointer type. */
320 if (pstyle == UBSAN_PRINT_POINTER)
322 gcc_assert (POINTER_TYPE_P (type));
323 type2 = TREE_TYPE (type);
325 /* Remove any '*' operators from TYPE. */
326 while (POINTER_TYPE_P (type2))
327 deref_depth++, type2 = TREE_TYPE (type2);
329 if (TREE_CODE (type2) == METHOD_TYPE)
330 type2 = TYPE_METHOD_BASETYPE (type2);
333 /* If an array, get its type. */
334 type2 = strip_array_types (type2);
336 if (pstyle == UBSAN_PRINT_ARRAY)
338 while (POINTER_TYPE_P (type2))
339 deref_depth++, type2 = TREE_TYPE (type2);
342 if (TYPE_NAME (type2) != NULL)
344 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
345 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
346 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
347 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
350 if (tname == NULL)
351 /* We weren't able to determine the type name. */
352 tname = "<unknown>";
354 /* Decorate the type name with '', '*', "struct", or "union". */
355 pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
356 if (pstyle == UBSAN_PRINT_POINTER)
358 int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
359 TYPE_VOLATILE (type2) ? "volatile " : "",
360 TYPE_READONLY (type2) ? "const " : "",
361 TYPE_RESTRICT (type2) ? "restrict " : "",
362 TYPE_ATOMIC (type2) ? "_Atomic " : "",
363 TREE_CODE (type2) == RECORD_TYPE
364 ? "struct "
365 : TREE_CODE (type2) == UNION_TYPE
366 ? "union " : "", tname,
367 deref_depth == 0 ? "" : " ");
368 while (deref_depth-- > 0)
369 pretty_name[pos++] = '*';
370 pretty_name[pos++] = '\'';
371 pretty_name[pos] = '\0';
373 else if (pstyle == UBSAN_PRINT_ARRAY)
375 /* Pretty print the array dimensions. */
376 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
377 tree t = type;
378 int pos = sprintf (pretty_name, "'%s ", tname);
379 while (deref_depth-- > 0)
380 pretty_name[pos++] = '*';
381 while (TREE_CODE (t) == ARRAY_TYPE)
383 pretty_name[pos++] = '[';
384 tree dom = TYPE_DOMAIN (t);
385 if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
386 pos += sprintf (&pretty_name[pos], HOST_WIDE_INT_PRINT_DEC,
387 tree_to_shwi (TYPE_MAX_VALUE (dom)) + 1);
388 else
389 /* ??? We can't determine the variable name; print VLA unspec. */
390 pretty_name[pos++] = '*';
391 pretty_name[pos++] = ']';
392 t = TREE_TYPE (t);
394 pretty_name[pos++] = '\'';
395 pretty_name[pos] = '\0';
397 /* Save the tree with stripped types. */
398 type = t;
400 else
401 sprintf (pretty_name, "'%s'", tname);
403 switch (TREE_CODE (type))
405 case BOOLEAN_TYPE:
406 case ENUMERAL_TYPE:
407 case INTEGER_TYPE:
408 tkind = 0x0000;
409 break;
410 case REAL_TYPE:
411 /* FIXME: libubsan right now only supports float, double and
412 long double type formats. */
413 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
414 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
415 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
416 tkind = 0x0001;
417 else
418 tkind = 0xffff;
419 break;
420 default:
421 tkind = 0xffff;
422 break;
424 tinfo = get_ubsan_type_info_for_type (type);
426 /* Create a new VAR_DECL of type descriptor. */
427 char tmp_name[32];
428 static unsigned int type_var_id_num;
429 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
430 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
431 dtype);
432 TREE_STATIC (decl) = 1;
433 TREE_PUBLIC (decl) = 0;
434 DECL_ARTIFICIAL (decl) = 1;
435 DECL_IGNORED_P (decl) = 1;
436 DECL_EXTERNAL (decl) = 0;
438 size_t len = strlen (pretty_name);
439 tree str = build_string (len + 1, pretty_name);
440 TREE_TYPE (str) = build_array_type (char_type_node,
441 build_index_type (size_int (len)));
442 TREE_READONLY (str) = 1;
443 TREE_STATIC (str) = 1;
444 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
445 build_int_cst (short_unsigned_type_node,
446 tkind), NULL_TREE,
447 build_int_cst (short_unsigned_type_node,
448 tinfo), NULL_TREE, str);
449 TREE_CONSTANT (ctor) = 1;
450 TREE_STATIC (ctor) = 1;
451 DECL_INITIAL (decl) = ctor;
452 varpool_node::finalize_decl (decl);
454 /* Save the VAR_DECL into the hash table. */
455 decl_for_type_insert (type, decl);
457 return build_fold_addr_expr (decl);
460 /* Create a structure for the ubsan library. NAME is a name of the new
461 structure. LOCCNT is number of locations, PLOC points to array of
462 locations. The arguments in ... are of __ubsan_type_descriptor type
463 and there are at most two of them, followed by NULL_TREE, followed
464 by optional extra arguments and another NULL_TREE. */
466 tree
467 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
469 va_list args;
470 tree ret, t;
471 tree fields[6];
472 vec<tree, va_gc> *saved_args = NULL;
473 size_t i = 0;
474 int j;
476 /* Firstly, create a pointer to type descriptor type. */
477 tree td_type = ubsan_type_descriptor_type ();
478 TYPE_READONLY (td_type) = 1;
479 td_type = build_pointer_type (td_type);
481 /* Create the structure type. */
482 ret = make_node (RECORD_TYPE);
483 for (j = 0; j < loccnt; j++)
485 gcc_checking_assert (i < 2);
486 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
487 ubsan_source_location_type ());
488 DECL_CONTEXT (fields[i]) = ret;
489 if (i)
490 DECL_CHAIN (fields[i - 1]) = fields[i];
491 i++;
494 va_start (args, ploc);
495 for (t = va_arg (args, tree); t != NULL_TREE;
496 i++, t = va_arg (args, tree))
498 gcc_checking_assert (i < 4);
499 /* Save the tree arguments for later use. */
500 vec_safe_push (saved_args, t);
501 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
502 td_type);
503 DECL_CONTEXT (fields[i]) = ret;
504 if (i)
505 DECL_CHAIN (fields[i - 1]) = fields[i];
508 for (t = va_arg (args, tree); t != NULL_TREE;
509 i++, t = va_arg (args, tree))
511 gcc_checking_assert (i < 6);
512 /* Save the tree arguments for later use. */
513 vec_safe_push (saved_args, t);
514 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
515 TREE_TYPE (t));
516 DECL_CONTEXT (fields[i]) = ret;
517 if (i)
518 DECL_CHAIN (fields[i - 1]) = fields[i];
520 va_end (args);
522 TYPE_FIELDS (ret) = fields[0];
523 TYPE_NAME (ret) = get_identifier (name);
524 layout_type (ret);
526 /* Now, fill in the type. */
527 char tmp_name[32];
528 static unsigned int ubsan_var_id_num;
529 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
530 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
531 ret);
532 TREE_STATIC (var) = 1;
533 TREE_PUBLIC (var) = 0;
534 DECL_ARTIFICIAL (var) = 1;
535 DECL_IGNORED_P (var) = 1;
536 DECL_EXTERNAL (var) = 0;
538 vec<constructor_elt, va_gc> *v;
539 vec_alloc (v, i);
540 tree ctor = build_constructor (ret, v);
542 /* If desirable, set the __ubsan_source_location element. */
543 for (j = 0; j < loccnt; j++)
545 location_t loc = LOCATION_LOCUS (ploc[j]);
546 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
549 size_t nelts = vec_safe_length (saved_args);
550 for (i = 0; i < nelts; i++)
552 t = (*saved_args)[i];
553 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
556 TREE_CONSTANT (ctor) = 1;
557 TREE_STATIC (ctor) = 1;
558 DECL_INITIAL (var) = ctor;
559 varpool_node::finalize_decl (var);
561 return var;
564 /* Instrument the __builtin_unreachable call. We just call the libubsan
565 routine instead. */
567 tree
568 ubsan_instrument_unreachable (location_t loc)
570 if (flag_sanitize_undefined_trap_on_error)
571 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
573 initialize_sanitizer_builtins ();
574 tree data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc, NULL_TREE,
575 NULL_TREE);
576 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
577 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
580 /* Return true if T is a call to a libubsan routine. */
582 bool
583 is_ubsan_builtin_p (tree t)
585 return TREE_CODE (t) == FUNCTION_DECL
586 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
587 "__builtin___ubsan_", 18) == 0;
590 /* Expand the UBSAN_BOUNDS special builtin function. */
592 bool
593 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
595 gimple stmt = gsi_stmt (*gsi);
596 location_t loc = gimple_location (stmt);
597 gcc_assert (gimple_call_num_args (stmt) == 3);
599 /* Pick up the arguments of the UBSAN_BOUNDS call. */
600 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
601 tree index = gimple_call_arg (stmt, 1);
602 tree orig_index_type = TREE_TYPE (index);
603 tree bound = gimple_call_arg (stmt, 2);
605 gimple_stmt_iterator gsi_orig = *gsi;
607 /* Create condition "if (index > bound)". */
608 basic_block then_bb, fallthru_bb;
609 gimple_stmt_iterator cond_insert_point
610 = create_cond_insert_point (gsi, 0/*before_p*/, false, true,
611 &then_bb, &fallthru_bb);
612 index = fold_convert (TREE_TYPE (bound), index);
613 index = force_gimple_operand_gsi (&cond_insert_point, index,
614 true/*simple_p*/, NULL_TREE,
615 false/*before*/, GSI_NEW_STMT);
616 gimple g = gimple_build_cond (GT_EXPR, index, bound, NULL_TREE, NULL_TREE);
617 gimple_set_location (g, loc);
618 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
620 /* Generate __ubsan_handle_out_of_bounds call. */
621 *gsi = gsi_after_labels (then_bb);
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
627 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
628 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
629 ubsan_type_descriptor (orig_index_type),
630 NULL_TREE, NULL_TREE);
631 data = build_fold_addr_expr_loc (loc, data);
632 enum built_in_function bcode
633 = flag_sanitize_recover
634 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
635 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
636 tree fn = builtin_decl_explicit (bcode);
637 tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
638 true, NULL_TREE, true,
639 GSI_SAME_STMT);
640 g = gimple_build_call (fn, 2, data, val);
642 gimple_set_location (g, loc);
643 gsi_insert_before (gsi, g, GSI_SAME_STMT);
645 /* Get rid of the UBSAN_BOUNDS call from the IR. */
646 unlink_stmt_vdef (stmt);
647 gsi_remove (&gsi_orig, true);
649 /* Point GSI to next logical statement. */
650 *gsi = gsi_start_bb (fallthru_bb);
651 return true;
654 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
655 argument which is a constant, because the middle-end treats pointer
656 conversions as useless and therefore the type of the first argument
657 could be changed to any other pointer type. */
659 bool
660 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
662 gimple_stmt_iterator gsi = *gsip;
663 gimple stmt = gsi_stmt (gsi);
664 location_t loc = gimple_location (stmt);
665 gcc_assert (gimple_call_num_args (stmt) == 3);
666 tree ptr = gimple_call_arg (stmt, 0);
667 tree ckind = gimple_call_arg (stmt, 1);
668 tree align = gimple_call_arg (stmt, 2);
669 tree check_align = NULL_TREE;
670 bool check_null;
672 basic_block cur_bb = gsi_bb (gsi);
674 gimple g;
675 if (!integer_zerop (align))
677 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
678 if (compare_tree_int (align, ptralign) == 1)
680 check_align = make_ssa_name (pointer_sized_int_node, NULL);
681 g = gimple_build_assign_with_ops (NOP_EXPR, check_align,
682 ptr, NULL_TREE);
683 gimple_set_location (g, loc);
684 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
687 check_null = (flag_sanitize & SANITIZE_NULL) != 0;
689 if (check_align == NULL_TREE && !check_null)
691 gsi_remove (gsip, true);
692 /* Unlink the UBSAN_NULLs vops before replacing it. */
693 unlink_stmt_vdef (stmt);
694 return true;
697 /* Split the original block holding the pointer dereference. */
698 edge e = split_block (cur_bb, stmt);
700 /* Get a hold on the 'condition block', the 'then block' and the
701 'else block'. */
702 basic_block cond_bb = e->src;
703 basic_block fallthru_bb = e->dest;
704 basic_block then_bb = create_empty_bb (cond_bb);
705 add_bb_to_loop (then_bb, cond_bb->loop_father);
706 loops_state_set (LOOPS_NEED_FIXUP);
708 /* Make an edge coming from the 'cond block' into the 'then block';
709 this edge is unlikely taken, so set up the probability accordingly. */
710 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
711 e->probability = PROB_VERY_UNLIKELY;
713 /* Connect 'then block' with the 'else block'. This is needed
714 as the ubsan routines we call in the 'then block' are not noreturn.
715 The 'then block' only has one outcoming edge. */
716 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
718 /* Set up the fallthrough basic block. */
719 e = find_edge (cond_bb, fallthru_bb);
720 e->flags = EDGE_FALSE_VALUE;
721 e->count = cond_bb->count;
722 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
724 /* Update dominance info for the newly created then_bb; note that
725 fallthru_bb's dominance info has already been updated by
726 split_block. */
727 if (dom_info_available_p (CDI_DOMINATORS))
728 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
730 /* Put the ubsan builtin call into the newly created BB. */
731 if (flag_sanitize_undefined_trap_on_error)
732 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
733 else
735 enum built_in_function bcode
736 = flag_sanitize_recover
737 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
738 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
739 tree fn = builtin_decl_implicit (bcode);
740 tree data
741 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
742 ubsan_type_descriptor (TREE_TYPE (ckind),
743 UBSAN_PRINT_POINTER),
744 NULL_TREE,
745 align,
746 fold_convert (unsigned_char_type_node, ckind),
747 NULL_TREE);
748 data = build_fold_addr_expr_loc (loc, data);
749 g = gimple_build_call (fn, 2, data,
750 check_align ? check_align
751 : build_zero_cst (pointer_sized_int_node));
753 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
754 gimple_set_location (g, loc);
755 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
757 /* Unlink the UBSAN_NULLs vops before replacing it. */
758 unlink_stmt_vdef (stmt);
760 if (check_null)
762 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
763 NULL_TREE, NULL_TREE);
764 gimple_set_location (g, loc);
766 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
767 gsi_replace (&gsi, g, false);
770 if (check_align)
772 if (check_null)
774 /* Split the block with the condition again. */
775 e = split_block (cond_bb, stmt);
776 basic_block cond1_bb = e->src;
777 basic_block cond2_bb = e->dest;
779 /* Make an edge coming from the 'cond1 block' into the 'then block';
780 this edge is unlikely taken, so set up the probability
781 accordingly. */
782 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
783 e->probability = PROB_VERY_UNLIKELY;
785 /* Set up the fallthrough basic block. */
786 e = find_edge (cond1_bb, cond2_bb);
787 e->flags = EDGE_FALSE_VALUE;
788 e->count = cond1_bb->count;
789 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
791 /* Update dominance info. */
792 if (dom_info_available_p (CDI_DOMINATORS))
794 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
795 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
798 gsi2 = gsi_start_bb (cond2_bb);
801 tree mask = build_int_cst (pointer_sized_int_node,
802 tree_to_uhwi (align) - 1);
803 g = gimple_build_assign_with_ops (BIT_AND_EXPR,
804 make_ssa_name (pointer_sized_int_node,
805 NULL),
806 check_align, mask);
807 gimple_set_location (g, loc);
808 if (check_null)
809 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
810 else
811 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
813 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
814 build_int_cst (pointer_sized_int_node, 0),
815 NULL_TREE, NULL_TREE);
816 gimple_set_location (g, loc);
817 if (check_null)
818 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
819 else
820 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
821 gsi_replace (&gsi, g, false);
823 return false;
826 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
827 whether the pointer is on the left hand side of the assignment. */
829 static void
830 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
831 bool is_lhs)
833 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
834 unsigned int align = 0;
835 if (flag_sanitize & SANITIZE_ALIGNMENT)
837 align = min_align_of_type (TREE_TYPE (base));
838 if (align <= 1)
839 align = 0;
841 if (align == 0 && (flag_sanitize & SANITIZE_NULL) == 0)
842 return;
843 tree t = TREE_OPERAND (base, 0);
844 if (!POINTER_TYPE_P (TREE_TYPE (t)))
845 return;
846 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && mem != base)
847 ikind = UBSAN_MEMBER_ACCESS;
848 tree kind = build_int_cst (TREE_TYPE (t), ikind);
849 tree alignt = build_int_cst (pointer_sized_int_node, align);
850 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
851 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
852 gsi_insert_before (iter, g, GSI_SAME_STMT);
855 /* Perform the pointer instrumentation. */
857 static void
858 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
860 gimple stmt = gsi_stmt (gsi);
861 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
862 tree base = get_base_address (t);
863 const enum tree_code code = TREE_CODE (base);
864 if (code == MEM_REF
865 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
866 instrument_mem_ref (t, base, &gsi, is_lhs);
869 /* Build an ubsan builtin call for the signed-integer-overflow
870 sanitization. CODE says what kind of builtin are we building,
871 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
872 are operands of the binary operation. */
874 tree
875 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
876 tree op0, tree op1)
878 if (flag_sanitize_undefined_trap_on_error)
879 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
881 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
882 ubsan_type_descriptor (lhstype), NULL_TREE,
883 NULL_TREE);
884 enum built_in_function fn_code;
886 switch (code)
888 case PLUS_EXPR:
889 fn_code = flag_sanitize_recover
890 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
891 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
892 break;
893 case MINUS_EXPR:
894 fn_code = flag_sanitize_recover
895 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
896 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
897 break;
898 case MULT_EXPR:
899 fn_code = flag_sanitize_recover
900 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
901 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
902 break;
903 case NEGATE_EXPR:
904 fn_code = flag_sanitize_recover
905 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
906 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
907 break;
908 default:
909 gcc_unreachable ();
911 tree fn = builtin_decl_explicit (fn_code);
912 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
913 build_fold_addr_expr_loc (loc, data),
914 ubsan_encode_value (op0, true),
915 op1 ? ubsan_encode_value (op1, true)
916 : NULL_TREE);
919 /* Perform the signed integer instrumentation. GSI is the iterator
920 pointing at statement we are trying to instrument. */
922 static void
923 instrument_si_overflow (gimple_stmt_iterator gsi)
925 gimple stmt = gsi_stmt (gsi);
926 tree_code code = gimple_assign_rhs_code (stmt);
927 tree lhs = gimple_assign_lhs (stmt);
928 tree lhstype = TREE_TYPE (lhs);
929 tree a, b;
930 gimple g;
932 /* If this is not a signed operation, don't instrument anything here.
933 Also punt on bit-fields. */
934 if (!INTEGRAL_TYPE_P (lhstype)
935 || TYPE_OVERFLOW_WRAPS (lhstype)
936 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
937 return;
939 switch (code)
941 case MINUS_EXPR:
942 case PLUS_EXPR:
943 case MULT_EXPR:
944 /* Transform
945 i = u {+,-,*} 5;
946 into
947 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
948 a = gimple_assign_rhs1 (stmt);
949 b = gimple_assign_rhs2 (stmt);
950 g = gimple_build_call_internal (code == PLUS_EXPR
951 ? IFN_UBSAN_CHECK_ADD
952 : code == MINUS_EXPR
953 ? IFN_UBSAN_CHECK_SUB
954 : IFN_UBSAN_CHECK_MUL, 2, a, b);
955 gimple_call_set_lhs (g, lhs);
956 gsi_replace (&gsi, g, false);
957 break;
958 case NEGATE_EXPR:
959 /* Represent i = -u;
961 i = UBSAN_CHECK_SUB (0, u); */
962 a = build_int_cst (lhstype, 0);
963 b = gimple_assign_rhs1 (stmt);
964 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
965 gimple_call_set_lhs (g, lhs);
966 gsi_replace (&gsi, g, false);
967 break;
968 case ABS_EXPR:
969 /* Transform i = ABS_EXPR<u>;
970 into
971 _N = UBSAN_CHECK_SUB (0, u);
972 i = ABS_EXPR<_N>; */
973 a = build_int_cst (lhstype, 0);
974 b = gimple_assign_rhs1 (stmt);
975 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
976 a = make_ssa_name (lhstype, NULL);
977 gimple_call_set_lhs (g, a);
978 gimple_set_location (g, gimple_location (stmt));
979 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
980 gimple_assign_set_rhs1 (stmt, a);
981 update_stmt (stmt);
982 break;
983 default:
984 break;
988 /* Instrument loads from (non-bitfield) bool and C++ enum values
989 to check if the memory value is outside of the range of the valid
990 type values. */
992 static void
993 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
995 gimple stmt = gsi_stmt (*gsi);
996 tree rhs = gimple_assign_rhs1 (stmt);
997 tree type = TREE_TYPE (rhs);
998 tree minv = NULL_TREE, maxv = NULL_TREE;
1000 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
1002 minv = boolean_false_node;
1003 maxv = boolean_true_node;
1005 else if (TREE_CODE (type) == ENUMERAL_TYPE
1006 && (flag_sanitize & SANITIZE_ENUM)
1007 && TREE_TYPE (type) != NULL_TREE
1008 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1009 && (TYPE_PRECISION (TREE_TYPE (type))
1010 < GET_MODE_PRECISION (TYPE_MODE (type))))
1012 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1013 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1015 else
1016 return;
1018 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
1019 HOST_WIDE_INT bitsize, bitpos;
1020 tree offset;
1021 enum machine_mode mode;
1022 int volatilep = 0, unsignedp = 0;
1023 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1024 &unsignedp, &volatilep, false);
1025 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1027 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
1028 || (bitpos % modebitsize) != 0
1029 || bitsize != modebitsize
1030 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
1031 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1032 return;
1034 location_t loc = gimple_location (stmt);
1035 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1036 tree atype = reference_alias_ptr_type (rhs);
1037 gimple g = gimple_build_assign (make_ssa_name (ptype, NULL),
1038 build_fold_addr_expr (rhs));
1039 gimple_set_location (g, loc);
1040 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1041 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1042 build_int_cst (atype, 0));
1043 tree urhs = make_ssa_name (utype, NULL);
1044 g = gimple_build_assign (urhs, mem);
1045 gimple_set_location (g, loc);
1046 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1047 minv = fold_convert (utype, minv);
1048 maxv = fold_convert (utype, maxv);
1049 if (!integer_zerop (minv))
1051 g = gimple_build_assign_with_ops (MINUS_EXPR,
1052 make_ssa_name (utype, NULL),
1053 urhs, minv);
1054 gimple_set_location (g, loc);
1055 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1058 gimple_stmt_iterator gsi2 = *gsi;
1059 basic_block then_bb, fallthru_bb;
1060 *gsi = create_cond_insert_point (gsi, true, false, true,
1061 &then_bb, &fallthru_bb);
1062 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1063 int_const_binop (MINUS_EXPR, maxv, minv),
1064 NULL_TREE, NULL_TREE);
1065 gimple_set_location (g, loc);
1066 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1068 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
1069 update_stmt (stmt);
1071 gsi2 = gsi_after_labels (then_bb);
1072 if (flag_sanitize_undefined_trap_on_error)
1073 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1074 else
1076 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1077 ubsan_type_descriptor (type), NULL_TREE,
1078 NULL_TREE);
1079 data = build_fold_addr_expr_loc (loc, data);
1080 enum built_in_function bcode
1081 = flag_sanitize_recover
1082 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1083 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1084 tree fn = builtin_decl_explicit (bcode);
1086 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
1087 true, NULL_TREE, true,
1088 GSI_SAME_STMT);
1089 g = gimple_build_call (fn, 2, data, val);
1091 gimple_set_location (g, loc);
1092 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1093 *gsi = gsi_for_stmt (stmt);
1096 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1097 destination, EXPR is floating-point expression. */
1099 tree
1100 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1102 tree expr_type = TREE_TYPE (expr);
1103 tree t, tt, fn, min, max;
1104 enum machine_mode mode = TYPE_MODE (expr_type);
1105 int prec = TYPE_PRECISION (type);
1106 bool uns_p = TYPE_UNSIGNED (type);
1108 /* Float to integer conversion first truncates toward zero, so
1109 even signed char c = 127.875f; is not problematic.
1110 Therefore, we should complain only if EXPR is unordered or smaller
1111 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1112 TYPE_MAX_VALUE + 1.0. */
1113 if (REAL_MODE_FORMAT (mode)->b == 2)
1115 /* For maximum, TYPE_MAX_VALUE might not be representable
1116 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1117 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1118 either representable or infinity. */
1119 REAL_VALUE_TYPE maxval = dconst1;
1120 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1121 real_convert (&maxval, mode, &maxval);
1122 max = build_real (expr_type, maxval);
1124 /* For unsigned, assume -1.0 is always representable. */
1125 if (uns_p)
1126 min = build_minus_one_cst (expr_type);
1127 else
1129 /* TYPE_MIN_VALUE is generally representable (or -inf),
1130 but TYPE_MIN_VALUE - 1.0 might not be. */
1131 REAL_VALUE_TYPE minval = dconstm1, minval2;
1132 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1133 real_convert (&minval, mode, &minval);
1134 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1135 real_convert (&minval2, mode, &minval2);
1136 if (real_compare (EQ_EXPR, &minval, &minval2)
1137 && !real_isinf (&minval))
1139 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1140 rounds to TYPE_MIN_VALUE, we need to subtract
1141 more. As REAL_MODE_FORMAT (mode)->p is the number
1142 of base digits, we want to subtract a number that
1143 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1144 times smaller than minval. */
1145 minval2 = dconst1;
1146 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1147 SET_REAL_EXP (&minval2,
1148 REAL_EXP (&minval2) + prec - 1
1149 - REAL_MODE_FORMAT (mode)->p + 1);
1150 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1151 real_convert (&minval2, mode, &minval2);
1153 min = build_real (expr_type, minval2);
1156 else if (REAL_MODE_FORMAT (mode)->b == 10)
1158 /* For _Decimal128 up to 34 decimal digits, - sign,
1159 dot, e, exponent. */
1160 char buf[64];
1161 mpfr_t m;
1162 int p = REAL_MODE_FORMAT (mode)->p;
1163 REAL_VALUE_TYPE maxval, minval;
1165 /* Use mpfr_snprintf rounding to compute the smallest
1166 representable decimal number greater or equal than
1167 1 << (prec - !uns_p). */
1168 mpfr_init2 (m, prec + 2);
1169 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
1170 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
1171 decimal_real_from_string (&maxval, buf);
1172 max = build_real (expr_type, maxval);
1174 /* For unsigned, assume -1.0 is always representable. */
1175 if (uns_p)
1176 min = build_minus_one_cst (expr_type);
1177 else
1179 /* Use mpfr_snprintf rounding to compute the largest
1180 representable decimal number less or equal than
1181 (-1 << (prec - 1)) - 1. */
1182 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
1183 mpfr_sub_ui (m, m, 1, GMP_RNDN);
1184 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
1185 decimal_real_from_string (&minval, buf);
1186 min = build_real (expr_type, minval);
1188 mpfr_clear (m);
1190 else
1191 return NULL_TREE;
1193 if (flag_sanitize_undefined_trap_on_error)
1194 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1195 else
1197 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1198 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
1199 NULL, ubsan_type_descriptor (expr_type),
1200 ubsan_type_descriptor (type), NULL_TREE,
1201 NULL_TREE);
1202 enum built_in_function bcode
1203 = flag_sanitize_recover
1204 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1205 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1206 fn = builtin_decl_explicit (bcode);
1207 fn = build_call_expr_loc (loc, fn, 2,
1208 build_fold_addr_expr_loc (loc, data),
1209 ubsan_encode_value (expr, false));
1212 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1213 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1214 return fold_build3 (COND_EXPR, void_type_node,
1215 fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt),
1216 fn, integer_zero_node);
1219 /* Instrument values passed to function arguments with nonnull attribute. */
1221 static void
1222 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
1224 gimple stmt = gsi_stmt (*gsi);
1225 location_t loc[2];
1226 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1227 while for nonnull sanitization it is clear. */
1228 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1229 flag_delete_null_pointer_checks = 1;
1230 loc[0] = gimple_location (stmt);
1231 loc[1] = UNKNOWN_LOCATION;
1232 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
1234 tree arg = gimple_call_arg (stmt, i);
1235 if (POINTER_TYPE_P (TREE_TYPE (arg))
1236 && infer_nonnull_range (stmt, arg, false, true))
1238 gimple g;
1239 if (!is_gimple_val (arg))
1241 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg), NULL),
1242 arg);
1243 gimple_set_location (g, loc[0]);
1244 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1245 arg = gimple_assign_lhs (g);
1248 basic_block then_bb, fallthru_bb;
1249 *gsi = create_cond_insert_point (gsi, true, false, true,
1250 &then_bb, &fallthru_bb);
1251 g = gimple_build_cond (EQ_EXPR, arg,
1252 build_zero_cst (TREE_TYPE (arg)),
1253 NULL_TREE, NULL_TREE);
1254 gimple_set_location (g, loc[0]);
1255 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1257 *gsi = gsi_after_labels (then_bb);
1258 if (flag_sanitize_undefined_trap_on_error)
1259 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1260 else
1262 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
1263 2, loc, NULL_TREE,
1264 build_int_cst (integer_type_node,
1265 i + 1),
1266 NULL_TREE);
1267 data = build_fold_addr_expr_loc (loc[0], data);
1268 enum built_in_function bcode
1269 = flag_sanitize_recover
1270 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1271 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
1272 tree fn = builtin_decl_explicit (bcode);
1274 g = gimple_build_call (fn, 1, data);
1276 gimple_set_location (g, loc[0]);
1277 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1279 *gsi = gsi_for_stmt (stmt);
1281 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1284 /* Instrument returns in functions with returns_nonnull attribute. */
1286 static void
1287 instrument_nonnull_return (gimple_stmt_iterator *gsi)
1289 gimple stmt = gsi_stmt (*gsi);
1290 location_t loc[2];
1291 tree arg = gimple_return_retval (stmt);
1292 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1293 while for nonnull return sanitization it is clear. */
1294 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
1295 flag_delete_null_pointer_checks = 1;
1296 loc[0] = gimple_location (stmt);
1297 loc[1] = UNKNOWN_LOCATION;
1298 if (arg
1299 && POINTER_TYPE_P (TREE_TYPE (arg))
1300 && is_gimple_val (arg)
1301 && infer_nonnull_range (stmt, arg, false, true))
1303 basic_block then_bb, fallthru_bb;
1304 *gsi = create_cond_insert_point (gsi, true, false, true,
1305 &then_bb, &fallthru_bb);
1306 gimple g = gimple_build_cond (EQ_EXPR, arg,
1307 build_zero_cst (TREE_TYPE (arg)),
1308 NULL_TREE, NULL_TREE);
1309 gimple_set_location (g, loc[0]);
1310 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1312 *gsi = gsi_after_labels (then_bb);
1313 if (flag_sanitize_undefined_trap_on_error)
1314 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1315 else
1317 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
1318 2, loc, NULL_TREE, NULL_TREE);
1319 data = build_fold_addr_expr_loc (loc[0], data);
1320 enum built_in_function bcode
1321 = flag_sanitize_recover
1322 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1323 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT;
1324 tree fn = builtin_decl_explicit (bcode);
1326 g = gimple_build_call (fn, 1, data);
1328 gimple_set_location (g, loc[0]);
1329 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1330 *gsi = gsi_for_stmt (stmt);
1332 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
1335 namespace {
1337 const pass_data pass_data_ubsan =
1339 GIMPLE_PASS, /* type */
1340 "ubsan", /* name */
1341 OPTGROUP_NONE, /* optinfo_flags */
1342 TV_TREE_UBSAN, /* tv_id */
1343 ( PROP_cfg | PROP_ssa ), /* properties_required */
1344 0, /* properties_provided */
1345 0, /* properties_destroyed */
1346 0, /* todo_flags_start */
1347 TODO_update_ssa, /* todo_flags_finish */
1350 class pass_ubsan : public gimple_opt_pass
1352 public:
1353 pass_ubsan (gcc::context *ctxt)
1354 : gimple_opt_pass (pass_data_ubsan, ctxt)
1357 /* opt_pass methods: */
1358 virtual bool gate (function *)
1360 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1361 | SANITIZE_BOOL | SANITIZE_ENUM
1362 | SANITIZE_ALIGNMENT
1363 | SANITIZE_NONNULL_ATTRIBUTE
1364 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1365 && current_function_decl != NULL_TREE
1366 && !lookup_attribute ("no_sanitize_undefined",
1367 DECL_ATTRIBUTES (current_function_decl));
1370 virtual unsigned int execute (function *);
1372 }; // class pass_ubsan
1374 unsigned int
1375 pass_ubsan::execute (function *fun)
1377 basic_block bb;
1378 gimple_stmt_iterator gsi;
1380 initialize_sanitizer_builtins ();
1382 FOR_EACH_BB_FN (bb, fun)
1384 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1386 gimple stmt = gsi_stmt (gsi);
1387 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1389 gsi_next (&gsi);
1390 continue;
1393 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1394 && is_gimple_assign (stmt))
1395 instrument_si_overflow (gsi);
1397 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1399 if (gimple_store_p (stmt))
1400 instrument_null (gsi, true);
1401 if (gimple_assign_load_p (stmt))
1402 instrument_null (gsi, false);
1405 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1406 && gimple_assign_load_p (stmt))
1408 instrument_bool_enum_load (&gsi);
1409 bb = gimple_bb (stmt);
1412 if ((flag_sanitize & SANITIZE_NONNULL_ATTRIBUTE)
1413 && is_gimple_call (stmt)
1414 && !gimple_call_internal_p (stmt))
1416 instrument_nonnull_arg (&gsi);
1417 bb = gimple_bb (stmt);
1420 if ((flag_sanitize & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
1421 && gimple_code (stmt) == GIMPLE_RETURN)
1423 instrument_nonnull_return (&gsi);
1424 bb = gimple_bb (stmt);
1427 gsi_next (&gsi);
1430 return 0;
1433 } // anon namespace
1435 gimple_opt_pass *
1436 make_pass_ubsan (gcc::context *ctxt)
1438 return new pass_ubsan (ctxt);
1441 #include "gt-ubsan.h"