ada: Fix minor glitch in finish_record_type
[official-gcc.git] / gcc / ubsan.cc
blob25726df8ce99474f2e0636a2a760a76bbf6f9c0b
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2023 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 "stringpool.h"
43 #include "attribs.h"
44 #include "asan.h"
45 #include "gimplify-me.h"
46 #include "dfp.h"
47 #include "builtins.h"
48 #include "tree-object-size.h"
49 #include "tree-cfg.h"
50 #include "gimple-fold.h"
51 #include "varasm.h"
52 #include "realmpfr.h"
53 #include "target.h"
54 #include "langhooks.h"
56 /* Map from a tree to a VAR_DECL tree. */
58 struct GTY((for_user)) tree_type_map {
59 struct tree_map_base type;
60 tree decl;
63 struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
65 static inline hashval_t
66 hash (tree_type_map *t)
68 return TYPE_UID (t->type.from);
71 static inline bool
72 equal (tree_type_map *a, tree_type_map *b)
74 return a->type.from == b->type.from;
77 static int
78 keep_cache_entry (tree_type_map *&m)
80 return ggc_marked_p (m->type.from);
84 static GTY ((cache))
85 hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
87 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
89 static tree
90 decl_for_type_lookup (tree type)
92 /* If the hash table is not initialized yet, create it now. */
93 if (decl_tree_for_type == NULL)
95 decl_tree_for_type
96 = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
97 /* That also means we don't have to bother with the lookup. */
98 return NULL_TREE;
101 struct tree_type_map *h, in;
102 in.type.from = type;
104 h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
105 return h ? h->decl : NULL_TREE;
108 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
110 static void
111 decl_for_type_insert (tree type, tree decl)
113 struct tree_type_map *h;
115 h = ggc_alloc<tree_type_map> ();
116 h->type.from = type;
117 h->decl = decl;
118 *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
121 /* Helper routine, which encodes a value in the pointer_sized_int_node.
122 Arguments with precision <= POINTER_SIZE are passed directly,
123 the rest is passed by reference. T is a value we are to encode.
124 PHASE determines when this function is called. */
126 tree
127 ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase)
129 tree type = TREE_TYPE (t);
130 if (TREE_CODE (type) == BITINT_TYPE)
132 if (TYPE_PRECISION (type) <= POINTER_SIZE)
134 type = pointer_sized_int_node;
135 t = fold_build1 (NOP_EXPR, type, t);
137 else
139 scalar_int_mode arith_mode
140 = (targetm.scalar_mode_supported_p (TImode) ? TImode : DImode);
141 if (TYPE_PRECISION (type) > GET_MODE_PRECISION (arith_mode))
142 return build_zero_cst (pointer_sized_int_node);
143 type
144 = build_nonstandard_integer_type (GET_MODE_PRECISION (arith_mode),
145 TYPE_UNSIGNED (type));
146 t = fold_build1 (NOP_EXPR, type, t);
149 scalar_mode mode = SCALAR_TYPE_MODE (type);
150 const unsigned int bitsize = GET_MODE_BITSIZE (mode);
151 if (bitsize <= POINTER_SIZE)
152 switch (TREE_CODE (type))
154 case BOOLEAN_TYPE:
155 case ENUMERAL_TYPE:
156 case INTEGER_TYPE:
157 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
158 case REAL_TYPE:
160 tree itype = build_nonstandard_integer_type (bitsize, true);
161 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
162 return fold_convert (pointer_sized_int_node, t);
164 default:
165 gcc_unreachable ();
167 else
169 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
171 /* The reason for this is that we don't want to pessimize
172 code by making vars unnecessarily addressable. */
173 tree var;
174 if (phase != UBSAN_ENCODE_VALUE_GENERIC)
176 var = create_tmp_var (type);
177 mark_addressable (var);
179 else
181 var = create_tmp_var_raw (type);
182 TREE_ADDRESSABLE (var) = 1;
183 DECL_CONTEXT (var) = current_function_decl;
185 if (phase == UBSAN_ENCODE_VALUE_RTL)
187 rtx mem = assign_stack_temp_for_type (mode, GET_MODE_SIZE (mode),
188 type);
189 SET_DECL_RTL (var, mem);
190 expand_assignment (var, t, false);
191 return build_fold_addr_expr (var);
193 if (phase != UBSAN_ENCODE_VALUE_GENERIC)
195 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
196 t = build_fold_addr_expr (var);
197 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
199 else
201 var = build4 (TARGET_EXPR, type, var, t, NULL_TREE, NULL_TREE);
202 return build_fold_addr_expr (var);
205 else
206 return build_fold_addr_expr (t);
210 /* Cached ubsan_get_type_descriptor_type () return value. */
211 static GTY(()) tree ubsan_type_descriptor_type;
213 /* Build
214 struct __ubsan_type_descriptor
216 unsigned short __typekind;
217 unsigned short __typeinfo;
218 char __typename[];
220 type. */
222 static tree
223 ubsan_get_type_descriptor_type (void)
225 static const char *field_names[3]
226 = { "__typekind", "__typeinfo", "__typename" };
227 tree fields[3], ret;
229 if (ubsan_type_descriptor_type)
230 return ubsan_type_descriptor_type;
232 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
233 tree flex_arr_type = build_array_type (char_type_node, itype);
235 ret = make_node (RECORD_TYPE);
236 for (int i = 0; i < 3; i++)
238 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
239 get_identifier (field_names[i]),
240 (i == 2) ? flex_arr_type
241 : short_unsigned_type_node);
242 DECL_CONTEXT (fields[i]) = ret;
243 if (i)
244 DECL_CHAIN (fields[i - 1]) = fields[i];
246 tree type_decl = build_decl (input_location, TYPE_DECL,
247 get_identifier ("__ubsan_type_descriptor"),
248 ret);
249 DECL_IGNORED_P (type_decl) = 1;
250 DECL_ARTIFICIAL (type_decl) = 1;
251 TYPE_FIELDS (ret) = fields[0];
252 TYPE_NAME (ret) = type_decl;
253 TYPE_STUB_DECL (ret) = type_decl;
254 TYPE_ARTIFICIAL (ret) = 1;
255 layout_type (ret);
256 ubsan_type_descriptor_type = ret;
257 return ret;
260 /* Cached ubsan_get_source_location_type () return value. */
261 static GTY(()) tree ubsan_source_location_type;
263 /* Build
264 struct __ubsan_source_location
266 const char *__filename;
267 unsigned int __line;
268 unsigned int __column;
270 type. */
272 tree
273 ubsan_get_source_location_type (void)
275 static const char *field_names[3]
276 = { "__filename", "__line", "__column" };
277 tree fields[3], ret;
278 if (ubsan_source_location_type)
279 return ubsan_source_location_type;
281 tree const_char_type = build_qualified_type (char_type_node,
282 TYPE_QUAL_CONST);
284 ret = make_node (RECORD_TYPE);
285 for (int i = 0; i < 3; i++)
287 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
288 get_identifier (field_names[i]),
289 (i == 0) ? build_pointer_type (const_char_type)
290 : unsigned_type_node);
291 DECL_CONTEXT (fields[i]) = ret;
292 if (i)
293 DECL_CHAIN (fields[i - 1]) = fields[i];
295 tree type_decl = build_decl (input_location, TYPE_DECL,
296 get_identifier ("__ubsan_source_location"),
297 ret);
298 DECL_IGNORED_P (type_decl) = 1;
299 DECL_ARTIFICIAL (type_decl) = 1;
300 TYPE_FIELDS (ret) = fields[0];
301 TYPE_NAME (ret) = type_decl;
302 TYPE_STUB_DECL (ret) = type_decl;
303 TYPE_ARTIFICIAL (ret) = 1;
304 layout_type (ret);
305 ubsan_source_location_type = ret;
306 return ret;
309 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
310 type with its fields filled from a location_t LOC. */
312 static tree
313 ubsan_source_location (location_t loc)
315 expanded_location xloc;
316 tree type = ubsan_get_source_location_type ();
318 xloc = expand_location (loc);
319 tree str;
320 if (xloc.file == NULL)
322 str = build_int_cst (ptr_type_node, 0);
323 xloc.line = 0;
324 xloc.column = 0;
326 else
328 /* Fill in the values from LOC. */
329 size_t len = strlen (xloc.file) + 1;
330 str = build_string (len, xloc.file);
331 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
332 TREE_READONLY (str) = 1;
333 TREE_STATIC (str) = 1;
334 str = build_fold_addr_expr (str);
336 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
337 build_int_cst (unsigned_type_node,
338 xloc.line), NULL_TREE,
339 build_int_cst (unsigned_type_node,
340 xloc.column));
341 TREE_CONSTANT (ctor) = 1;
342 TREE_STATIC (ctor) = 1;
344 return ctor;
347 /* This routine returns a magic number for TYPE. */
349 static unsigned short
350 get_ubsan_type_info_for_type (tree type)
352 if (SCALAR_FLOAT_TYPE_P (type))
353 return tree_to_uhwi (TYPE_SIZE (type));
354 else if (INTEGRAL_TYPE_P (type))
356 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
357 gcc_assert (prec != -1);
358 return (prec << 1) | !TYPE_UNSIGNED (type);
360 else
361 return 0;
364 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
365 ubsan_ids[1] for Lubsan_data labels. */
366 static GTY(()) unsigned int ubsan_ids[2];
368 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
369 descriptor. It first looks into the hash table; if not found,
370 create the VAR_DECL, put it into the hash table and return the
371 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
372 an enum controlling how we want to print the type. */
374 tree
375 ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
377 /* See through any typedefs. */
378 type = TYPE_MAIN_VARIANT (type);
379 tree type3 = type;
380 if (pstyle == UBSAN_PRINT_FORCE_INT)
382 /* Temporary hack for -fsanitize=shift with _BitInt(129) and more.
383 libubsan crashes if it is not TK_Integer type. */
384 if (TREE_CODE (type) == BITINT_TYPE)
386 scalar_int_mode arith_mode
387 = (targetm.scalar_mode_supported_p (TImode)
388 ? TImode : DImode);
389 if (TYPE_PRECISION (type) > GET_MODE_PRECISION (arith_mode))
390 type3 = build_qualified_type (type, TYPE_QUAL_CONST);
392 if (type3 == type)
393 pstyle = UBSAN_PRINT_NORMAL;
396 tree decl = decl_for_type_lookup (type3);
397 /* It is possible that some of the earlier created DECLs were found
398 unused, in that case they weren't emitted and varpool_node::get
399 returns NULL node on them. But now we really need them. Thus,
400 renew them here. */
401 if (decl != NULL_TREE && varpool_node::get (decl))
403 return build_fold_addr_expr (decl);
406 tree dtype = ubsan_get_type_descriptor_type ();
407 tree type2 = type;
408 const char *tname = NULL;
409 pretty_printer pretty_name;
410 unsigned char deref_depth = 0;
411 unsigned short tkind, tinfo;
412 char tname_bitint[sizeof ("unsigned _BitInt(2147483647)")];
414 /* Get the name of the type, or the name of the pointer type. */
415 if (pstyle == UBSAN_PRINT_POINTER)
417 gcc_assert (POINTER_TYPE_P (type));
418 type2 = TREE_TYPE (type);
420 /* Remove any '*' operators from TYPE. */
421 while (POINTER_TYPE_P (type2))
422 deref_depth++, type2 = TREE_TYPE (type2);
424 if (TREE_CODE (type2) == METHOD_TYPE)
425 type2 = TYPE_METHOD_BASETYPE (type2);
428 /* If an array, get its type. */
429 type2 = strip_array_types (type2);
431 if (pstyle == UBSAN_PRINT_ARRAY)
433 while (POINTER_TYPE_P (type2))
434 deref_depth++, type2 = TREE_TYPE (type2);
437 if (TYPE_NAME (type2) != NULL)
439 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
440 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
441 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
442 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
445 if (tname == NULL)
447 if (TREE_CODE (type2) == BITINT_TYPE)
449 snprintf (tname_bitint, sizeof (tname_bitint),
450 "%s_BitInt(%d)", TYPE_UNSIGNED (type2) ? "unsigned " : "",
451 TYPE_PRECISION (type2));
452 tname = tname_bitint;
454 else
455 /* We weren't able to determine the type name. */
456 tname = "<unknown>";
459 pp_quote (&pretty_name);
461 tree eltype = type;
462 if (pstyle == UBSAN_PRINT_POINTER)
464 pp_printf (&pretty_name, "%s%s%s%s%s%s%s",
465 TYPE_VOLATILE (type2) ? "volatile " : "",
466 TYPE_READONLY (type2) ? "const " : "",
467 TYPE_RESTRICT (type2) ? "restrict " : "",
468 TYPE_ATOMIC (type2) ? "_Atomic " : "",
469 TREE_CODE (type2) == RECORD_TYPE
470 ? "struct "
471 : TREE_CODE (type2) == UNION_TYPE
472 ? "union " : "", tname,
473 deref_depth == 0 ? "" : " ");
474 while (deref_depth-- > 0)
475 pp_star (&pretty_name);
477 else if (pstyle == UBSAN_PRINT_ARRAY)
479 /* Pretty print the array dimensions. */
480 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
481 tree t = type;
482 pp_string (&pretty_name, tname);
483 pp_space (&pretty_name);
484 while (deref_depth-- > 0)
485 pp_star (&pretty_name);
486 while (TREE_CODE (t) == ARRAY_TYPE)
488 pp_left_bracket (&pretty_name);
489 tree dom = TYPE_DOMAIN (t);
490 if (dom != NULL_TREE
491 && TYPE_MAX_VALUE (dom) != NULL_TREE
492 && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
494 unsigned HOST_WIDE_INT m;
495 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
496 && (m = tree_to_uhwi (TYPE_MAX_VALUE (dom))) + 1 != 0)
497 pp_unsigned_wide_integer (&pretty_name, m + 1);
498 else
499 pp_wide_int (&pretty_name,
500 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
501 TYPE_SIGN (TREE_TYPE (dom)));
503 else
504 /* ??? We can't determine the variable name; print VLA unspec. */
505 pp_star (&pretty_name);
506 pp_right_bracket (&pretty_name);
507 t = TREE_TYPE (t);
510 /* Save the tree with stripped types. */
511 eltype = t;
513 else
514 pp_string (&pretty_name, tname);
516 pp_quote (&pretty_name);
518 switch (TREE_CODE (eltype))
520 case BOOLEAN_TYPE:
521 case ENUMERAL_TYPE:
522 case INTEGER_TYPE:
523 tkind = 0x0000;
524 break;
525 case BITINT_TYPE:
527 /* FIXME: libubsan right now only supports _BitInts which
528 fit into DImode or TImode. */
529 scalar_int_mode arith_mode = (targetm.scalar_mode_supported_p (TImode)
530 ? TImode : DImode);
531 if (TYPE_PRECISION (eltype) <= GET_MODE_PRECISION (arith_mode))
532 tkind = 0x0000;
533 else
534 tkind = 0xffff;
536 break;
537 case REAL_TYPE:
538 /* FIXME: libubsan right now only supports float, double and
539 long double type formats. */
540 if (TYPE_MODE (eltype) == TYPE_MODE (float_type_node)
541 || TYPE_MODE (eltype) == TYPE_MODE (double_type_node)
542 || TYPE_MODE (eltype) == TYPE_MODE (long_double_type_node))
543 tkind = 0x0001;
544 else
545 tkind = 0xffff;
546 break;
547 default:
548 tkind = 0xffff;
549 break;
551 tinfo = tkind == 0xffff ? 0 : get_ubsan_type_info_for_type (eltype);
553 if (pstyle == UBSAN_PRINT_FORCE_INT)
555 tkind = 0x0000;
556 scalar_int_mode arith_mode = (targetm.scalar_mode_supported_p (TImode)
557 ? TImode : DImode);
558 tree t = lang_hooks.types.type_for_mode (arith_mode,
559 TYPE_UNSIGNED (eltype));
560 tinfo = get_ubsan_type_info_for_type (t);
563 /* Create a new VAR_DECL of type descriptor. */
564 const char *tmp = pp_formatted_text (&pretty_name);
565 size_t len = strlen (tmp) + 1;
566 tree str = build_string (len, tmp);
567 TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
568 TREE_READONLY (str) = 1;
569 TREE_STATIC (str) = 1;
571 char tmp_name[32];
572 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", ubsan_ids[0]++);
573 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
574 dtype);
575 TREE_STATIC (decl) = 1;
576 TREE_PUBLIC (decl) = 0;
577 DECL_ARTIFICIAL (decl) = 1;
578 DECL_IGNORED_P (decl) = 1;
579 DECL_EXTERNAL (decl) = 0;
580 DECL_SIZE (decl)
581 = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
582 DECL_SIZE_UNIT (decl)
583 = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
584 TYPE_SIZE_UNIT (TREE_TYPE (str)));
586 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
587 build_int_cst (short_unsigned_type_node,
588 tkind), NULL_TREE,
589 build_int_cst (short_unsigned_type_node,
590 tinfo), NULL_TREE, str);
591 TREE_CONSTANT (ctor) = 1;
592 TREE_STATIC (ctor) = 1;
593 DECL_INITIAL (decl) = ctor;
594 varpool_node::finalize_decl (decl);
596 /* Save the VAR_DECL into the hash table. */
597 decl_for_type_insert (type3, decl);
599 return build_fold_addr_expr (decl);
602 /* Create a structure for the ubsan library. NAME is a name of the new
603 structure. LOCCNT is number of locations, PLOC points to array of
604 locations. The arguments in ... are of __ubsan_type_descriptor type
605 and there are at most two of them, followed by NULL_TREE, followed
606 by optional extra arguments and another NULL_TREE. */
608 tree
609 ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
611 va_list args;
612 tree ret, t;
613 tree fields[6];
614 vec<tree, va_gc> *saved_args = NULL;
615 size_t i = 0;
616 int j;
618 /* It is possible that PCH zapped table with definitions of sanitizer
619 builtins. Reinitialize them if needed. */
620 initialize_sanitizer_builtins ();
622 /* Firstly, create a pointer to type descriptor type. */
623 tree td_type = ubsan_get_type_descriptor_type ();
624 td_type = build_pointer_type (td_type);
626 /* Create the structure type. */
627 ret = make_node (RECORD_TYPE);
628 for (j = 0; j < loccnt; j++)
630 gcc_checking_assert (i < 2);
631 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
632 ubsan_get_source_location_type ());
633 DECL_CONTEXT (fields[i]) = ret;
634 if (i)
635 DECL_CHAIN (fields[i - 1]) = fields[i];
636 i++;
639 va_start (args, ploc);
640 for (t = va_arg (args, tree); t != NULL_TREE;
641 i++, t = va_arg (args, tree))
643 gcc_checking_assert (i < 4);
644 /* Save the tree arguments for later use. */
645 vec_safe_push (saved_args, t);
646 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
647 td_type);
648 DECL_CONTEXT (fields[i]) = ret;
649 if (i)
650 DECL_CHAIN (fields[i - 1]) = fields[i];
653 for (t = va_arg (args, tree); t != NULL_TREE;
654 i++, t = va_arg (args, tree))
656 gcc_checking_assert (i < 6);
657 /* Save the tree arguments for later use. */
658 vec_safe_push (saved_args, t);
659 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
660 TREE_TYPE (t));
661 DECL_CONTEXT (fields[i]) = ret;
662 if (i)
663 DECL_CHAIN (fields[i - 1]) = fields[i];
665 va_end (args);
667 tree type_decl = build_decl (input_location, TYPE_DECL,
668 get_identifier (name), ret);
669 DECL_IGNORED_P (type_decl) = 1;
670 DECL_ARTIFICIAL (type_decl) = 1;
671 TYPE_FIELDS (ret) = fields[0];
672 TYPE_NAME (ret) = type_decl;
673 TYPE_STUB_DECL (ret) = type_decl;
674 TYPE_ARTIFICIAL (ret) = 1;
675 layout_type (ret);
677 /* Now, fill in the type. */
678 char tmp_name[32];
679 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_ids[1]++);
680 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
681 ret);
682 TREE_STATIC (var) = 1;
683 TREE_PUBLIC (var) = 0;
684 DECL_ARTIFICIAL (var) = 1;
685 DECL_IGNORED_P (var) = 1;
686 DECL_EXTERNAL (var) = 0;
688 vec<constructor_elt, va_gc> *v;
689 vec_alloc (v, i);
690 tree ctor = build_constructor (ret, v);
692 /* If desirable, set the __ubsan_source_location element. */
693 for (j = 0; j < loccnt; j++)
695 location_t loc = LOCATION_LOCUS (ploc[j]);
696 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
699 size_t nelts = vec_safe_length (saved_args);
700 for (i = 0; i < nelts; i++)
702 t = (*saved_args)[i];
703 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
706 TREE_CONSTANT (ctor) = 1;
707 TREE_STATIC (ctor) = 1;
708 DECL_INITIAL (var) = ctor;
709 varpool_node::finalize_decl (var);
711 return var;
714 /* Shared between *build_builtin_unreachable. */
716 tree
717 sanitize_unreachable_fn (tree *data, location_t loc)
719 tree fn = NULL_TREE;
720 bool san = sanitize_flags_p (SANITIZE_UNREACHABLE);
721 if (san
722 ? (flag_sanitize_trap & SANITIZE_UNREACHABLE)
723 : flag_unreachable_traps)
725 fn = builtin_decl_explicit (BUILT_IN_UNREACHABLE_TRAP);
726 *data = NULL_TREE;
728 else if (san)
730 /* Call ubsan_create_data first as it initializes SANITIZER built-ins. */
731 *data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
732 NULL_TREE, NULL_TREE);
733 fn = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
734 *data = build_fold_addr_expr_loc (loc, *data);
736 else
738 fn = builtin_decl_explicit (BUILT_IN_UNREACHABLE);
739 *data = NULL_TREE;
741 return fn;
744 /* Rewrite a gcall to __builtin_unreachable for -fsanitize=unreachable. Called
745 by the sanopt pass. */
747 bool
748 ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
750 location_t loc = gimple_location (gsi_stmt (*gsi));
751 gimple *g = gimple_build_builtin_unreachable (loc);
752 gsi_replace (gsi, g, false);
753 return false;
756 /* Return true if T is a call to a libubsan routine. */
758 bool
759 is_ubsan_builtin_p (tree t)
761 return TREE_CODE (t) == FUNCTION_DECL
762 && fndecl_built_in_p (t, BUILT_IN_NORMAL)
763 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
764 "__builtin___ubsan_", 18) == 0;
767 /* Create a callgraph edge for statement STMT. */
769 static void
770 ubsan_create_edge (gimple *stmt)
772 gcall *call_stmt = dyn_cast <gcall *> (stmt);
773 basic_block bb = gimple_bb (stmt);
774 cgraph_node *node = cgraph_node::get (current_function_decl);
775 tree decl = gimple_call_fndecl (call_stmt);
776 if (decl)
777 node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count);
780 /* Expand the UBSAN_BOUNDS special builtin function. */
782 bool
783 ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
785 gimple *stmt = gsi_stmt (*gsi);
786 location_t loc = gimple_location (stmt);
787 gcc_assert (gimple_call_num_args (stmt) == 3);
789 /* Pick up the arguments of the UBSAN_BOUNDS call. */
790 tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
791 tree index = gimple_call_arg (stmt, 1);
792 tree orig_index = index;
793 tree bound = gimple_call_arg (stmt, 2);
795 gimple_stmt_iterator gsi_orig = *gsi;
797 /* Create condition "if (index >= bound)". */
798 basic_block then_bb, fallthru_bb;
799 gimple_stmt_iterator cond_insert_point
800 = create_cond_insert_point (gsi, false, false, true,
801 &then_bb, &fallthru_bb);
802 index = fold_convert (TREE_TYPE (bound), index);
803 index = force_gimple_operand_gsi (&cond_insert_point, index,
804 true, NULL_TREE,
805 false, GSI_NEW_STMT);
806 gimple *g = gimple_build_cond (GE_EXPR, index, bound, NULL_TREE, NULL_TREE);
807 gimple_set_location (g, loc);
808 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
810 /* Generate __ubsan_handle_out_of_bounds call. */
811 *gsi = gsi_after_labels (then_bb);
812 if (flag_sanitize_trap & SANITIZE_BOUNDS)
813 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
814 else
816 tree data
817 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
818 ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
819 ubsan_type_descriptor (TREE_TYPE (orig_index)),
820 NULL_TREE, NULL_TREE);
821 data = build_fold_addr_expr_loc (loc, data);
822 enum built_in_function bcode
823 = (flag_sanitize_recover & SANITIZE_BOUNDS)
824 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
825 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
826 tree fn = builtin_decl_explicit (bcode);
827 tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE);
828 val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true,
829 GSI_SAME_STMT);
830 g = gimple_build_call (fn, 2, data, val);
832 gimple_set_location (g, loc);
833 gsi_insert_before (gsi, g, GSI_SAME_STMT);
835 /* Get rid of the UBSAN_BOUNDS call from the IR. */
836 unlink_stmt_vdef (stmt);
837 gsi_remove (&gsi_orig, true);
839 /* Point GSI to next logical statement. */
840 *gsi = gsi_start_bb (fallthru_bb);
841 return true;
844 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
845 argument which is a constant, because the middle-end treats pointer
846 conversions as useless and therefore the type of the first argument
847 could be changed to any other pointer type. */
849 bool
850 ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
852 gimple_stmt_iterator gsi = *gsip;
853 gimple *stmt = gsi_stmt (gsi);
854 location_t loc = gimple_location (stmt);
855 gcc_assert (gimple_call_num_args (stmt) == 3);
856 tree ptr = gimple_call_arg (stmt, 0);
857 tree ckind = gimple_call_arg (stmt, 1);
858 tree align = gimple_call_arg (stmt, 2);
859 tree check_align = NULL_TREE;
860 bool check_null;
862 basic_block cur_bb = gsi_bb (gsi);
864 gimple *g;
865 if (!integer_zerop (align))
867 unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
868 if (compare_tree_int (align, ptralign) == 1)
870 check_align = make_ssa_name (pointer_sized_int_node);
871 g = gimple_build_assign (check_align, NOP_EXPR, ptr);
872 gimple_set_location (g, loc);
873 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
876 check_null = sanitize_flags_p (SANITIZE_NULL);
878 if (check_align == NULL_TREE && !check_null)
880 gsi_remove (gsip, true);
881 /* Unlink the UBSAN_NULLs vops before replacing it. */
882 unlink_stmt_vdef (stmt);
883 return true;
886 /* Split the original block holding the pointer dereference. */
887 edge e = split_block (cur_bb, stmt);
889 /* Get a hold on the 'condition block', the 'then block' and the
890 'else block'. */
891 basic_block cond_bb = e->src;
892 basic_block fallthru_bb = e->dest;
893 basic_block then_bb = create_empty_bb (cond_bb);
894 add_bb_to_loop (then_bb, cond_bb->loop_father);
895 loops_state_set (LOOPS_NEED_FIXUP);
897 /* Make an edge coming from the 'cond block' into the 'then block';
898 this edge is unlikely taken, so set up the probability accordingly. */
899 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
900 e->probability = profile_probability::very_unlikely ();
901 then_bb->count = e->count ();
903 /* Connect 'then block' with the 'else block'. This is needed
904 as the ubsan routines we call in the 'then block' are not noreturn.
905 The 'then block' only has one outcoming edge. */
906 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
908 /* Set up the fallthrough basic block. */
909 e = find_edge (cond_bb, fallthru_bb);
910 e->flags = EDGE_FALSE_VALUE;
911 e->probability = profile_probability::very_likely ();
913 /* Update dominance info for the newly created then_bb; note that
914 fallthru_bb's dominance info has already been updated by
915 split_block. */
916 if (dom_info_available_p (CDI_DOMINATORS))
917 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
919 /* Put the ubsan builtin call into the newly created BB. */
920 if (flag_sanitize_trap & ((check_align ? SANITIZE_ALIGNMENT + 0 : 0)
921 | (check_null ? SANITIZE_NULL + 0 : 0)))
922 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
923 else
925 enum built_in_function bcode
926 = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT + 0 : 0)
927 | (check_null ? SANITIZE_NULL + 0 : 0)))
928 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1
929 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_ABORT;
930 tree fn = builtin_decl_implicit (bcode);
931 int align_log = tree_log2 (align);
932 tree data
933 = ubsan_create_data ("__ubsan_null_data", 1, &loc,
934 ubsan_type_descriptor (TREE_TYPE (ckind),
935 UBSAN_PRINT_POINTER),
936 NULL_TREE,
937 build_int_cst (unsigned_char_type_node,
938 MAX (align_log, 0)),
939 fold_convert (unsigned_char_type_node, ckind),
940 NULL_TREE);
941 data = build_fold_addr_expr_loc (loc, data);
942 g = gimple_build_call (fn, 2, data,
943 check_align ? check_align
944 : build_zero_cst (pointer_sized_int_node));
946 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
947 gimple_set_location (g, loc);
948 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
950 /* Unlink the UBSAN_NULLs vops before replacing it. */
951 unlink_stmt_vdef (stmt);
953 if (check_null)
955 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
956 NULL_TREE, NULL_TREE);
957 gimple_set_location (g, loc);
959 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
960 gsi_replace (&gsi, g, false);
961 stmt = g;
964 if (check_align)
966 if (check_null)
968 /* Split the block with the condition again. */
969 e = split_block (cond_bb, stmt);
970 basic_block cond1_bb = e->src;
971 basic_block cond2_bb = e->dest;
973 /* Make an edge coming from the 'cond1 block' into the 'then block';
974 this edge is unlikely taken, so set up the probability
975 accordingly. */
976 e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
977 e->probability = profile_probability::very_unlikely ();
979 /* Set up the fallthrough basic block. */
980 e = find_edge (cond1_bb, cond2_bb);
981 e->flags = EDGE_FALSE_VALUE;
982 e->probability = profile_probability::very_likely ();
984 /* Update dominance info. */
985 if (dom_info_available_p (CDI_DOMINATORS))
987 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
988 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
991 gsi2 = gsi_start_bb (cond2_bb);
994 tree mask = build_int_cst (pointer_sized_int_node,
995 tree_to_uhwi (align) - 1);
996 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
997 BIT_AND_EXPR, check_align, mask);
998 gimple_set_location (g, loc);
999 if (check_null)
1000 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1001 else
1002 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1004 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
1005 build_int_cst (pointer_sized_int_node, 0),
1006 NULL_TREE, NULL_TREE);
1007 gimple_set_location (g, loc);
1008 if (check_null)
1009 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1010 else
1011 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
1012 gsi_replace (&gsi, g, false);
1014 return false;
1017 #define OBJSZ_MAX_OFFSET (1024 * 16)
1019 /* Expand UBSAN_OBJECT_SIZE internal call. */
1021 bool
1022 ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
1024 gimple *stmt = gsi_stmt (*gsi);
1025 location_t loc = gimple_location (stmt);
1026 gcc_assert (gimple_call_num_args (stmt) == 4);
1028 tree ptr = gimple_call_arg (stmt, 0);
1029 tree offset = gimple_call_arg (stmt, 1);
1030 tree size = gimple_call_arg (stmt, 2);
1031 tree ckind = gimple_call_arg (stmt, 3);
1032 gimple_stmt_iterator gsi_orig = *gsi;
1033 gimple *g;
1035 /* See if we can discard the check. */
1036 if (TREE_CODE (size) == INTEGER_CST
1037 && integer_all_onesp (size))
1038 /* Yes, __builtin_object_size couldn't determine the
1039 object size. */;
1040 else if (TREE_CODE (offset) == INTEGER_CST
1041 && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
1042 && wi::to_widest (offset) <= -1)
1043 /* The offset is in range [-16K, -1]. */;
1044 else
1046 /* if (offset > objsize) */
1047 basic_block then_bb, fallthru_bb;
1048 gimple_stmt_iterator cond_insert_point
1049 = create_cond_insert_point (gsi, false, false, true,
1050 &then_bb, &fallthru_bb);
1051 g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
1052 gimple_set_location (g, loc);
1053 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1055 /* If the offset is small enough, we don't need the second
1056 run-time check. */
1057 if (TREE_CODE (offset) == INTEGER_CST
1058 && wi::to_widest (offset) >= 0
1059 && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
1060 *gsi = gsi_after_labels (then_bb);
1061 else
1063 /* Don't issue run-time error if (ptr > ptr + offset). That
1064 may happen when computing a POINTER_PLUS_EXPR. */
1065 basic_block then2_bb, fallthru2_bb;
1067 gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
1068 cond_insert_point = create_cond_insert_point (&gsi2, false, false,
1069 true, &then2_bb,
1070 &fallthru2_bb);
1071 /* Convert the pointer to an integer type. */
1072 tree p = make_ssa_name (pointer_sized_int_node);
1073 g = gimple_build_assign (p, NOP_EXPR, ptr);
1074 gimple_set_location (g, loc);
1075 gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
1076 p = gimple_assign_lhs (g);
1077 /* Compute ptr + offset. */
1078 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1079 PLUS_EXPR, p, offset);
1080 gimple_set_location (g, loc);
1081 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1082 /* Now build the conditional and put it into the IR. */
1083 g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
1084 NULL_TREE, NULL_TREE);
1085 gimple_set_location (g, loc);
1086 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1087 *gsi = gsi_after_labels (then2_bb);
1090 /* Generate __ubsan_handle_type_mismatch call. */
1091 if (flag_sanitize_trap & SANITIZE_OBJECT_SIZE)
1092 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1093 else
1095 tree data
1096 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
1097 ubsan_type_descriptor (TREE_TYPE (ptr),
1098 UBSAN_PRINT_POINTER),
1099 NULL_TREE,
1100 build_zero_cst (unsigned_char_type_node),
1101 ckind,
1102 NULL_TREE);
1103 data = build_fold_addr_expr_loc (loc, data);
1104 enum built_in_function bcode
1105 = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
1106 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1
1107 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_ABORT;
1108 tree p = make_ssa_name (pointer_sized_int_node);
1109 g = gimple_build_assign (p, NOP_EXPR, ptr);
1110 gimple_set_location (g, loc);
1111 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1112 g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
1114 gimple_set_location (g, loc);
1115 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1117 /* Point GSI to next logical statement. */
1118 *gsi = gsi_start_bb (fallthru_bb);
1120 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1121 unlink_stmt_vdef (stmt);
1122 gsi_remove (&gsi_orig, true);
1123 return true;
1126 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1127 unlink_stmt_vdef (stmt);
1128 gsi_remove (gsi, true);
1129 return true;
1132 /* Expand UBSAN_PTR internal call. */
1134 bool
1135 ubsan_expand_ptr_ifn (gimple_stmt_iterator *gsip)
1137 gimple_stmt_iterator gsi = *gsip;
1138 gimple *stmt = gsi_stmt (gsi);
1139 location_t loc = gimple_location (stmt);
1140 gcc_assert (gimple_call_num_args (stmt) == 2);
1141 tree ptr = gimple_call_arg (stmt, 0);
1142 tree off = gimple_call_arg (stmt, 1);
1144 if (integer_zerop (off))
1146 gsi_remove (gsip, true);
1147 unlink_stmt_vdef (stmt);
1148 return true;
1151 basic_block cur_bb = gsi_bb (gsi);
1152 tree ptrplusoff = make_ssa_name (pointer_sized_int_node);
1153 tree ptri = make_ssa_name (pointer_sized_int_node);
1154 int pos_neg = get_range_pos_neg (off);
1156 /* Split the original block holding the pointer dereference. */
1157 edge e = split_block (cur_bb, stmt);
1159 /* Get a hold on the 'condition block', the 'then block' and the
1160 'else block'. */
1161 basic_block cond_bb = e->src;
1162 basic_block fallthru_bb = e->dest;
1163 basic_block then_bb = create_empty_bb (cond_bb);
1164 basic_block cond_pos_bb = NULL, cond_neg_bb = NULL;
1165 add_bb_to_loop (then_bb, cond_bb->loop_father);
1166 loops_state_set (LOOPS_NEED_FIXUP);
1168 /* Set up the fallthrough basic block. */
1169 e->flags = EDGE_FALSE_VALUE;
1170 if (pos_neg != 3)
1172 e->probability = profile_probability::very_likely ();
1174 /* Connect 'then block' with the 'else block'. This is needed
1175 as the ubsan routines we call in the 'then block' are not noreturn.
1176 The 'then block' only has one outcoming edge. */
1177 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
1179 /* Make an edge coming from the 'cond block' into the 'then block';
1180 this edge is unlikely taken, so set up the probability
1181 accordingly. */
1182 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
1183 e->probability = profile_probability::very_unlikely ();
1184 then_bb->count = e->count ();
1186 else
1188 e->probability = profile_probability::even ();
1190 e = split_block (fallthru_bb, (gimple *) NULL);
1191 cond_neg_bb = e->src;
1192 fallthru_bb = e->dest;
1193 e->probability = profile_probability::very_likely ();
1194 e->flags = EDGE_FALSE_VALUE;
1196 e = make_edge (cond_neg_bb, then_bb, EDGE_TRUE_VALUE);
1197 e->probability = profile_probability::very_unlikely ();
1198 then_bb->count = e->count ();
1200 cond_pos_bb = create_empty_bb (cond_bb);
1201 add_bb_to_loop (cond_pos_bb, cond_bb->loop_father);
1203 e = make_edge (cond_bb, cond_pos_bb, EDGE_TRUE_VALUE);
1204 e->probability = profile_probability::even ();
1205 cond_pos_bb->count = e->count ();
1207 e = make_edge (cond_pos_bb, then_bb, EDGE_TRUE_VALUE);
1208 e->probability = profile_probability::very_unlikely ();
1210 e = make_edge (cond_pos_bb, fallthru_bb, EDGE_FALSE_VALUE);
1211 e->probability = profile_probability::very_likely ();
1213 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
1216 gimple *g = gimple_build_assign (ptri, NOP_EXPR, ptr);
1217 gimple_set_location (g, loc);
1218 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1219 g = gimple_build_assign (ptrplusoff, PLUS_EXPR, ptri, off);
1220 gimple_set_location (g, loc);
1221 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1223 /* Update dominance info for the newly created then_bb; note that
1224 fallthru_bb's dominance info has already been updated by
1225 split_block. */
1226 if (dom_info_available_p (CDI_DOMINATORS))
1228 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
1229 if (pos_neg == 3)
1231 set_immediate_dominator (CDI_DOMINATORS, cond_pos_bb, cond_bb);
1232 set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond_bb);
1236 /* Put the ubsan builtin call into the newly created BB. */
1237 if (flag_sanitize_trap & SANITIZE_POINTER_OVERFLOW)
1238 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
1239 else
1241 enum built_in_function bcode
1242 = (flag_sanitize_recover & SANITIZE_POINTER_OVERFLOW)
1243 ? BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW
1244 : BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW_ABORT;
1245 tree fn = builtin_decl_implicit (bcode);
1246 tree data
1247 = ubsan_create_data ("__ubsan_ptrovf_data", 1, &loc,
1248 NULL_TREE, NULL_TREE);
1249 data = build_fold_addr_expr_loc (loc, data);
1250 g = gimple_build_call (fn, 3, data, ptr, ptrplusoff);
1252 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
1253 gimple_set_location (g, loc);
1254 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1256 /* Unlink the UBSAN_PTRs vops before replacing it. */
1257 unlink_stmt_vdef (stmt);
1259 if (TREE_CODE (off) == INTEGER_CST)
1260 g = gimple_build_cond (wi::neg_p (wi::to_wide (off)) ? LT_EXPR : GE_EXPR,
1261 ptri, fold_build1 (NEGATE_EXPR, sizetype, off),
1262 NULL_TREE, NULL_TREE);
1263 else if (pos_neg != 3)
1264 g = gimple_build_cond (pos_neg == 1 ? LT_EXPR : GT_EXPR,
1265 ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1266 else
1268 gsi2 = gsi_start_bb (cond_pos_bb);
1269 g = gimple_build_cond (LT_EXPR, ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1270 gimple_set_location (g, loc);
1271 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1273 gsi2 = gsi_start_bb (cond_neg_bb);
1274 g = gimple_build_cond (GT_EXPR, ptrplusoff, ptri, NULL_TREE, NULL_TREE);
1275 gimple_set_location (g, loc);
1276 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
1278 tree t = gimple_build (&gsi, true, GSI_SAME_STMT,
1279 loc, NOP_EXPR, ssizetype, off);
1280 g = gimple_build_cond (GE_EXPR, t, ssize_int (0),
1281 NULL_TREE, NULL_TREE);
1283 gimple_set_location (g, loc);
1284 /* Replace the UBSAN_PTR with a GIMPLE_COND stmt. */
1285 gsi_replace (&gsi, g, false);
1286 return false;
1290 /* Cached __ubsan_vptr_type_cache decl. */
1291 static GTY(()) tree ubsan_vptr_type_cache_decl;
1293 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1294 argument which is a constant, because the middle-end treats pointer
1295 conversions as useless and therefore the type of the first argument
1296 could be changed to any other pointer type. */
1298 bool
1299 ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
1301 gimple_stmt_iterator gsi = *gsip;
1302 gimple *stmt = gsi_stmt (gsi);
1303 location_t loc = gimple_location (stmt);
1304 gcc_assert (gimple_call_num_args (stmt) == 5);
1305 tree op = gimple_call_arg (stmt, 0);
1306 tree vptr = gimple_call_arg (stmt, 1);
1307 tree str_hash = gimple_call_arg (stmt, 2);
1308 tree ti_decl_addr = gimple_call_arg (stmt, 3);
1309 tree ckind_tree = gimple_call_arg (stmt, 4);
1310 ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
1311 tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
1312 gimple *g;
1313 basic_block fallthru_bb = NULL;
1315 if (ckind == UBSAN_DOWNCAST_POINTER)
1317 /* Guard everything with if (op != NULL) { ... }. */
1318 basic_block then_bb;
1319 gimple_stmt_iterator cond_insert_point
1320 = create_cond_insert_point (gsip, false, false, true,
1321 &then_bb, &fallthru_bb);
1322 g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
1323 NULL_TREE, NULL_TREE);
1324 gimple_set_location (g, loc);
1325 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1326 *gsip = gsi_after_labels (then_bb);
1327 gsi_remove (&gsi, false);
1328 gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
1329 gsi = *gsip;
1332 tree htype = TREE_TYPE (str_hash);
1333 tree cst = wide_int_to_tree (htype,
1334 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1335 | 0xeb382d69, 64));
1336 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1337 vptr, str_hash);
1338 gimple_set_location (g, loc);
1339 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1340 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1341 gimple_assign_lhs (g), cst);
1342 gimple_set_location (g, loc);
1343 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1344 tree t1 = gimple_assign_lhs (g);
1345 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1346 t1, build_int_cst (integer_type_node, 47));
1347 gimple_set_location (g, loc);
1348 tree t2 = gimple_assign_lhs (g);
1349 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1350 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1351 vptr, t1);
1352 gimple_set_location (g, loc);
1353 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1354 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1355 t2, gimple_assign_lhs (g));
1356 gimple_set_location (g, loc);
1357 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1358 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1359 gimple_assign_lhs (g), cst);
1360 gimple_set_location (g, loc);
1361 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1362 tree t3 = gimple_assign_lhs (g);
1363 g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
1364 t3, build_int_cst (integer_type_node, 47));
1365 gimple_set_location (g, loc);
1366 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1367 g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
1368 t3, gimple_assign_lhs (g));
1369 gimple_set_location (g, loc);
1370 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1371 g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
1372 gimple_assign_lhs (g), cst);
1373 gimple_set_location (g, loc);
1374 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1375 if (!useless_type_conversion_p (pointer_sized_int_node, htype))
1377 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1378 NOP_EXPR, gimple_assign_lhs (g));
1379 gimple_set_location (g, loc);
1380 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1382 tree hash = gimple_assign_lhs (g);
1384 if (ubsan_vptr_type_cache_decl == NULL_TREE)
1386 tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
1387 tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1388 get_identifier ("__ubsan_vptr_type_cache"),
1389 atype);
1390 DECL_ARTIFICIAL (array) = 1;
1391 DECL_IGNORED_P (array) = 1;
1392 TREE_PUBLIC (array) = 1;
1393 TREE_STATIC (array) = 1;
1394 DECL_EXTERNAL (array) = 1;
1395 DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
1396 DECL_VISIBILITY_SPECIFIED (array) = 1;
1397 varpool_node::finalize_decl (array);
1398 ubsan_vptr_type_cache_decl = array;
1401 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1402 BIT_AND_EXPR, hash,
1403 build_int_cst (pointer_sized_int_node, 127));
1404 gimple_set_location (g, loc);
1405 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1407 tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
1408 ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
1409 NULL_TREE, NULL_TREE);
1410 g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
1411 ARRAY_REF, c);
1412 gimple_set_location (g, loc);
1413 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1415 basic_block then_bb, fallthru2_bb;
1416 gimple_stmt_iterator cond_insert_point
1417 = create_cond_insert_point (gsip, false, false, true,
1418 &then_bb, &fallthru2_bb);
1419 g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
1420 NULL_TREE, NULL_TREE);
1421 gimple_set_location (g, loc);
1422 gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
1423 *gsip = gsi_after_labels (then_bb);
1424 if (fallthru_bb == NULL)
1425 fallthru_bb = fallthru2_bb;
1427 tree data
1428 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
1429 ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
1430 build_int_cst (unsigned_char_type_node, ckind),
1431 NULL_TREE);
1432 data = build_fold_addr_expr_loc (loc, data);
1433 enum built_in_function bcode
1434 = (flag_sanitize_recover & SANITIZE_VPTR)
1435 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1436 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
1438 g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
1439 gimple_set_location (g, loc);
1440 gsi_insert_before (gsip, g, GSI_SAME_STMT);
1442 /* Point GSI to next logical statement. */
1443 *gsip = gsi_start_bb (fallthru_bb);
1445 /* Get rid of the UBSAN_VPTR call from the IR. */
1446 unlink_stmt_vdef (stmt);
1447 gsi_remove (&gsi, true);
1448 return true;
1451 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1452 whether the pointer is on the left hand side of the assignment. */
1454 static void
1455 instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
1456 bool is_lhs)
1458 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
1459 unsigned int align = 0;
1460 if (sanitize_flags_p (SANITIZE_ALIGNMENT))
1462 align = min_align_of_type (TREE_TYPE (base));
1463 if (align <= 1)
1464 align = 0;
1466 if (align == 0 && !sanitize_flags_p (SANITIZE_NULL))
1467 return;
1468 tree t = TREE_OPERAND (base, 0);
1469 if (!POINTER_TYPE_P (TREE_TYPE (t)))
1470 return;
1471 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
1472 ikind = UBSAN_MEMBER_ACCESS;
1473 tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
1474 tree alignt = build_int_cst (pointer_sized_int_node, align);
1475 gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
1476 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
1477 gsi_insert_before (iter, g, GSI_SAME_STMT);
1480 /* Perform the pointer instrumentation. */
1482 static void
1483 instrument_null (gimple_stmt_iterator gsi, tree t, bool is_lhs)
1485 /* Handle also e.g. &s->i. */
1486 if (TREE_CODE (t) == ADDR_EXPR)
1487 t = TREE_OPERAND (t, 0);
1488 tree base = get_base_address (t);
1489 if (base != NULL_TREE
1490 && TREE_CODE (base) == MEM_REF
1491 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1492 instrument_mem_ref (t, base, &gsi, is_lhs);
1495 /* Instrument pointer arithmetics PTR p+ OFF. */
1497 static void
1498 instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree ptr, tree off)
1500 if (TYPE_PRECISION (sizetype) != POINTER_SIZE)
1501 return;
1502 gcall *g = gimple_build_call_internal (IFN_UBSAN_PTR, 2, ptr, off);
1503 gimple_set_location (g, gimple_location (gsi_stmt (*gsi)));
1504 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1507 /* Instrument pointer arithmetics if any. */
1509 static void
1510 maybe_instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree t)
1512 if (TYPE_PRECISION (sizetype) != POINTER_SIZE)
1513 return;
1515 /* Handle also e.g. &s->i. */
1516 if (TREE_CODE (t) == ADDR_EXPR)
1517 t = TREE_OPERAND (t, 0);
1519 if (!handled_component_p (t) && TREE_CODE (t) != MEM_REF)
1520 return;
1522 poly_int64 bitsize, bitpos, bytepos;
1523 tree offset;
1524 machine_mode mode;
1525 int volatilep = 0, reversep, unsignedp = 0;
1526 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
1527 &unsignedp, &reversep, &volatilep);
1528 tree moff = NULL_TREE;
1530 bool decl_p = DECL_P (inner);
1531 tree base;
1532 if (decl_p)
1534 if ((VAR_P (inner)
1535 || TREE_CODE (inner) == PARM_DECL
1536 || TREE_CODE (inner) == RESULT_DECL)
1537 && DECL_REGISTER (inner))
1538 return;
1539 base = inner;
1540 /* If BASE is a fixed size automatic variable or
1541 global variable defined in the current TU and bitpos
1542 fits, don't instrument anything. */
1543 poly_int64 base_size;
1544 if (offset == NULL_TREE
1545 && maybe_ne (bitpos, 0)
1546 && (VAR_P (base)
1547 || TREE_CODE (base) == PARM_DECL
1548 || TREE_CODE (base) == RESULT_DECL)
1549 && poly_int_tree_p (DECL_SIZE (base), &base_size)
1550 && known_ge (base_size, bitpos)
1551 && (!is_global_var (base) || decl_binds_to_current_def_p (base)))
1552 return;
1554 else if (TREE_CODE (inner) == MEM_REF)
1556 base = TREE_OPERAND (inner, 0);
1557 if (TREE_CODE (base) == ADDR_EXPR
1558 && DECL_P (TREE_OPERAND (base, 0))
1559 && !TREE_ADDRESSABLE (TREE_OPERAND (base, 0))
1560 && !is_global_var (TREE_OPERAND (base, 0)))
1561 return;
1562 moff = TREE_OPERAND (inner, 1);
1563 if (integer_zerop (moff))
1564 moff = NULL_TREE;
1566 else
1567 return;
1569 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
1570 return;
1571 bytepos = bits_to_bytes_round_down (bitpos);
1572 if (offset == NULL_TREE && known_eq (bytepos, 0) && moff == NULL_TREE)
1573 return;
1575 tree base_addr = base;
1576 if (decl_p)
1577 base_addr = build1 (ADDR_EXPR,
1578 build_pointer_type (TREE_TYPE (base)), base);
1579 t = offset;
1580 if (maybe_ne (bytepos, 0))
1582 if (t)
1583 t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t,
1584 build_int_cst (TREE_TYPE (t), bytepos));
1585 else
1586 t = size_int (bytepos);
1588 if (moff)
1590 if (t)
1591 t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t,
1592 fold_convert (TREE_TYPE (t), moff));
1593 else
1594 t = fold_convert (sizetype, moff);
1596 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
1597 GSI_SAME_STMT);
1598 base_addr = force_gimple_operand_gsi (gsi, base_addr, true, NULL_TREE, true,
1599 GSI_SAME_STMT);
1600 instrument_pointer_overflow (gsi, base_addr, t);
1603 /* Build an ubsan builtin call for the signed-integer-overflow
1604 sanitization. CODE says what kind of builtin are we building,
1605 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1606 are operands of the binary operation. */
1608 tree
1609 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
1610 tree op0, tree op1, tree *datap)
1612 if (flag_sanitize_trap & SANITIZE_SI_OVERFLOW)
1613 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1615 tree data;
1616 if (datap && *datap)
1617 data = *datap;
1618 else
1619 data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
1620 ubsan_type_descriptor (lhstype), NULL_TREE,
1621 NULL_TREE);
1622 if (datap)
1623 *datap = data;
1624 enum built_in_function fn_code;
1626 switch (code)
1628 case PLUS_EXPR:
1629 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1630 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1631 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
1632 break;
1633 case MINUS_EXPR:
1634 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1635 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1636 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
1637 break;
1638 case MULT_EXPR:
1639 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1640 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1641 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
1642 break;
1643 case NEGATE_EXPR:
1644 fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
1645 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1646 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
1647 break;
1648 default:
1649 gcc_unreachable ();
1651 tree fn = builtin_decl_explicit (fn_code);
1652 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
1653 build_fold_addr_expr_loc (loc, data),
1654 ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL),
1656 ? ubsan_encode_value (op1,
1657 UBSAN_ENCODE_VALUE_RTL)
1658 : NULL_TREE);
1661 /* Perform the signed integer instrumentation. GSI is the iterator
1662 pointing at statement we are trying to instrument. */
1664 static void
1665 instrument_si_overflow (gimple_stmt_iterator gsi)
1667 gimple *stmt = gsi_stmt (gsi);
1668 tree_code code = gimple_assign_rhs_code (stmt);
1669 tree lhs = gimple_assign_lhs (stmt);
1670 tree lhstype = TREE_TYPE (lhs);
1671 tree lhsinner = VECTOR_TYPE_P (lhstype) ? TREE_TYPE (lhstype) : lhstype;
1672 tree a, b;
1673 gimple *g;
1675 /* If this is not a signed operation, don't instrument anything here.
1676 Also punt on bit-fields. */
1677 if (!INTEGRAL_TYPE_P (lhsinner)
1678 || TYPE_OVERFLOW_WRAPS (lhsinner)
1679 || (TREE_CODE (lhsinner) != BITINT_TYPE
1680 && maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (lhsinner)),
1681 TYPE_PRECISION (lhsinner))))
1682 return;
1684 switch (code)
1686 case MINUS_EXPR:
1687 case PLUS_EXPR:
1688 case MULT_EXPR:
1689 /* Transform
1690 i = u {+,-,*} 5;
1691 into
1692 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1693 a = gimple_assign_rhs1 (stmt);
1694 b = gimple_assign_rhs2 (stmt);
1695 g = gimple_build_call_internal (code == PLUS_EXPR
1696 ? IFN_UBSAN_CHECK_ADD
1697 : code == MINUS_EXPR
1698 ? IFN_UBSAN_CHECK_SUB
1699 : IFN_UBSAN_CHECK_MUL, 2, a, b);
1700 gimple_call_set_lhs (g, lhs);
1701 gsi_replace (&gsi, g, true);
1702 break;
1703 case NEGATE_EXPR:
1704 /* Represent i = -u;
1706 i = UBSAN_CHECK_SUB (0, u); */
1707 a = build_zero_cst (lhstype);
1708 b = gimple_assign_rhs1 (stmt);
1709 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1710 gimple_call_set_lhs (g, lhs);
1711 gsi_replace (&gsi, g, true);
1712 break;
1713 case ABS_EXPR:
1714 /* Transform i = ABS_EXPR<u>;
1715 into
1716 _N = UBSAN_CHECK_SUB (0, u);
1717 i = ABS_EXPR<_N>; */
1718 a = build_zero_cst (lhstype);
1719 b = gimple_assign_rhs1 (stmt);
1720 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
1721 a = make_ssa_name (lhstype);
1722 gimple_call_set_lhs (g, a);
1723 gimple_set_location (g, gimple_location (stmt));
1724 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1725 gimple_assign_set_rhs1 (stmt, a);
1726 update_stmt (stmt);
1727 break;
1728 default:
1729 break;
1733 /* Instrument loads from (non-bitfield) bool and C++ enum values
1734 to check if the memory value is outside of the range of the valid
1735 type values. */
1737 static void
1738 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
1740 gimple *stmt = gsi_stmt (*gsi);
1741 tree rhs = gimple_assign_rhs1 (stmt);
1742 tree type = TREE_TYPE (rhs);
1743 tree minv = NULL_TREE, maxv = NULL_TREE;
1745 if (TREE_CODE (type) == BOOLEAN_TYPE
1746 && sanitize_flags_p (SANITIZE_BOOL))
1748 minv = boolean_false_node;
1749 maxv = boolean_true_node;
1751 else if (TREE_CODE (type) == ENUMERAL_TYPE
1752 && sanitize_flags_p (SANITIZE_ENUM)
1753 && TREE_TYPE (type) != NULL_TREE
1754 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
1755 && (TYPE_PRECISION (TREE_TYPE (type))
1756 < GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (type))))
1758 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
1759 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
1761 else
1762 return;
1764 int modebitsize = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type));
1765 poly_int64 bitsize, bitpos;
1766 tree offset;
1767 machine_mode mode;
1768 int volatilep = 0, reversep, unsignedp = 0;
1769 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
1770 &unsignedp, &reversep, &volatilep);
1771 tree utype = build_nonstandard_integer_type (modebitsize, 1);
1773 if ((VAR_P (base) && DECL_HARD_REGISTER (base))
1774 || !multiple_p (bitpos, modebitsize)
1775 || maybe_ne (bitsize, modebitsize)
1776 || GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (utype)) != modebitsize
1777 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1778 return;
1780 bool ends_bb = stmt_ends_bb_p (stmt);
1781 location_t loc = gimple_location (stmt);
1782 tree lhs = gimple_assign_lhs (stmt);
1783 tree ptype = build_pointer_type (TREE_TYPE (rhs));
1784 tree atype = reference_alias_ptr_type (rhs);
1785 gimple *g = gimple_build_assign (make_ssa_name (ptype),
1786 build_fold_addr_expr (rhs));
1787 gimple_set_location (g, loc);
1788 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1789 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
1790 build_int_cst (atype, 0));
1791 tree urhs = make_ssa_name (utype);
1792 if (ends_bb)
1794 gimple_assign_set_lhs (stmt, urhs);
1795 g = gimple_build_assign (lhs, NOP_EXPR, urhs);
1796 gimple_set_location (g, loc);
1797 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
1798 gsi_insert_on_edge_immediate (e, g);
1799 gimple_assign_set_rhs_from_tree (gsi, mem);
1800 update_stmt (stmt);
1801 *gsi = gsi_for_stmt (g);
1802 g = stmt;
1804 else
1806 g = gimple_build_assign (urhs, mem);
1807 gimple_set_location (g, loc);
1808 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1810 minv = fold_convert (utype, minv);
1811 maxv = fold_convert (utype, maxv);
1812 if (!integer_zerop (minv))
1814 g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
1815 gimple_set_location (g, loc);
1816 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1819 gimple_stmt_iterator gsi2 = *gsi;
1820 basic_block then_bb, fallthru_bb;
1821 *gsi = create_cond_insert_point (gsi, true, false, true,
1822 &then_bb, &fallthru_bb);
1823 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
1824 int_const_binop (MINUS_EXPR, maxv, minv),
1825 NULL_TREE, NULL_TREE);
1826 gimple_set_location (g, loc);
1827 gsi_insert_after (gsi, g, GSI_NEW_STMT);
1829 if (!ends_bb)
1831 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
1832 update_stmt (stmt);
1835 gsi2 = gsi_after_labels (then_bb);
1836 if (flag_sanitize_trap & (TREE_CODE (type) == BOOLEAN_TYPE
1837 ? SANITIZE_BOOL : SANITIZE_ENUM))
1838 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1839 else
1841 tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
1842 ubsan_type_descriptor (type), NULL_TREE,
1843 NULL_TREE);
1844 data = build_fold_addr_expr_loc (loc, data);
1845 enum built_in_function bcode
1846 = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
1847 ? SANITIZE_BOOL : SANITIZE_ENUM))
1848 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1849 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
1850 tree fn = builtin_decl_explicit (bcode);
1852 tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE);
1853 val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true,
1854 GSI_SAME_STMT);
1855 g = gimple_build_call (fn, 2, data, val);
1857 gimple_set_location (g, loc);
1858 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
1859 ubsan_create_edge (g);
1860 *gsi = gsi_for_stmt (stmt);
1863 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1864 new style handlers. Libubsan uses heuristics to destinguish between old and
1865 new styles and relies on these properties for filename:
1867 a) Location's filename must not be NULL.
1868 b) Location's filename must not be equal to "".
1869 c) Location's filename must not be equal to "\1".
1870 d) First two bytes of filename must not contain '\xff' symbol. */
1872 static bool
1873 ubsan_use_new_style_p (location_t loc)
1875 if (loc == UNKNOWN_LOCATION)
1876 return false;
1878 expanded_location xloc = expand_location (loc);
1879 if (xloc.file == NULL || startswith (xloc.file, "\1")
1880 || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
1881 || xloc.file[1] == '\xff')
1882 return false;
1884 return true;
1887 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1888 destination, EXPR is floating-point expression. */
1890 tree
1891 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
1893 tree expr_type = TREE_TYPE (expr);
1894 tree t, tt, fn, min, max;
1895 machine_mode mode = TYPE_MODE (expr_type);
1896 int prec = TYPE_PRECISION (type);
1897 bool uns_p = TYPE_UNSIGNED (type);
1898 if (loc == UNKNOWN_LOCATION)
1899 loc = input_location;
1901 /* Float to integer conversion first truncates toward zero, so
1902 even signed char c = 127.875f; is not problematic.
1903 Therefore, we should complain only if EXPR is unordered or smaller
1904 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1905 TYPE_MAX_VALUE + 1.0. */
1906 if (REAL_MODE_FORMAT (mode)->b == 2)
1908 /* For maximum, TYPE_MAX_VALUE might not be representable
1909 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1910 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1911 either representable or infinity. */
1912 REAL_VALUE_TYPE maxval = dconst1;
1913 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
1914 real_convert (&maxval, mode, &maxval);
1915 max = build_real (expr_type, maxval);
1917 /* For unsigned, assume -1.0 is always representable. */
1918 if (uns_p)
1919 min = build_minus_one_cst (expr_type);
1920 else
1922 /* TYPE_MIN_VALUE is generally representable (or -inf),
1923 but TYPE_MIN_VALUE - 1.0 might not be. */
1924 REAL_VALUE_TYPE minval = dconstm1, minval2;
1925 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
1926 real_convert (&minval, mode, &minval);
1927 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
1928 real_convert (&minval2, mode, &minval2);
1929 if (real_compare (EQ_EXPR, &minval, &minval2)
1930 && !real_isinf (&minval))
1932 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1933 rounds to TYPE_MIN_VALUE, we need to subtract
1934 more. As REAL_MODE_FORMAT (mode)->p is the number
1935 of base digits, we want to subtract a number that
1936 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1937 times smaller than minval. */
1938 minval2 = dconst1;
1939 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
1940 SET_REAL_EXP (&minval2,
1941 REAL_EXP (&minval2) + prec - 1
1942 - REAL_MODE_FORMAT (mode)->p + 1);
1943 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
1944 real_convert (&minval2, mode, &minval2);
1946 min = build_real (expr_type, minval2);
1949 else if (REAL_MODE_FORMAT (mode)->b == 10)
1951 /* For _Decimal128 up to 34 decimal digits, - sign,
1952 dot, e, exponent. */
1953 char buf[64];
1954 int p = REAL_MODE_FORMAT (mode)->p;
1955 REAL_VALUE_TYPE maxval, minval;
1957 /* Use mpfr_snprintf rounding to compute the smallest
1958 representable decimal number greater or equal than
1959 1 << (prec - !uns_p). */
1960 auto_mpfr m (prec + 2);
1961 mpfr_set_ui_2exp (m, 1, prec - !uns_p, MPFR_RNDN);
1962 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, (mpfr_srcptr) m);
1963 decimal_real_from_string (&maxval, buf);
1964 max = build_real (expr_type, maxval);
1966 /* For unsigned, assume -1.0 is always representable. */
1967 if (uns_p)
1968 min = build_minus_one_cst (expr_type);
1969 else
1971 /* Use mpfr_snprintf rounding to compute the largest
1972 representable decimal number less or equal than
1973 (-1 << (prec - 1)) - 1. */
1974 mpfr_set_si_2exp (m, -1, prec - 1, MPFR_RNDN);
1975 mpfr_sub_ui (m, m, 1, MPFR_RNDN);
1976 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, (mpfr_srcptr) m);
1977 decimal_real_from_string (&minval, buf);
1978 min = build_real (expr_type, minval);
1981 else
1982 return NULL_TREE;
1984 if (HONOR_NANS (mode))
1986 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1987 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1989 else
1991 t = fold_build2 (LE_EXPR, boolean_type_node, expr, min);
1992 tt = fold_build2 (GE_EXPR, boolean_type_node, expr, max);
1994 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
1995 if (integer_zerop (t))
1996 return NULL_TREE;
1998 if (flag_sanitize_trap & SANITIZE_FLOAT_CAST)
1999 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
2000 else
2002 location_t *loc_ptr = NULL;
2003 unsigned num_locations = 0;
2004 /* Figure out if we can propagate location to ubsan_data and use new
2005 style handlers in libubsan. */
2006 if (ubsan_use_new_style_p (loc))
2008 loc_ptr = &loc;
2009 num_locations = 1;
2011 /* Create the __ubsan_handle_float_cast_overflow fn call. */
2012 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
2013 num_locations, loc_ptr,
2014 ubsan_type_descriptor (expr_type),
2015 ubsan_type_descriptor (type), NULL_TREE,
2016 NULL_TREE);
2017 enum built_in_function bcode
2018 = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
2019 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
2020 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
2021 fn = builtin_decl_explicit (bcode);
2022 fn = build_call_expr_loc (loc, fn, 2,
2023 build_fold_addr_expr_loc (loc, data),
2024 ubsan_encode_value (expr));
2027 return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
2030 /* Instrument values passed to function arguments with nonnull attribute. */
2032 static void
2033 instrument_nonnull_arg (gimple_stmt_iterator *gsi)
2035 gimple *stmt = gsi_stmt (*gsi);
2036 location_t loc[2];
2037 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
2038 while for nonnull sanitization it is clear. */
2039 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
2040 flag_delete_null_pointer_checks = 1;
2041 loc[0] = gimple_location (stmt);
2042 loc[1] = UNKNOWN_LOCATION;
2043 for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
2045 tree arg = gimple_call_arg (stmt, i);
2046 if (POINTER_TYPE_P (TREE_TYPE (arg))
2047 && infer_nonnull_range_by_attribute (stmt, arg))
2049 gimple *g;
2050 if (!is_gimple_val (arg))
2052 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
2053 gimple_set_location (g, loc[0]);
2054 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2055 arg = gimple_assign_lhs (g);
2058 basic_block then_bb, fallthru_bb;
2059 *gsi = create_cond_insert_point (gsi, true, false, true,
2060 &then_bb, &fallthru_bb);
2061 g = gimple_build_cond (EQ_EXPR, arg,
2062 build_zero_cst (TREE_TYPE (arg)),
2063 NULL_TREE, NULL_TREE);
2064 gimple_set_location (g, loc[0]);
2065 gsi_insert_after (gsi, g, GSI_NEW_STMT);
2067 *gsi = gsi_after_labels (then_bb);
2068 if (flag_sanitize_trap & SANITIZE_NONNULL_ATTRIBUTE)
2069 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2070 else
2072 tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
2073 2, loc, NULL_TREE,
2074 build_int_cst (integer_type_node,
2075 i + 1),
2076 NULL_TREE);
2077 data = build_fold_addr_expr_loc (loc[0], data);
2078 enum built_in_function bcode
2079 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
2080 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
2081 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
2082 tree fn = builtin_decl_explicit (bcode);
2084 g = gimple_build_call (fn, 1, data);
2086 gimple_set_location (g, loc[0]);
2087 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2088 ubsan_create_edge (g);
2090 *gsi = gsi_for_stmt (stmt);
2092 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
2095 /* Instrument returns in functions with returns_nonnull attribute. */
2097 static void
2098 instrument_nonnull_return (gimple_stmt_iterator *gsi)
2100 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
2101 location_t loc[2];
2102 tree arg = gimple_return_retval (stmt);
2103 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
2104 while for nonnull return sanitization it is clear. */
2105 int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
2106 flag_delete_null_pointer_checks = 1;
2107 loc[0] = gimple_location (stmt);
2108 loc[1] = UNKNOWN_LOCATION;
2109 if (arg
2110 && POINTER_TYPE_P (TREE_TYPE (arg))
2111 && is_gimple_val (arg)
2112 && infer_nonnull_range_by_attribute (stmt, arg))
2114 basic_block then_bb, fallthru_bb;
2115 *gsi = create_cond_insert_point (gsi, true, false, true,
2116 &then_bb, &fallthru_bb);
2117 gimple *g = gimple_build_cond (EQ_EXPR, arg,
2118 build_zero_cst (TREE_TYPE (arg)),
2119 NULL_TREE, NULL_TREE);
2120 gimple_set_location (g, loc[0]);
2121 gsi_insert_after (gsi, g, GSI_NEW_STMT);
2123 *gsi = gsi_after_labels (then_bb);
2124 if (flag_sanitize_trap & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2125 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2126 else
2128 tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
2129 1, &loc[1], NULL_TREE, NULL_TREE);
2130 data = build_fold_addr_expr_loc (loc[0], data);
2131 tree data2 = ubsan_create_data ("__ubsan_nonnull_return_data",
2132 1, &loc[0], NULL_TREE, NULL_TREE);
2133 data2 = build_fold_addr_expr_loc (loc[0], data2);
2134 enum built_in_function bcode
2135 = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
2136 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1
2137 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1_ABORT;
2138 tree fn = builtin_decl_explicit (bcode);
2140 g = gimple_build_call (fn, 2, data, data2);
2142 gimple_set_location (g, loc[0]);
2143 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2144 ubsan_create_edge (g);
2145 *gsi = gsi_for_stmt (stmt);
2147 flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
2150 /* Instrument memory references. Here we check whether the pointer
2151 points to an out-of-bounds location. */
2153 static void
2154 instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
2156 gimple *stmt = gsi_stmt (*gsi);
2157 location_t loc = gimple_location (stmt);
2158 tree type;
2159 tree index = NULL_TREE;
2160 HOST_WIDE_INT size_in_bytes;
2162 type = TREE_TYPE (t);
2163 if (VOID_TYPE_P (type))
2164 return;
2166 switch (TREE_CODE (t))
2168 case COMPONENT_REF:
2169 if (TREE_CODE (t) == COMPONENT_REF
2170 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
2172 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
2173 t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
2174 repr, TREE_OPERAND (t, 2));
2176 break;
2177 case ARRAY_REF:
2178 index = TREE_OPERAND (t, 1);
2179 break;
2180 case INDIRECT_REF:
2181 case MEM_REF:
2182 case VAR_DECL:
2183 case PARM_DECL:
2184 case RESULT_DECL:
2185 break;
2186 default:
2187 return;
2190 size_in_bytes = int_size_in_bytes (type);
2191 if (size_in_bytes <= 0)
2192 return;
2194 poly_int64 bitsize, bitpos;
2195 tree offset;
2196 machine_mode mode;
2197 int volatilep = 0, reversep, unsignedp = 0;
2198 tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
2199 &unsignedp, &reversep, &volatilep);
2201 if (!multiple_p (bitpos, BITS_PER_UNIT)
2202 || maybe_ne (bitsize, size_in_bytes * BITS_PER_UNIT))
2203 return;
2205 bool decl_p = DECL_P (inner);
2206 tree base;
2207 if (decl_p)
2209 if ((VAR_P (inner)
2210 || TREE_CODE (inner) == PARM_DECL
2211 || TREE_CODE (inner) == RESULT_DECL)
2212 && DECL_REGISTER (inner))
2213 return;
2214 if (t == inner && !is_global_var (t))
2215 return;
2216 base = inner;
2218 else if (TREE_CODE (inner) == MEM_REF)
2219 base = TREE_OPERAND (inner, 0);
2220 else
2221 return;
2222 tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
2224 while (TREE_CODE (base) == SSA_NAME)
2226 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
2227 if (gimple_assign_ssa_name_copy_p (def_stmt)
2228 || (gimple_assign_cast_p (def_stmt)
2229 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
2230 || (is_gimple_assign (def_stmt)
2231 && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
2233 tree rhs1 = gimple_assign_rhs1 (def_stmt);
2234 if (TREE_CODE (rhs1) == SSA_NAME
2235 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
2236 break;
2237 else
2238 base = rhs1;
2240 else
2241 break;
2244 if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
2245 return;
2247 tree sizet;
2248 tree base_addr = base;
2249 gimple *bos_stmt = NULL;
2250 if (decl_p)
2251 base_addr = build1 (ADDR_EXPR,
2252 build_pointer_type (TREE_TYPE (base)), base);
2253 if (compute_builtin_object_size (base_addr, OST_DYNAMIC, &sizet))
2255 else if (optimize)
2257 if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
2258 loc = input_location;
2259 /* Generate __builtin_dynamic_object_size call. */
2260 sizet = builtin_decl_explicit (BUILT_IN_DYNAMIC_OBJECT_SIZE);
2261 sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
2262 integer_zero_node);
2263 sizet = force_gimple_operand_gsi (gsi, sizet, false, NULL_TREE, true,
2264 GSI_SAME_STMT);
2265 /* If the call above didn't end up being an integer constant, go one
2266 statement back and get the __builtin_object_size stmt. Save it,
2267 we might need it later. */
2268 if (SSA_VAR_P (sizet))
2270 gsi_prev (gsi);
2271 bos_stmt = gsi_stmt (*gsi);
2273 /* Move on to where we were. */
2274 gsi_next (gsi);
2277 else
2278 return;
2280 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
2281 call. */
2282 /* ptr + sizeof (*ptr) - base */
2283 t = fold_build2 (MINUS_EXPR, sizetype,
2284 fold_convert (pointer_sized_int_node, ptr),
2285 fold_convert (pointer_sized_int_node, base_addr));
2286 t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
2288 /* Perhaps we can omit the check. */
2289 if (TREE_CODE (t) == INTEGER_CST
2290 && TREE_CODE (sizet) == INTEGER_CST
2291 && tree_int_cst_le (t, sizet))
2292 return;
2294 if (index != NULL_TREE
2295 && TREE_CODE (index) == SSA_NAME
2296 && TREE_CODE (sizet) == INTEGER_CST)
2298 gimple *def = SSA_NAME_DEF_STMT (index);
2299 if (is_gimple_assign (def)
2300 && gimple_assign_rhs_code (def) == BIT_AND_EXPR
2301 && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
2303 tree cst = gimple_assign_rhs2 (def);
2304 tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
2305 TYPE_SIZE_UNIT (type));
2306 if (tree_int_cst_sgn (cst) >= 0
2307 && tree_int_cst_lt (cst, sz))
2308 return;
2312 if (DECL_P (base)
2313 && decl_function_context (base) == current_function_decl
2314 && !TREE_ADDRESSABLE (base))
2315 mark_addressable (base);
2317 if (bos_stmt
2318 && gimple_call_builtin_p (bos_stmt, BUILT_IN_DYNAMIC_OBJECT_SIZE))
2319 ubsan_create_edge (bos_stmt);
2321 /* We have to emit the check. */
2322 t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true,
2323 GSI_SAME_STMT);
2324 ptr = force_gimple_operand_gsi (gsi, ptr, true, NULL_TREE, true,
2325 GSI_SAME_STMT);
2326 tree ckind = build_int_cst (unsigned_char_type_node,
2327 is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
2328 gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
2329 ptr, t, sizet, ckind);
2330 gimple_set_location (g, loc);
2331 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2334 /* Instrument values passed to builtin functions. */
2336 static void
2337 instrument_builtin (gimple_stmt_iterator *gsi)
2339 gimple *stmt = gsi_stmt (*gsi);
2340 location_t loc = gimple_location (stmt);
2341 tree arg;
2342 enum built_in_function fcode
2343 = DECL_FUNCTION_CODE (gimple_call_fndecl (stmt));
2344 int kind = 0;
2345 switch (fcode)
2347 CASE_INT_FN (BUILT_IN_CLZ):
2348 kind = 1;
2349 gcc_fallthrough ();
2350 CASE_INT_FN (BUILT_IN_CTZ):
2351 arg = gimple_call_arg (stmt, 0);
2352 if (!integer_nonzerop (arg))
2354 gimple *g;
2355 if (!is_gimple_val (arg))
2357 g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
2358 gimple_set_location (g, loc);
2359 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2360 arg = gimple_assign_lhs (g);
2363 basic_block then_bb, fallthru_bb;
2364 *gsi = create_cond_insert_point (gsi, true, false, true,
2365 &then_bb, &fallthru_bb);
2366 g = gimple_build_cond (EQ_EXPR, arg,
2367 build_zero_cst (TREE_TYPE (arg)),
2368 NULL_TREE, NULL_TREE);
2369 gimple_set_location (g, loc);
2370 gsi_insert_after (gsi, g, GSI_NEW_STMT);
2372 *gsi = gsi_after_labels (then_bb);
2373 if (flag_sanitize_trap & SANITIZE_BUILTIN)
2374 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2375 else
2377 tree t = build_int_cst (unsigned_char_type_node, kind);
2378 tree data = ubsan_create_data ("__ubsan_builtin_data",
2379 1, &loc, NULL_TREE, t, NULL_TREE);
2380 data = build_fold_addr_expr_loc (loc, data);
2381 enum built_in_function bcode
2382 = (flag_sanitize_recover & SANITIZE_BUILTIN)
2383 ? BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN
2384 : BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN_ABORT;
2385 tree fn = builtin_decl_explicit (bcode);
2387 g = gimple_build_call (fn, 1, data);
2389 gimple_set_location (g, loc);
2390 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2391 ubsan_create_edge (g);
2393 *gsi = gsi_for_stmt (stmt);
2394 break;
2395 default:
2396 break;
2400 namespace {
2402 const pass_data pass_data_ubsan =
2404 GIMPLE_PASS, /* type */
2405 "ubsan", /* name */
2406 OPTGROUP_NONE, /* optinfo_flags */
2407 TV_TREE_UBSAN, /* tv_id */
2408 ( PROP_cfg | PROP_ssa ), /* properties_required */
2409 0, /* properties_provided */
2410 0, /* properties_destroyed */
2411 0, /* todo_flags_start */
2412 TODO_update_ssa, /* todo_flags_finish */
2415 class pass_ubsan : public gimple_opt_pass
2417 public:
2418 pass_ubsan (gcc::context *ctxt)
2419 : gimple_opt_pass (pass_data_ubsan, ctxt)
2422 /* opt_pass methods: */
2423 bool gate (function *) final override
2425 return sanitize_flags_p ((SANITIZE_NULL | SANITIZE_SI_OVERFLOW
2426 | SANITIZE_BOOL | SANITIZE_ENUM
2427 | SANITIZE_ALIGNMENT
2428 | SANITIZE_NONNULL_ATTRIBUTE
2429 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
2430 | SANITIZE_OBJECT_SIZE
2431 | SANITIZE_POINTER_OVERFLOW
2432 | SANITIZE_BUILTIN));
2435 unsigned int execute (function *) final override;
2437 }; // class pass_ubsan
2439 unsigned int
2440 pass_ubsan::execute (function *fun)
2442 basic_block bb;
2443 gimple_stmt_iterator gsi;
2444 unsigned int ret = 0;
2446 initialize_sanitizer_builtins ();
2448 FOR_EACH_BB_FN (bb, fun)
2450 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
2452 gimple *stmt = gsi_stmt (gsi);
2453 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
2455 gsi_next (&gsi);
2456 continue;
2459 if ((sanitize_flags_p (SANITIZE_SI_OVERFLOW, fun->decl))
2460 && is_gimple_assign (stmt))
2461 instrument_si_overflow (gsi);
2463 if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT, fun->decl))
2465 if (gimple_store_p (stmt))
2466 instrument_null (gsi, gimple_get_lhs (stmt), true);
2467 if (gimple_assign_single_p (stmt))
2468 instrument_null (gsi, gimple_assign_rhs1 (stmt), false);
2469 if (is_gimple_call (stmt))
2471 unsigned args_num = gimple_call_num_args (stmt);
2472 for (unsigned i = 0; i < args_num; ++i)
2474 tree arg = gimple_call_arg (stmt, i);
2475 if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2476 continue;
2477 instrument_null (gsi, arg, false);
2482 if (sanitize_flags_p (SANITIZE_BOOL | SANITIZE_ENUM, fun->decl)
2483 && gimple_assign_load_p (stmt))
2485 instrument_bool_enum_load (&gsi);
2486 bb = gimple_bb (stmt);
2489 if (sanitize_flags_p (SANITIZE_NONNULL_ATTRIBUTE, fun->decl)
2490 && is_gimple_call (stmt)
2491 && !gimple_call_internal_p (stmt))
2493 instrument_nonnull_arg (&gsi);
2494 bb = gimple_bb (stmt);
2497 if (sanitize_flags_p (SANITIZE_BUILTIN, fun->decl)
2498 && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
2500 instrument_builtin (&gsi);
2501 bb = gimple_bb (stmt);
2504 if (sanitize_flags_p (SANITIZE_RETURNS_NONNULL_ATTRIBUTE, fun->decl)
2505 && gimple_code (stmt) == GIMPLE_RETURN)
2507 instrument_nonnull_return (&gsi);
2508 bb = gimple_bb (stmt);
2511 if (sanitize_flags_p (SANITIZE_OBJECT_SIZE, fun->decl))
2513 if (gimple_store_p (stmt))
2514 instrument_object_size (&gsi, gimple_get_lhs (stmt), true);
2515 if (gimple_assign_load_p (stmt))
2516 instrument_object_size (&gsi, gimple_assign_rhs1 (stmt),
2517 false);
2518 if (is_gimple_call (stmt))
2520 unsigned args_num = gimple_call_num_args (stmt);
2521 for (unsigned i = 0; i < args_num; ++i)
2523 tree arg = gimple_call_arg (stmt, i);
2524 if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
2525 continue;
2526 instrument_object_size (&gsi, arg, false);
2531 if (sanitize_flags_p (SANITIZE_POINTER_OVERFLOW, fun->decl))
2533 if (is_gimple_assign (stmt)
2534 && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
2535 instrument_pointer_overflow (&gsi,
2536 gimple_assign_rhs1 (stmt),
2537 gimple_assign_rhs2 (stmt));
2538 if (gimple_store_p (stmt))
2539 maybe_instrument_pointer_overflow (&gsi,
2540 gimple_get_lhs (stmt));
2541 if (gimple_assign_single_p (stmt))
2542 maybe_instrument_pointer_overflow (&gsi,
2543 gimple_assign_rhs1 (stmt));
2544 if (is_gimple_call (stmt))
2546 unsigned args_num = gimple_call_num_args (stmt);
2547 for (unsigned i = 0; i < args_num; ++i)
2549 tree arg = gimple_call_arg (stmt, i);
2550 if (is_gimple_reg (arg))
2551 continue;
2552 maybe_instrument_pointer_overflow (&gsi, arg);
2557 gsi_next (&gsi);
2559 if (gimple_purge_dead_eh_edges (bb))
2560 ret = TODO_cleanup_cfg;
2562 return ret;
2565 } // anon namespace
2567 gimple_opt_pass *
2568 make_pass_ubsan (gcc::context *ctxt)
2570 return new pass_ubsan (ctxt);
2573 #include "gt-ubsan.h"