1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2017 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
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
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/>. */
23 #include "coretypes.h"
26 #include "c-family/c-common.h"
29 #include "tree-pass.h"
34 #include "tree-pretty-print.h"
35 #include "stor-layout.h"
37 #include "gimple-iterator.h"
43 #include "gimplify-me.h"
46 #include "tree-object-size.h"
48 #include "gimple-fold.h"
51 /* Map from a tree to a VAR_DECL tree. */
53 struct GTY((for_user
)) tree_type_map
{
54 struct tree_map_base type
;
58 struct tree_type_map_cache_hasher
: ggc_cache_ptr_hash
<tree_type_map
>
60 static inline hashval_t
61 hash (tree_type_map
*t
)
63 return TYPE_UID (t
->type
.from
);
67 equal (tree_type_map
*a
, tree_type_map
*b
)
69 return a
->type
.from
== b
->type
.from
;
73 keep_cache_entry (tree_type_map
*&m
)
75 return ggc_marked_p (m
->type
.from
);
80 hash_table
<tree_type_map_cache_hasher
> *decl_tree_for_type
;
82 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
85 decl_for_type_lookup (tree type
)
87 /* If the hash table is not initialized yet, create it now. */
88 if (decl_tree_for_type
== NULL
)
91 = hash_table
<tree_type_map_cache_hasher
>::create_ggc (10);
92 /* That also means we don't have to bother with the lookup. */
96 struct tree_type_map
*h
, in
;
99 h
= decl_tree_for_type
->find_with_hash (&in
, TYPE_UID (type
));
100 return h
? h
->decl
: NULL_TREE
;
103 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
106 decl_for_type_insert (tree type
, tree decl
)
108 struct tree_type_map
*h
;
110 h
= ggc_alloc
<tree_type_map
> ();
113 *decl_tree_for_type
->find_slot_with_hash (h
, TYPE_UID (type
), INSERT
) = h
;
116 /* Helper routine, which encodes a value in the pointer_sized_int_node.
117 Arguments with precision <= POINTER_SIZE are passed directly,
118 the rest is passed by reference. T is a value we are to encode.
119 PHASE determines when this function is called. */
122 ubsan_encode_value (tree t
, enum ubsan_encode_value_phase phase
)
124 tree type
= TREE_TYPE (t
);
125 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
126 if (bitsize
<= POINTER_SIZE
)
127 switch (TREE_CODE (type
))
132 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
135 tree itype
= build_nonstandard_integer_type (bitsize
, true);
136 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
137 return fold_convert (pointer_sized_int_node
, t
);
144 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
146 /* The reason for this is that we don't want to pessimize
147 code by making vars unnecessarily addressable. */
149 if (phase
!= UBSAN_ENCODE_VALUE_GENERIC
)
151 var
= create_tmp_var (type
);
152 mark_addressable (var
);
156 var
= create_tmp_var_raw (type
);
157 TREE_ADDRESSABLE (var
) = 1;
158 DECL_CONTEXT (var
) = current_function_decl
;
160 if (phase
== UBSAN_ENCODE_VALUE_RTL
)
163 = assign_stack_temp_for_type (TYPE_MODE (type
),
164 GET_MODE_SIZE (TYPE_MODE (type
)),
166 SET_DECL_RTL (var
, mem
);
167 expand_assignment (var
, t
, false);
168 return build_fold_addr_expr (var
);
170 if (phase
!= UBSAN_ENCODE_VALUE_GENERIC
)
172 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
173 t
= build_fold_addr_expr (var
);
174 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
178 var
= build4 (TARGET_EXPR
, type
, var
, t
, NULL_TREE
, NULL_TREE
);
179 return build_fold_addr_expr (var
);
183 return build_fold_addr_expr (t
);
187 /* Cached ubsan_get_type_descriptor_type () return value. */
188 static GTY(()) tree ubsan_type_descriptor_type
;
191 struct __ubsan_type_descriptor
193 unsigned short __typekind;
194 unsigned short __typeinfo;
200 ubsan_get_type_descriptor_type (void)
202 static const char *field_names
[3]
203 = { "__typekind", "__typeinfo", "__typename" };
206 if (ubsan_type_descriptor_type
)
207 return ubsan_type_descriptor_type
;
209 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
210 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
212 ret
= make_node (RECORD_TYPE
);
213 for (int i
= 0; i
< 3; i
++)
215 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
216 get_identifier (field_names
[i
]),
217 (i
== 2) ? flex_arr_type
218 : short_unsigned_type_node
);
219 DECL_CONTEXT (fields
[i
]) = ret
;
221 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
223 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
224 get_identifier ("__ubsan_type_descriptor"),
226 DECL_IGNORED_P (type_decl
) = 1;
227 DECL_ARTIFICIAL (type_decl
) = 1;
228 TYPE_FIELDS (ret
) = fields
[0];
229 TYPE_NAME (ret
) = type_decl
;
230 TYPE_STUB_DECL (ret
) = type_decl
;
232 ubsan_type_descriptor_type
= ret
;
236 /* Cached ubsan_get_source_location_type () return value. */
237 static GTY(()) tree ubsan_source_location_type
;
240 struct __ubsan_source_location
242 const char *__filename;
244 unsigned int __column;
249 ubsan_get_source_location_type (void)
251 static const char *field_names
[3]
252 = { "__filename", "__line", "__column" };
254 if (ubsan_source_location_type
)
255 return ubsan_source_location_type
;
257 tree const_char_type
= build_qualified_type (char_type_node
,
260 ret
= make_node (RECORD_TYPE
);
261 for (int i
= 0; i
< 3; i
++)
263 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
264 get_identifier (field_names
[i
]),
265 (i
== 0) ? build_pointer_type (const_char_type
)
266 : unsigned_type_node
);
267 DECL_CONTEXT (fields
[i
]) = ret
;
269 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
271 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
272 get_identifier ("__ubsan_source_location"),
274 DECL_IGNORED_P (type_decl
) = 1;
275 DECL_ARTIFICIAL (type_decl
) = 1;
276 TYPE_FIELDS (ret
) = fields
[0];
277 TYPE_NAME (ret
) = type_decl
;
278 TYPE_STUB_DECL (ret
) = type_decl
;
280 ubsan_source_location_type
= ret
;
284 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
285 type with its fields filled from a location_t LOC. */
288 ubsan_source_location (location_t loc
)
290 expanded_location xloc
;
291 tree type
= ubsan_get_source_location_type ();
293 xloc
= expand_location (loc
);
295 if (xloc
.file
== NULL
)
297 str
= build_int_cst (ptr_type_node
, 0);
303 /* Fill in the values from LOC. */
304 size_t len
= strlen (xloc
.file
) + 1;
305 str
= build_string (len
, xloc
.file
);
306 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
307 TREE_READONLY (str
) = 1;
308 TREE_STATIC (str
) = 1;
309 str
= build_fold_addr_expr (str
);
311 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
312 build_int_cst (unsigned_type_node
,
313 xloc
.line
), NULL_TREE
,
314 build_int_cst (unsigned_type_node
,
316 TREE_CONSTANT (ctor
) = 1;
317 TREE_STATIC (ctor
) = 1;
322 /* This routine returns a magic number for TYPE. */
324 static unsigned short
325 get_ubsan_type_info_for_type (tree type
)
327 if (TREE_CODE (type
) == REAL_TYPE
)
328 return tree_to_uhwi (TYPE_SIZE (type
));
329 else if (INTEGRAL_TYPE_P (type
))
331 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
332 gcc_assert (prec
!= -1);
333 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
339 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
340 ubsan_ids[1] for Lubsan_data labels. */
341 static GTY(()) unsigned int ubsan_ids
[2];
343 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
344 descriptor. It first looks into the hash table; if not found,
345 create the VAR_DECL, put it into the hash table and return the
346 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
347 an enum controlling how we want to print the type. */
350 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
352 /* See through any typedefs. */
353 type
= TYPE_MAIN_VARIANT (type
);
355 tree decl
= decl_for_type_lookup (type
);
356 /* It is possible that some of the earlier created DECLs were found
357 unused, in that case they weren't emitted and varpool_node::get
358 returns NULL node on them. But now we really need them. Thus,
360 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
361 return build_fold_addr_expr (decl
);
363 tree dtype
= ubsan_get_type_descriptor_type ();
365 const char *tname
= NULL
;
366 pretty_printer pretty_name
;
367 unsigned char deref_depth
= 0;
368 unsigned short tkind
, tinfo
;
370 /* Get the name of the type, or the name of the pointer type. */
371 if (pstyle
== UBSAN_PRINT_POINTER
)
373 gcc_assert (POINTER_TYPE_P (type
));
374 type2
= TREE_TYPE (type
);
376 /* Remove any '*' operators from TYPE. */
377 while (POINTER_TYPE_P (type2
))
378 deref_depth
++, type2
= TREE_TYPE (type2
);
380 if (TREE_CODE (type2
) == METHOD_TYPE
)
381 type2
= TYPE_METHOD_BASETYPE (type2
);
384 /* If an array, get its type. */
385 type2
= strip_array_types (type2
);
387 if (pstyle
== UBSAN_PRINT_ARRAY
)
389 while (POINTER_TYPE_P (type2
))
390 deref_depth
++, type2
= TREE_TYPE (type2
);
393 if (TYPE_NAME (type2
) != NULL
)
395 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
396 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
397 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
398 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
402 /* We weren't able to determine the type name. */
406 if (pstyle
== UBSAN_PRINT_POINTER
)
408 pp_printf (&pretty_name
, "'%s%s%s%s%s%s%s",
409 TYPE_VOLATILE (type2
) ? "volatile " : "",
410 TYPE_READONLY (type2
) ? "const " : "",
411 TYPE_RESTRICT (type2
) ? "restrict " : "",
412 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
413 TREE_CODE (type2
) == RECORD_TYPE
415 : TREE_CODE (type2
) == UNION_TYPE
416 ? "union " : "", tname
,
417 deref_depth
== 0 ? "" : " ");
418 while (deref_depth
-- > 0)
419 pp_star (&pretty_name
);
420 pp_quote (&pretty_name
);
422 else if (pstyle
== UBSAN_PRINT_ARRAY
)
424 /* Pretty print the array dimensions. */
425 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
427 pp_printf (&pretty_name
, "'%s ", tname
);
428 while (deref_depth
-- > 0)
429 pp_star (&pretty_name
);
430 while (TREE_CODE (t
) == ARRAY_TYPE
)
432 pp_left_bracket (&pretty_name
);
433 tree dom
= TYPE_DOMAIN (t
);
435 && TYPE_MAX_VALUE (dom
) != NULL_TREE
436 && TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
438 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom
))
439 && tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1 != 0)
440 pp_printf (&pretty_name
, HOST_WIDE_INT_PRINT_DEC
,
441 tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1);
443 pp_wide_int (&pretty_name
,
444 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom
)), 1),
445 TYPE_SIGN (TREE_TYPE (dom
)));
448 /* ??? We can't determine the variable name; print VLA unspec. */
449 pp_star (&pretty_name
);
450 pp_right_bracket (&pretty_name
);
453 pp_quote (&pretty_name
);
455 /* Save the tree with stripped types. */
459 pp_printf (&pretty_name
, "'%s'", tname
);
461 switch (TREE_CODE (eltype
))
469 /* FIXME: libubsan right now only supports float, double and
470 long double type formats. */
471 if (TYPE_MODE (eltype
) == TYPE_MODE (float_type_node
)
472 || TYPE_MODE (eltype
) == TYPE_MODE (double_type_node
)
473 || TYPE_MODE (eltype
) == TYPE_MODE (long_double_type_node
))
482 tinfo
= get_ubsan_type_info_for_type (eltype
);
484 /* Create a new VAR_DECL of type descriptor. */
485 const char *tmp
= pp_formatted_text (&pretty_name
);
486 size_t len
= strlen (tmp
) + 1;
487 tree str
= build_string (len
, tmp
);
488 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
489 TREE_READONLY (str
) = 1;
490 TREE_STATIC (str
) = 1;
493 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", ubsan_ids
[0]++);
494 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
496 TREE_STATIC (decl
) = 1;
497 TREE_PUBLIC (decl
) = 0;
498 DECL_ARTIFICIAL (decl
) = 1;
499 DECL_IGNORED_P (decl
) = 1;
500 DECL_EXTERNAL (decl
) = 0;
502 = size_binop (PLUS_EXPR
, DECL_SIZE (decl
), TYPE_SIZE (TREE_TYPE (str
)));
503 DECL_SIZE_UNIT (decl
)
504 = size_binop (PLUS_EXPR
, DECL_SIZE_UNIT (decl
),
505 TYPE_SIZE_UNIT (TREE_TYPE (str
)));
507 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
508 build_int_cst (short_unsigned_type_node
,
510 build_int_cst (short_unsigned_type_node
,
511 tinfo
), NULL_TREE
, str
);
512 TREE_CONSTANT (ctor
) = 1;
513 TREE_STATIC (ctor
) = 1;
514 DECL_INITIAL (decl
) = ctor
;
515 varpool_node::finalize_decl (decl
);
517 /* Save the VAR_DECL into the hash table. */
518 decl_for_type_insert (type
, decl
);
520 return build_fold_addr_expr (decl
);
523 /* Create a structure for the ubsan library. NAME is a name of the new
524 structure. LOCCNT is number of locations, PLOC points to array of
525 locations. The arguments in ... are of __ubsan_type_descriptor type
526 and there are at most two of them, followed by NULL_TREE, followed
527 by optional extra arguments and another NULL_TREE. */
530 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
535 vec
<tree
, va_gc
> *saved_args
= NULL
;
539 /* It is possible that PCH zapped table with definitions of sanitizer
540 builtins. Reinitialize them if needed. */
541 initialize_sanitizer_builtins ();
543 /* Firstly, create a pointer to type descriptor type. */
544 tree td_type
= ubsan_get_type_descriptor_type ();
545 td_type
= build_pointer_type (td_type
);
547 /* Create the structure type. */
548 ret
= make_node (RECORD_TYPE
);
549 for (j
= 0; j
< loccnt
; j
++)
551 gcc_checking_assert (i
< 2);
552 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
553 ubsan_get_source_location_type ());
554 DECL_CONTEXT (fields
[i
]) = ret
;
556 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
560 va_start (args
, ploc
);
561 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
562 i
++, t
= va_arg (args
, tree
))
564 gcc_checking_assert (i
< 4);
565 /* Save the tree arguments for later use. */
566 vec_safe_push (saved_args
, t
);
567 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
569 DECL_CONTEXT (fields
[i
]) = ret
;
571 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
574 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
575 i
++, t
= va_arg (args
, tree
))
577 gcc_checking_assert (i
< 6);
578 /* Save the tree arguments for later use. */
579 vec_safe_push (saved_args
, t
);
580 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
582 DECL_CONTEXT (fields
[i
]) = ret
;
584 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
588 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
589 get_identifier (name
), ret
);
590 DECL_IGNORED_P (type_decl
) = 1;
591 DECL_ARTIFICIAL (type_decl
) = 1;
592 TYPE_FIELDS (ret
) = fields
[0];
593 TYPE_NAME (ret
) = type_decl
;
594 TYPE_STUB_DECL (ret
) = type_decl
;
597 /* Now, fill in the type. */
599 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_ids
[1]++);
600 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
602 TREE_STATIC (var
) = 1;
603 TREE_PUBLIC (var
) = 0;
604 DECL_ARTIFICIAL (var
) = 1;
605 DECL_IGNORED_P (var
) = 1;
606 DECL_EXTERNAL (var
) = 0;
608 vec
<constructor_elt
, va_gc
> *v
;
610 tree ctor
= build_constructor (ret
, v
);
612 /* If desirable, set the __ubsan_source_location element. */
613 for (j
= 0; j
< loccnt
; j
++)
615 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
616 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
619 size_t nelts
= vec_safe_length (saved_args
);
620 for (i
= 0; i
< nelts
; i
++)
622 t
= (*saved_args
)[i
];
623 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
626 TREE_CONSTANT (ctor
) = 1;
627 TREE_STATIC (ctor
) = 1;
628 DECL_INITIAL (var
) = ctor
;
629 varpool_node::finalize_decl (var
);
634 /* Instrument the __builtin_unreachable call. We just call the libubsan
638 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
641 location_t loc
= gimple_location (gsi_stmt (*gsi
));
643 if (flag_sanitize_undefined_trap_on_error
)
644 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
647 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
648 NULL_TREE
, NULL_TREE
);
649 data
= build_fold_addr_expr_loc (loc
, data
);
651 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
652 g
= gimple_build_call (fn
, 1, data
);
654 gimple_set_location (g
, loc
);
655 gsi_replace (gsi
, g
, false);
659 /* Return true if T is a call to a libubsan routine. */
662 is_ubsan_builtin_p (tree t
)
664 return TREE_CODE (t
) == FUNCTION_DECL
665 && DECL_BUILT_IN_CLASS (t
) == BUILT_IN_NORMAL
666 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
667 "__builtin___ubsan_", 18) == 0;
670 /* Create a callgraph edge for statement STMT. */
673 ubsan_create_edge (gimple
*stmt
)
675 gcall
*call_stmt
= dyn_cast
<gcall
*> (stmt
);
676 basic_block bb
= gimple_bb (stmt
);
677 int freq
= compute_call_stmt_bb_frequency (current_function_decl
, bb
);
678 cgraph_node
*node
= cgraph_node::get (current_function_decl
);
679 tree decl
= gimple_call_fndecl (call_stmt
);
681 node
->create_edge (cgraph_node::get_create (decl
), call_stmt
, bb
->count
,
685 /* Expand the UBSAN_BOUNDS special builtin function. */
688 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
690 gimple
*stmt
= gsi_stmt (*gsi
);
691 location_t loc
= gimple_location (stmt
);
692 gcc_assert (gimple_call_num_args (stmt
) == 3);
694 /* Pick up the arguments of the UBSAN_BOUNDS call. */
695 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
696 tree index
= gimple_call_arg (stmt
, 1);
697 tree orig_index
= index
;
698 tree bound
= gimple_call_arg (stmt
, 2);
700 gimple_stmt_iterator gsi_orig
= *gsi
;
702 /* Create condition "if (index > bound)". */
703 basic_block then_bb
, fallthru_bb
;
704 gimple_stmt_iterator cond_insert_point
705 = create_cond_insert_point (gsi
, false, false, true,
706 &then_bb
, &fallthru_bb
);
707 index
= fold_convert (TREE_TYPE (bound
), index
);
708 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
710 false, GSI_NEW_STMT
);
711 gimple
*g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
712 gimple_set_location (g
, loc
);
713 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
715 /* Generate __ubsan_handle_out_of_bounds call. */
716 *gsi
= gsi_after_labels (then_bb
);
717 if (flag_sanitize_undefined_trap_on_error
)
718 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
722 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
723 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
724 ubsan_type_descriptor (TREE_TYPE (orig_index
)),
725 NULL_TREE
, NULL_TREE
);
726 data
= build_fold_addr_expr_loc (loc
, data
);
727 enum built_in_function bcode
728 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
729 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
730 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
731 tree fn
= builtin_decl_explicit (bcode
);
732 tree val
= ubsan_encode_value (orig_index
, UBSAN_ENCODE_VALUE_GIMPLE
);
733 val
= force_gimple_operand_gsi (gsi
, val
, true, NULL_TREE
, true,
735 g
= gimple_build_call (fn
, 2, data
, val
);
737 gimple_set_location (g
, loc
);
738 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
740 /* Get rid of the UBSAN_BOUNDS call from the IR. */
741 unlink_stmt_vdef (stmt
);
742 gsi_remove (&gsi_orig
, true);
744 /* Point GSI to next logical statement. */
745 *gsi
= gsi_start_bb (fallthru_bb
);
749 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
750 argument which is a constant, because the middle-end treats pointer
751 conversions as useless and therefore the type of the first argument
752 could be changed to any other pointer type. */
755 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
757 gimple_stmt_iterator gsi
= *gsip
;
758 gimple
*stmt
= gsi_stmt (gsi
);
759 location_t loc
= gimple_location (stmt
);
760 gcc_assert (gimple_call_num_args (stmt
) == 3);
761 tree ptr
= gimple_call_arg (stmt
, 0);
762 tree ckind
= gimple_call_arg (stmt
, 1);
763 tree align
= gimple_call_arg (stmt
, 2);
764 tree check_align
= NULL_TREE
;
767 basic_block cur_bb
= gsi_bb (gsi
);
770 if (!integer_zerop (align
))
772 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
773 if (compare_tree_int (align
, ptralign
) == 1)
775 check_align
= make_ssa_name (pointer_sized_int_node
);
776 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
777 gimple_set_location (g
, loc
);
778 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
781 check_null
= sanitize_flags_p (SANITIZE_NULL
);
783 if (check_align
== NULL_TREE
&& !check_null
)
785 gsi_remove (gsip
, true);
786 /* Unlink the UBSAN_NULLs vops before replacing it. */
787 unlink_stmt_vdef (stmt
);
791 /* Split the original block holding the pointer dereference. */
792 edge e
= split_block (cur_bb
, stmt
);
794 /* Get a hold on the 'condition block', the 'then block' and the
796 basic_block cond_bb
= e
->src
;
797 basic_block fallthru_bb
= e
->dest
;
798 basic_block then_bb
= create_empty_bb (cond_bb
);
799 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
800 loops_state_set (LOOPS_NEED_FIXUP
);
802 /* Make an edge coming from the 'cond block' into the 'then block';
803 this edge is unlikely taken, so set up the probability accordingly. */
804 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
805 e
->probability
= profile_probability::very_unlikely ();
807 /* Connect 'then block' with the 'else block'. This is needed
808 as the ubsan routines we call in the 'then block' are not noreturn.
809 The 'then block' only has one outcoming edge. */
810 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
812 /* Set up the fallthrough basic block. */
813 e
= find_edge (cond_bb
, fallthru_bb
);
814 e
->flags
= EDGE_FALSE_VALUE
;
815 e
->count
= cond_bb
->count
;
816 e
->probability
= profile_probability::very_likely ();
818 /* Update dominance info for the newly created then_bb; note that
819 fallthru_bb's dominance info has already been updated by
821 if (dom_info_available_p (CDI_DOMINATORS
))
822 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
824 /* Put the ubsan builtin call into the newly created BB. */
825 if (flag_sanitize_undefined_trap_on_error
)
826 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
829 enum built_in_function bcode
830 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
831 | (check_null
? SANITIZE_NULL
: 0)))
832 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
833 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
834 tree fn
= builtin_decl_implicit (bcode
);
836 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
837 ubsan_type_descriptor (TREE_TYPE (ckind
),
838 UBSAN_PRINT_POINTER
),
841 fold_convert (unsigned_char_type_node
, ckind
),
843 data
= build_fold_addr_expr_loc (loc
, data
);
844 g
= gimple_build_call (fn
, 2, data
,
845 check_align
? check_align
846 : build_zero_cst (pointer_sized_int_node
));
848 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
849 gimple_set_location (g
, loc
);
850 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
852 /* Unlink the UBSAN_NULLs vops before replacing it. */
853 unlink_stmt_vdef (stmt
);
857 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
858 NULL_TREE
, NULL_TREE
);
859 gimple_set_location (g
, loc
);
861 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
862 gsi_replace (&gsi
, g
, false);
870 /* Split the block with the condition again. */
871 e
= split_block (cond_bb
, stmt
);
872 basic_block cond1_bb
= e
->src
;
873 basic_block cond2_bb
= e
->dest
;
875 /* Make an edge coming from the 'cond1 block' into the 'then block';
876 this edge is unlikely taken, so set up the probability
878 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
879 e
->probability
= profile_probability::very_unlikely ();
881 /* Set up the fallthrough basic block. */
882 e
= find_edge (cond1_bb
, cond2_bb
);
883 e
->flags
= EDGE_FALSE_VALUE
;
884 e
->count
= cond1_bb
->count
;
885 e
->probability
= profile_probability::very_likely ();
887 /* Update dominance info. */
888 if (dom_info_available_p (CDI_DOMINATORS
))
890 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
891 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
894 gsi2
= gsi_start_bb (cond2_bb
);
897 tree mask
= build_int_cst (pointer_sized_int_node
,
898 tree_to_uhwi (align
) - 1);
899 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
900 BIT_AND_EXPR
, check_align
, mask
);
901 gimple_set_location (g
, loc
);
903 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
905 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
907 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
908 build_int_cst (pointer_sized_int_node
, 0),
909 NULL_TREE
, NULL_TREE
);
910 gimple_set_location (g
, loc
);
912 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
914 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
915 gsi_replace (&gsi
, g
, false);
920 #define OBJSZ_MAX_OFFSET (1024 * 16)
922 /* Expand UBSAN_OBJECT_SIZE internal call. */
925 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
927 gimple
*stmt
= gsi_stmt (*gsi
);
928 location_t loc
= gimple_location (stmt
);
929 gcc_assert (gimple_call_num_args (stmt
) == 4);
931 tree ptr
= gimple_call_arg (stmt
, 0);
932 tree offset
= gimple_call_arg (stmt
, 1);
933 tree size
= gimple_call_arg (stmt
, 2);
934 tree ckind
= gimple_call_arg (stmt
, 3);
935 gimple_stmt_iterator gsi_orig
= *gsi
;
938 /* See if we can discard the check. */
939 if (TREE_CODE (size
) != INTEGER_CST
940 || integer_all_onesp (size
))
941 /* Yes, __builtin_object_size couldn't determine the
943 else if (TREE_CODE (offset
) == INTEGER_CST
944 && wi::to_widest (offset
) >= -OBJSZ_MAX_OFFSET
945 && wi::to_widest (offset
) <= -1)
946 /* The offset is in range [-16K, -1]. */;
949 /* if (offset > objsize) */
950 basic_block then_bb
, fallthru_bb
;
951 gimple_stmt_iterator cond_insert_point
952 = create_cond_insert_point (gsi
, false, false, true,
953 &then_bb
, &fallthru_bb
);
954 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
955 gimple_set_location (g
, loc
);
956 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
958 /* If the offset is small enough, we don't need the second
960 if (TREE_CODE (offset
) == INTEGER_CST
961 && wi::to_widest (offset
) >= 0
962 && wi::to_widest (offset
) <= OBJSZ_MAX_OFFSET
)
963 *gsi
= gsi_after_labels (then_bb
);
966 /* Don't issue run-time error if (ptr > ptr + offset). That
967 may happen when computing a POINTER_PLUS_EXPR. */
968 basic_block then2_bb
, fallthru2_bb
;
970 gimple_stmt_iterator gsi2
= gsi_after_labels (then_bb
);
971 cond_insert_point
= create_cond_insert_point (&gsi2
, false, false,
974 /* Convert the pointer to an integer type. */
975 tree p
= make_ssa_name (pointer_sized_int_node
);
976 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
977 gimple_set_location (g
, loc
);
978 gsi_insert_before (&cond_insert_point
, g
, GSI_NEW_STMT
);
979 p
= gimple_assign_lhs (g
);
980 /* Compute ptr + offset. */
981 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
982 PLUS_EXPR
, p
, offset
);
983 gimple_set_location (g
, loc
);
984 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
985 /* Now build the conditional and put it into the IR. */
986 g
= gimple_build_cond (LE_EXPR
, p
, gimple_assign_lhs (g
),
987 NULL_TREE
, NULL_TREE
);
988 gimple_set_location (g
, loc
);
989 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
990 *gsi
= gsi_after_labels (then2_bb
);
993 /* Generate __ubsan_handle_type_mismatch call. */
994 if (flag_sanitize_undefined_trap_on_error
)
995 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
999 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
1000 ubsan_type_descriptor (TREE_TYPE (ptr
),
1001 UBSAN_PRINT_POINTER
),
1003 build_zero_cst (pointer_sized_int_node
),
1006 data
= build_fold_addr_expr_loc (loc
, data
);
1007 enum built_in_function bcode
1008 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
1009 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1010 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
1011 tree p
= make_ssa_name (pointer_sized_int_node
);
1012 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
1013 gimple_set_location (g
, loc
);
1014 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1015 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
1017 gimple_set_location (g
, loc
);
1018 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1020 /* Point GSI to next logical statement. */
1021 *gsi
= gsi_start_bb (fallthru_bb
);
1023 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1024 unlink_stmt_vdef (stmt
);
1025 gsi_remove (&gsi_orig
, true);
1029 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1030 unlink_stmt_vdef (stmt
);
1031 gsi_remove (gsi
, true);
1035 /* Expand UBSAN_PTR internal call. */
1038 ubsan_expand_ptr_ifn (gimple_stmt_iterator
*gsip
)
1040 gimple_stmt_iterator gsi
= *gsip
;
1041 gimple
*stmt
= gsi_stmt (gsi
);
1042 location_t loc
= gimple_location (stmt
);
1043 gcc_assert (gimple_call_num_args (stmt
) == 2);
1044 tree ptr
= gimple_call_arg (stmt
, 0);
1045 tree off
= gimple_call_arg (stmt
, 1);
1047 if (integer_zerop (off
))
1049 gsi_remove (gsip
, true);
1050 unlink_stmt_vdef (stmt
);
1054 basic_block cur_bb
= gsi_bb (gsi
);
1055 tree ptrplusoff
= make_ssa_name (pointer_sized_int_node
);
1056 tree ptri
= make_ssa_name (pointer_sized_int_node
);
1057 int pos_neg
= get_range_pos_neg (off
);
1059 /* Split the original block holding the pointer dereference. */
1060 edge e
= split_block (cur_bb
, stmt
);
1062 /* Get a hold on the 'condition block', the 'then block' and the
1064 basic_block cond_bb
= e
->src
;
1065 basic_block fallthru_bb
= e
->dest
;
1066 basic_block then_bb
= create_empty_bb (cond_bb
);
1067 basic_block cond_pos_bb
= NULL
, cond_neg_bb
= NULL
;
1068 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
1069 loops_state_set (LOOPS_NEED_FIXUP
);
1071 /* Set up the fallthrough basic block. */
1072 e
->flags
= EDGE_FALSE_VALUE
;
1075 e
->count
= cond_bb
->count
;
1076 e
->probability
= profile_probability::very_likely ();
1078 /* Connect 'then block' with the 'else block'. This is needed
1079 as the ubsan routines we call in the 'then block' are not noreturn.
1080 The 'then block' only has one outcoming edge. */
1081 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
1083 /* Make an edge coming from the 'cond block' into the 'then block';
1084 this edge is unlikely taken, so set up the probability
1086 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
1087 e
->probability
= profile_probability::very_unlikely ();
1091 profile_count count
= cond_bb
->count
.apply_probability (PROB_EVEN
);
1093 e
->probability
= profile_probability::even ();
1095 e
= split_block (fallthru_bb
, (gimple
*) NULL
);
1096 cond_neg_bb
= e
->src
;
1097 fallthru_bb
= e
->dest
;
1099 e
->probability
= profile_probability::very_likely ();
1100 e
->flags
= EDGE_FALSE_VALUE
;
1102 e
= make_edge (cond_neg_bb
, then_bb
, EDGE_TRUE_VALUE
);
1103 e
->probability
= profile_probability::very_unlikely ();
1105 cond_pos_bb
= create_empty_bb (cond_bb
);
1106 add_bb_to_loop (cond_pos_bb
, cond_bb
->loop_father
);
1108 e
= make_edge (cond_bb
, cond_pos_bb
, EDGE_TRUE_VALUE
);
1110 e
->probability
= profile_probability::even ();
1112 e
= make_edge (cond_pos_bb
, then_bb
, EDGE_TRUE_VALUE
);
1113 e
->probability
= profile_probability::very_unlikely ();
1115 e
= make_edge (cond_pos_bb
, fallthru_bb
, EDGE_FALSE_VALUE
);
1117 e
->probability
= profile_probability::very_likely ();
1119 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
1122 gimple
*g
= gimple_build_assign (ptri
, NOP_EXPR
, ptr
);
1123 gimple_set_location (g
, loc
);
1124 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1125 g
= gimple_build_assign (ptrplusoff
, PLUS_EXPR
, ptri
, off
);
1126 gimple_set_location (g
, loc
);
1127 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1129 /* Update dominance info for the newly created then_bb; note that
1130 fallthru_bb's dominance info has already been updated by
1132 if (dom_info_available_p (CDI_DOMINATORS
))
1134 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
1137 set_immediate_dominator (CDI_DOMINATORS
, cond_pos_bb
, cond_bb
);
1138 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond_bb
);
1142 /* Put the ubsan builtin call into the newly created BB. */
1143 if (flag_sanitize_undefined_trap_on_error
)
1144 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
1147 enum built_in_function bcode
1148 = (flag_sanitize_recover
& SANITIZE_POINTER_OVERFLOW
)
1149 ? BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW
1150 : BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW_ABORT
;
1151 tree fn
= builtin_decl_implicit (bcode
);
1153 = ubsan_create_data ("__ubsan_ptrovf_data", 1, &loc
,
1154 NULL_TREE
, NULL_TREE
);
1155 data
= build_fold_addr_expr_loc (loc
, data
);
1156 g
= gimple_build_call (fn
, 3, data
, ptr
, ptrplusoff
);
1158 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
1159 gimple_set_location (g
, loc
);
1160 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
1162 /* Unlink the UBSAN_PTRs vops before replacing it. */
1163 unlink_stmt_vdef (stmt
);
1165 if (TREE_CODE (off
) == INTEGER_CST
)
1166 g
= gimple_build_cond (wi::neg_p (off
) ? LT_EXPR
: GE_EXPR
, ptri
,
1167 fold_build1 (NEGATE_EXPR
, sizetype
, off
),
1168 NULL_TREE
, NULL_TREE
);
1169 else if (pos_neg
!= 3)
1170 g
= gimple_build_cond (pos_neg
== 1 ? LT_EXPR
: GT_EXPR
,
1171 ptrplusoff
, ptri
, NULL_TREE
, NULL_TREE
);
1174 gsi2
= gsi_start_bb (cond_pos_bb
);
1175 g
= gimple_build_cond (LT_EXPR
, ptrplusoff
, ptri
, NULL_TREE
, NULL_TREE
);
1176 gimple_set_location (g
, loc
);
1177 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
1179 gsi2
= gsi_start_bb (cond_neg_bb
);
1180 g
= gimple_build_cond (GT_EXPR
, ptrplusoff
, ptri
, NULL_TREE
, NULL_TREE
);
1181 gimple_set_location (g
, loc
);
1182 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
1184 gimple_seq seq
= NULL
;
1185 tree t
= gimple_build (&seq
, loc
, NOP_EXPR
, ssizetype
, off
);
1186 t
= gimple_build (&seq
, loc
, GE_EXPR
, boolean_type_node
,
1188 gsi_insert_seq_before (&gsi
, seq
, GSI_SAME_STMT
);
1189 g
= gimple_build_cond (NE_EXPR
, t
, boolean_false_node
,
1190 NULL_TREE
, NULL_TREE
);
1192 gimple_set_location (g
, loc
);
1193 /* Replace the UBSAN_PTR with a GIMPLE_COND stmt. */
1194 gsi_replace (&gsi
, g
, false);
1199 /* Cached __ubsan_vptr_type_cache decl. */
1200 static GTY(()) tree ubsan_vptr_type_cache_decl
;
1202 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1203 argument which is a constant, because the middle-end treats pointer
1204 conversions as useless and therefore the type of the first argument
1205 could be changed to any other pointer type. */
1208 ubsan_expand_vptr_ifn (gimple_stmt_iterator
*gsip
)
1210 gimple_stmt_iterator gsi
= *gsip
;
1211 gimple
*stmt
= gsi_stmt (gsi
);
1212 location_t loc
= gimple_location (stmt
);
1213 gcc_assert (gimple_call_num_args (stmt
) == 5);
1214 tree op
= gimple_call_arg (stmt
, 0);
1215 tree vptr
= gimple_call_arg (stmt
, 1);
1216 tree str_hash
= gimple_call_arg (stmt
, 2);
1217 tree ti_decl_addr
= gimple_call_arg (stmt
, 3);
1218 tree ckind_tree
= gimple_call_arg (stmt
, 4);
1219 ubsan_null_ckind ckind
= (ubsan_null_ckind
) tree_to_uhwi (ckind_tree
);
1220 tree type
= TREE_TYPE (TREE_TYPE (ckind_tree
));
1222 basic_block fallthru_bb
= NULL
;
1224 if (ckind
== UBSAN_DOWNCAST_POINTER
)
1226 /* Guard everything with if (op != NULL) { ... }. */
1227 basic_block then_bb
;
1228 gimple_stmt_iterator cond_insert_point
1229 = create_cond_insert_point (gsip
, false, false, true,
1230 &then_bb
, &fallthru_bb
);
1231 g
= gimple_build_cond (NE_EXPR
, op
, build_zero_cst (TREE_TYPE (op
)),
1232 NULL_TREE
, NULL_TREE
);
1233 gimple_set_location (g
, loc
);
1234 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1235 *gsip
= gsi_after_labels (then_bb
);
1236 gsi_remove (&gsi
, false);
1237 gsi_insert_before (gsip
, stmt
, GSI_NEW_STMT
);
1241 tree htype
= TREE_TYPE (str_hash
);
1242 tree cst
= wide_int_to_tree (htype
,
1243 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1245 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1247 gimple_set_location (g
, loc
);
1248 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1249 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1250 gimple_assign_lhs (g
), cst
);
1251 gimple_set_location (g
, loc
);
1252 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1253 tree t1
= gimple_assign_lhs (g
);
1254 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1255 t1
, build_int_cst (integer_type_node
, 47));
1256 gimple_set_location (g
, loc
);
1257 tree t2
= gimple_assign_lhs (g
);
1258 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1259 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1261 gimple_set_location (g
, loc
);
1262 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1263 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1264 t2
, gimple_assign_lhs (g
));
1265 gimple_set_location (g
, loc
);
1266 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1267 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1268 gimple_assign_lhs (g
), cst
);
1269 gimple_set_location (g
, loc
);
1270 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1271 tree t3
= gimple_assign_lhs (g
);
1272 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1273 t3
, build_int_cst (integer_type_node
, 47));
1274 gimple_set_location (g
, loc
);
1275 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1276 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1277 t3
, gimple_assign_lhs (g
));
1278 gimple_set_location (g
, loc
);
1279 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1280 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1281 gimple_assign_lhs (g
), cst
);
1282 gimple_set_location (g
, loc
);
1283 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1284 if (!useless_type_conversion_p (pointer_sized_int_node
, htype
))
1286 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1287 NOP_EXPR
, gimple_assign_lhs (g
));
1288 gimple_set_location (g
, loc
);
1289 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1291 tree hash
= gimple_assign_lhs (g
);
1293 if (ubsan_vptr_type_cache_decl
== NULL_TREE
)
1295 tree atype
= build_array_type_nelts (pointer_sized_int_node
, 128);
1296 tree array
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1297 get_identifier ("__ubsan_vptr_type_cache"),
1299 DECL_ARTIFICIAL (array
) = 1;
1300 DECL_IGNORED_P (array
) = 1;
1301 TREE_PUBLIC (array
) = 1;
1302 TREE_STATIC (array
) = 1;
1303 DECL_EXTERNAL (array
) = 1;
1304 DECL_VISIBILITY (array
) = VISIBILITY_DEFAULT
;
1305 DECL_VISIBILITY_SPECIFIED (array
) = 1;
1306 varpool_node::finalize_decl (array
);
1307 ubsan_vptr_type_cache_decl
= array
;
1310 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1312 build_int_cst (pointer_sized_int_node
, 127));
1313 gimple_set_location (g
, loc
);
1314 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1316 tree c
= build4_loc (loc
, ARRAY_REF
, pointer_sized_int_node
,
1317 ubsan_vptr_type_cache_decl
, gimple_assign_lhs (g
),
1318 NULL_TREE
, NULL_TREE
);
1319 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1321 gimple_set_location (g
, loc
);
1322 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1324 basic_block then_bb
, fallthru2_bb
;
1325 gimple_stmt_iterator cond_insert_point
1326 = create_cond_insert_point (gsip
, false, false, true,
1327 &then_bb
, &fallthru2_bb
);
1328 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
), hash
,
1329 NULL_TREE
, NULL_TREE
);
1330 gimple_set_location (g
, loc
);
1331 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1332 *gsip
= gsi_after_labels (then_bb
);
1333 if (fallthru_bb
== NULL
)
1334 fallthru_bb
= fallthru2_bb
;
1337 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc
,
1338 ubsan_type_descriptor (type
), NULL_TREE
, ti_decl_addr
,
1339 build_int_cst (unsigned_char_type_node
, ckind
),
1341 data
= build_fold_addr_expr_loc (loc
, data
);
1342 enum built_in_function bcode
1343 = (flag_sanitize_recover
& SANITIZE_VPTR
)
1344 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1345 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT
;
1347 g
= gimple_build_call (builtin_decl_explicit (bcode
), 3, data
, op
, hash
);
1348 gimple_set_location (g
, loc
);
1349 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1351 /* Point GSI to next logical statement. */
1352 *gsip
= gsi_start_bb (fallthru_bb
);
1354 /* Get rid of the UBSAN_VPTR call from the IR. */
1355 unlink_stmt_vdef (stmt
);
1356 gsi_remove (&gsi
, true);
1360 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1361 whether the pointer is on the left hand side of the assignment. */
1364 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
1367 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
1368 unsigned int align
= 0;
1369 if (sanitize_flags_p (SANITIZE_ALIGNMENT
))
1371 align
= min_align_of_type (TREE_TYPE (base
));
1375 if (align
== 0 && !sanitize_flags_p (SANITIZE_NULL
))
1377 tree t
= TREE_OPERAND (base
, 0);
1378 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
1380 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base
)) && mem
!= base
)
1381 ikind
= UBSAN_MEMBER_ACCESS
;
1382 tree kind
= build_int_cst (build_pointer_type (TREE_TYPE (base
)), ikind
);
1383 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
1384 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
1385 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
1386 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
1389 /* Perform the pointer instrumentation. */
1392 instrument_null (gimple_stmt_iterator gsi
, tree t
, bool is_lhs
)
1394 /* Handle also e.g. &s->i. */
1395 if (TREE_CODE (t
) == ADDR_EXPR
)
1396 t
= TREE_OPERAND (t
, 0);
1397 tree base
= get_base_address (t
);
1398 if (base
!= NULL_TREE
1399 && TREE_CODE (base
) == MEM_REF
1400 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1401 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1404 /* Instrument pointer arithmetics PTR p+ OFF. */
1407 instrument_pointer_overflow (gimple_stmt_iterator
*gsi
, tree ptr
, tree off
)
1409 if (TYPE_PRECISION (sizetype
) != POINTER_SIZE
)
1411 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_PTR
, 2, ptr
, off
);
1412 gimple_set_location (g
, gimple_location (gsi_stmt (*gsi
)));
1413 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1416 /* Instrument pointer arithmetics if any. */
1419 maybe_instrument_pointer_overflow (gimple_stmt_iterator
*gsi
, tree t
)
1421 if (TYPE_PRECISION (sizetype
) != POINTER_SIZE
)
1424 /* Handle also e.g. &s->i. */
1425 if (TREE_CODE (t
) == ADDR_EXPR
)
1426 t
= TREE_OPERAND (t
, 0);
1428 if (!handled_component_p (t
) && TREE_CODE (t
) != MEM_REF
)
1431 HOST_WIDE_INT bitsize
, bitpos
, bytepos
;
1434 int volatilep
= 0, reversep
, unsignedp
= 0;
1435 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1436 &unsignedp
, &reversep
, &volatilep
);
1437 tree moff
= NULL_TREE
;
1439 bool decl_p
= DECL_P (inner
);
1443 if (DECL_REGISTER (inner
))
1446 /* If BASE is a fixed size automatic variable or
1447 global variable defined in the current TU and bitpos
1448 fits, don't instrument anything. */
1449 if (offset
== NULL_TREE
1452 || TREE_CODE (base
) == PARM_DECL
1453 || TREE_CODE (base
) == RESULT_DECL
)
1455 && TREE_CODE (DECL_SIZE (base
)) == INTEGER_CST
1456 && compare_tree_int (DECL_SIZE (base
), bitpos
) >= 0
1457 && (!is_global_var (base
) || decl_binds_to_current_def_p (base
)))
1460 else if (TREE_CODE (inner
) == MEM_REF
)
1462 base
= TREE_OPERAND (inner
, 0);
1463 if (TREE_CODE (base
) == ADDR_EXPR
1464 && DECL_P (TREE_OPERAND (base
, 0))
1465 && !TREE_ADDRESSABLE (TREE_OPERAND (base
, 0))
1466 && !is_global_var (TREE_OPERAND (base
, 0)))
1468 moff
= TREE_OPERAND (inner
, 1);
1469 if (integer_zerop (moff
))
1475 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1477 bytepos
= bitpos
/ BITS_PER_UNIT
;
1478 if (offset
== NULL_TREE
&& bytepos
== 0 && moff
== NULL_TREE
)
1481 tree base_addr
= base
;
1483 base_addr
= build1 (ADDR_EXPR
,
1484 build_pointer_type (TREE_TYPE (base
)), base
);
1489 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t
,
1490 build_int_cst (TREE_TYPE (t
), bytepos
));
1492 t
= size_int (bytepos
);
1497 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t
,
1498 fold_convert (TREE_TYPE (t
), moff
));
1500 t
= fold_convert (sizetype
, moff
);
1502 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1504 base_addr
= force_gimple_operand_gsi (gsi
, base_addr
, true, NULL_TREE
, true,
1506 instrument_pointer_overflow (gsi
, base_addr
, t
);
1509 /* Build an ubsan builtin call for the signed-integer-overflow
1510 sanitization. CODE says what kind of builtin are we building,
1511 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1512 are operands of the binary operation. */
1515 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1516 tree op0
, tree op1
, tree
*datap
)
1518 if (flag_sanitize_undefined_trap_on_error
)
1519 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1522 if (datap
&& *datap
)
1525 data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1526 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1530 enum built_in_function fn_code
;
1535 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1536 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1537 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1540 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1541 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1542 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1545 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1546 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1547 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1550 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1551 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1552 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1557 tree fn
= builtin_decl_explicit (fn_code
);
1558 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1559 build_fold_addr_expr_loc (loc
, data
),
1560 ubsan_encode_value (op0
, UBSAN_ENCODE_VALUE_RTL
),
1562 ? ubsan_encode_value (op1
,
1563 UBSAN_ENCODE_VALUE_RTL
)
1567 /* Perform the signed integer instrumentation. GSI is the iterator
1568 pointing at statement we are trying to instrument. */
1571 instrument_si_overflow (gimple_stmt_iterator gsi
)
1573 gimple
*stmt
= gsi_stmt (gsi
);
1574 tree_code code
= gimple_assign_rhs_code (stmt
);
1575 tree lhs
= gimple_assign_lhs (stmt
);
1576 tree lhstype
= TREE_TYPE (lhs
);
1577 tree lhsinner
= VECTOR_TYPE_P (lhstype
) ? TREE_TYPE (lhstype
) : lhstype
;
1581 /* If this is not a signed operation, don't instrument anything here.
1582 Also punt on bit-fields. */
1583 if (!INTEGRAL_TYPE_P (lhsinner
)
1584 || TYPE_OVERFLOW_WRAPS (lhsinner
)
1585 || GET_MODE_BITSIZE (TYPE_MODE (lhsinner
)) != TYPE_PRECISION (lhsinner
))
1596 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1597 a
= gimple_assign_rhs1 (stmt
);
1598 b
= gimple_assign_rhs2 (stmt
);
1599 g
= gimple_build_call_internal (code
== PLUS_EXPR
1600 ? IFN_UBSAN_CHECK_ADD
1601 : code
== MINUS_EXPR
1602 ? IFN_UBSAN_CHECK_SUB
1603 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1604 gimple_call_set_lhs (g
, lhs
);
1605 gsi_replace (&gsi
, g
, true);
1608 /* Represent i = -u;
1610 i = UBSAN_CHECK_SUB (0, u); */
1611 a
= build_zero_cst (lhstype
);
1612 b
= gimple_assign_rhs1 (stmt
);
1613 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1614 gimple_call_set_lhs (g
, lhs
);
1615 gsi_replace (&gsi
, g
, true);
1618 /* Transform i = ABS_EXPR<u>;
1620 _N = UBSAN_CHECK_SUB (0, u);
1621 i = ABS_EXPR<_N>; */
1622 a
= build_zero_cst (lhstype
);
1623 b
= gimple_assign_rhs1 (stmt
);
1624 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1625 a
= make_ssa_name (lhstype
);
1626 gimple_call_set_lhs (g
, a
);
1627 gimple_set_location (g
, gimple_location (stmt
));
1628 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1629 gimple_assign_set_rhs1 (stmt
, a
);
1637 /* Instrument loads from (non-bitfield) bool and C++ enum values
1638 to check if the memory value is outside of the range of the valid
1642 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1644 gimple
*stmt
= gsi_stmt (*gsi
);
1645 tree rhs
= gimple_assign_rhs1 (stmt
);
1646 tree type
= TREE_TYPE (rhs
);
1647 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1649 if (TREE_CODE (type
) == BOOLEAN_TYPE
1650 && sanitize_flags_p (SANITIZE_BOOL
))
1652 minv
= boolean_false_node
;
1653 maxv
= boolean_true_node
;
1655 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1656 && sanitize_flags_p (SANITIZE_ENUM
)
1657 && TREE_TYPE (type
) != NULL_TREE
1658 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1659 && (TYPE_PRECISION (TREE_TYPE (type
))
1660 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1662 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1663 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1668 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1669 HOST_WIDE_INT bitsize
, bitpos
;
1672 int volatilep
= 0, reversep
, unsignedp
= 0;
1673 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1674 &unsignedp
, &reversep
, &volatilep
);
1675 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1677 if ((VAR_P (base
) && DECL_HARD_REGISTER (base
))
1678 || (bitpos
% modebitsize
) != 0
1679 || bitsize
!= modebitsize
1680 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1681 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1684 bool ends_bb
= stmt_ends_bb_p (stmt
);
1685 location_t loc
= gimple_location (stmt
);
1686 tree lhs
= gimple_assign_lhs (stmt
);
1687 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1688 tree atype
= reference_alias_ptr_type (rhs
);
1689 gimple
*g
= gimple_build_assign (make_ssa_name (ptype
),
1690 build_fold_addr_expr (rhs
));
1691 gimple_set_location (g
, loc
);
1692 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1693 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1694 build_int_cst (atype
, 0));
1695 tree urhs
= make_ssa_name (utype
);
1698 gimple_assign_set_lhs (stmt
, urhs
);
1699 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1700 gimple_set_location (g
, loc
);
1701 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1702 gsi_insert_on_edge_immediate (e
, g
);
1703 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1705 *gsi
= gsi_for_stmt (g
);
1710 g
= gimple_build_assign (urhs
, mem
);
1711 gimple_set_location (g
, loc
);
1712 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1714 minv
= fold_convert (utype
, minv
);
1715 maxv
= fold_convert (utype
, maxv
);
1716 if (!integer_zerop (minv
))
1718 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1719 gimple_set_location (g
, loc
);
1720 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1723 gimple_stmt_iterator gsi2
= *gsi
;
1724 basic_block then_bb
, fallthru_bb
;
1725 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1726 &then_bb
, &fallthru_bb
);
1727 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1728 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1729 NULL_TREE
, NULL_TREE
);
1730 gimple_set_location (g
, loc
);
1731 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1735 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1739 gsi2
= gsi_after_labels (then_bb
);
1740 if (flag_sanitize_undefined_trap_on_error
)
1741 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1744 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1745 ubsan_type_descriptor (type
), NULL_TREE
,
1747 data
= build_fold_addr_expr_loc (loc
, data
);
1748 enum built_in_function bcode
1749 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1750 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1751 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1752 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1753 tree fn
= builtin_decl_explicit (bcode
);
1755 tree val
= ubsan_encode_value (urhs
, UBSAN_ENCODE_VALUE_GIMPLE
);
1756 val
= force_gimple_operand_gsi (&gsi2
, val
, true, NULL_TREE
, true,
1758 g
= gimple_build_call (fn
, 2, data
, val
);
1760 gimple_set_location (g
, loc
);
1761 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1762 ubsan_create_edge (g
);
1763 *gsi
= gsi_for_stmt (stmt
);
1766 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1767 new style handlers. Libubsan uses heuristics to destinguish between old and
1768 new styles and relies on these properties for filename:
1770 a) Location's filename must not be NULL.
1771 b) Location's filename must not be equal to "".
1772 c) Location's filename must not be equal to "\1".
1773 d) First two bytes of filename must not contain '\xff' symbol. */
1776 ubsan_use_new_style_p (location_t loc
)
1778 if (loc
== UNKNOWN_LOCATION
)
1781 expanded_location xloc
= expand_location (loc
);
1782 if (xloc
.file
== NULL
|| strncmp (xloc
.file
, "\1", 2) == 0
1783 || xloc
.file
[0] == '\0' || xloc
.file
[0] == '\xff'
1784 || xloc
.file
[1] == '\xff')
1790 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1791 destination, EXPR is floating-point expression. */
1794 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
)
1796 tree expr_type
= TREE_TYPE (expr
);
1797 tree t
, tt
, fn
, min
, max
;
1798 machine_mode mode
= TYPE_MODE (expr_type
);
1799 int prec
= TYPE_PRECISION (type
);
1800 bool uns_p
= TYPE_UNSIGNED (type
);
1801 if (loc
== UNKNOWN_LOCATION
)
1802 loc
= input_location
;
1804 /* Float to integer conversion first truncates toward zero, so
1805 even signed char c = 127.875f; is not problematic.
1806 Therefore, we should complain only if EXPR is unordered or smaller
1807 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1808 TYPE_MAX_VALUE + 1.0. */
1809 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1811 /* For maximum, TYPE_MAX_VALUE might not be representable
1812 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1813 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1814 either representable or infinity. */
1815 REAL_VALUE_TYPE maxval
= dconst1
;
1816 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1817 real_convert (&maxval
, mode
, &maxval
);
1818 max
= build_real (expr_type
, maxval
);
1820 /* For unsigned, assume -1.0 is always representable. */
1822 min
= build_minus_one_cst (expr_type
);
1825 /* TYPE_MIN_VALUE is generally representable (or -inf),
1826 but TYPE_MIN_VALUE - 1.0 might not be. */
1827 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1828 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1829 real_convert (&minval
, mode
, &minval
);
1830 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1831 real_convert (&minval2
, mode
, &minval2
);
1832 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1833 && !real_isinf (&minval
))
1835 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1836 rounds to TYPE_MIN_VALUE, we need to subtract
1837 more. As REAL_MODE_FORMAT (mode)->p is the number
1838 of base digits, we want to subtract a number that
1839 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1840 times smaller than minval. */
1842 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1843 SET_REAL_EXP (&minval2
,
1844 REAL_EXP (&minval2
) + prec
- 1
1845 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1846 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1847 real_convert (&minval2
, mode
, &minval2
);
1849 min
= build_real (expr_type
, minval2
);
1852 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1854 /* For _Decimal128 up to 34 decimal digits, - sign,
1855 dot, e, exponent. */
1858 int p
= REAL_MODE_FORMAT (mode
)->p
;
1859 REAL_VALUE_TYPE maxval
, minval
;
1861 /* Use mpfr_snprintf rounding to compute the smallest
1862 representable decimal number greater or equal than
1863 1 << (prec - !uns_p). */
1864 mpfr_init2 (m
, prec
+ 2);
1865 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1866 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1867 decimal_real_from_string (&maxval
, buf
);
1868 max
= build_real (expr_type
, maxval
);
1870 /* For unsigned, assume -1.0 is always representable. */
1872 min
= build_minus_one_cst (expr_type
);
1875 /* Use mpfr_snprintf rounding to compute the largest
1876 representable decimal number less or equal than
1877 (-1 << (prec - 1)) - 1. */
1878 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1879 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1880 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1881 decimal_real_from_string (&minval
, buf
);
1882 min
= build_real (expr_type
, minval
);
1889 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1890 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1891 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
);
1892 if (integer_zerop (t
))
1895 if (flag_sanitize_undefined_trap_on_error
)
1896 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1899 location_t
*loc_ptr
= NULL
;
1900 unsigned num_locations
= 0;
1901 /* Figure out if we can propagate location to ubsan_data and use new
1902 style handlers in libubsan. */
1903 if (ubsan_use_new_style_p (loc
))
1908 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1909 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data",
1910 num_locations
, loc_ptr
,
1911 ubsan_type_descriptor (expr_type
),
1912 ubsan_type_descriptor (type
), NULL_TREE
,
1914 enum built_in_function bcode
1915 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1916 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1917 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1918 fn
= builtin_decl_explicit (bcode
);
1919 fn
= build_call_expr_loc (loc
, fn
, 2,
1920 build_fold_addr_expr_loc (loc
, data
),
1921 ubsan_encode_value (expr
));
1924 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1927 /* Instrument values passed to function arguments with nonnull attribute. */
1930 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1932 gimple
*stmt
= gsi_stmt (*gsi
);
1934 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1935 while for nonnull sanitization it is clear. */
1936 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1937 flag_delete_null_pointer_checks
= 1;
1938 loc
[0] = gimple_location (stmt
);
1939 loc
[1] = UNKNOWN_LOCATION
;
1940 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1942 tree arg
= gimple_call_arg (stmt
, i
);
1943 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1944 && infer_nonnull_range_by_attribute (stmt
, arg
))
1947 if (!is_gimple_val (arg
))
1949 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1950 gimple_set_location (g
, loc
[0]);
1951 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1952 arg
= gimple_assign_lhs (g
);
1955 basic_block then_bb
, fallthru_bb
;
1956 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1957 &then_bb
, &fallthru_bb
);
1958 g
= gimple_build_cond (EQ_EXPR
, arg
,
1959 build_zero_cst (TREE_TYPE (arg
)),
1960 NULL_TREE
, NULL_TREE
);
1961 gimple_set_location (g
, loc
[0]);
1962 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1964 *gsi
= gsi_after_labels (then_bb
);
1965 if (flag_sanitize_undefined_trap_on_error
)
1966 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1969 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1971 build_int_cst (integer_type_node
,
1974 data
= build_fold_addr_expr_loc (loc
[0], data
);
1975 enum built_in_function bcode
1976 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1977 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1978 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1979 tree fn
= builtin_decl_explicit (bcode
);
1981 g
= gimple_build_call (fn
, 1, data
);
1983 gimple_set_location (g
, loc
[0]);
1984 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1985 ubsan_create_edge (g
);
1987 *gsi
= gsi_for_stmt (stmt
);
1989 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1992 /* Instrument returns in functions with returns_nonnull attribute. */
1995 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1997 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
1999 tree arg
= gimple_return_retval (stmt
);
2000 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
2001 while for nonnull return sanitization it is clear. */
2002 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
2003 flag_delete_null_pointer_checks
= 1;
2004 loc
[0] = gimple_location (stmt
);
2005 loc
[1] = UNKNOWN_LOCATION
;
2007 && POINTER_TYPE_P (TREE_TYPE (arg
))
2008 && is_gimple_val (arg
)
2009 && infer_nonnull_range_by_attribute (stmt
, arg
))
2011 basic_block then_bb
, fallthru_bb
;
2012 *gsi
= create_cond_insert_point (gsi
, true, false, true,
2013 &then_bb
, &fallthru_bb
);
2014 gimple
*g
= gimple_build_cond (EQ_EXPR
, arg
,
2015 build_zero_cst (TREE_TYPE (arg
)),
2016 NULL_TREE
, NULL_TREE
);
2017 gimple_set_location (g
, loc
[0]);
2018 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
2020 *gsi
= gsi_after_labels (then_bb
);
2021 if (flag_sanitize_undefined_trap_on_error
)
2022 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
2025 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
2026 2, loc
, NULL_TREE
, NULL_TREE
);
2027 data
= build_fold_addr_expr_loc (loc
[0], data
);
2028 enum built_in_function bcode
2029 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
2030 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
2031 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
2032 tree fn
= builtin_decl_explicit (bcode
);
2034 g
= gimple_build_call (fn
, 1, data
);
2036 gimple_set_location (g
, loc
[0]);
2037 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
2038 ubsan_create_edge (g
);
2039 *gsi
= gsi_for_stmt (stmt
);
2041 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
2044 /* Instrument memory references. Here we check whether the pointer
2045 points to an out-of-bounds location. */
2048 instrument_object_size (gimple_stmt_iterator
*gsi
, tree t
, bool is_lhs
)
2050 gimple
*stmt
= gsi_stmt (*gsi
);
2051 location_t loc
= gimple_location (stmt
);
2053 tree index
= NULL_TREE
;
2054 HOST_WIDE_INT size_in_bytes
;
2056 type
= TREE_TYPE (t
);
2057 if (VOID_TYPE_P (type
))
2060 switch (TREE_CODE (t
))
2063 if (TREE_CODE (t
) == COMPONENT_REF
2064 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
2066 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
2067 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
2068 repr
, TREE_OPERAND (t
, 2));
2072 index
= TREE_OPERAND (t
, 1);
2084 size_in_bytes
= int_size_in_bytes (type
);
2085 if (size_in_bytes
<= 0)
2088 HOST_WIDE_INT bitsize
, bitpos
;
2091 int volatilep
= 0, reversep
, unsignedp
= 0;
2092 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
2093 &unsignedp
, &reversep
, &volatilep
);
2095 if (bitpos
% BITS_PER_UNIT
!= 0
2096 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
2099 bool decl_p
= DECL_P (inner
);
2103 if (DECL_REGISTER (inner
))
2107 else if (TREE_CODE (inner
) == MEM_REF
)
2108 base
= TREE_OPERAND (inner
, 0);
2111 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
2113 while (TREE_CODE (base
) == SSA_NAME
)
2115 gimple
*def_stmt
= SSA_NAME_DEF_STMT (base
);
2116 if (gimple_assign_ssa_name_copy_p (def_stmt
)
2117 || (gimple_assign_cast_p (def_stmt
)
2118 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
2119 || (is_gimple_assign (def_stmt
)
2120 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
2122 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
2123 if (TREE_CODE (rhs1
) == SSA_NAME
2124 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
2133 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
2137 tree base_addr
= base
;
2138 gimple
*bos_stmt
= NULL
;
2140 base_addr
= build1 (ADDR_EXPR
,
2141 build_pointer_type (TREE_TYPE (base
)), base
);
2142 unsigned HOST_WIDE_INT size
;
2143 if (compute_builtin_object_size (base_addr
, 0, &size
))
2144 sizet
= build_int_cst (sizetype
, size
);
2147 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
2148 loc
= input_location
;
2149 /* Generate __builtin_object_size call. */
2150 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
2151 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
2153 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
2155 /* If the call above didn't end up being an integer constant, go one
2156 statement back and get the __builtin_object_size stmt. Save it,
2157 we might need it later. */
2158 if (SSA_VAR_P (sizet
))
2161 bos_stmt
= gsi_stmt (*gsi
);
2163 /* Move on to where we were. */
2170 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
2172 /* ptr + sizeof (*ptr) - base */
2173 t
= fold_build2 (MINUS_EXPR
, sizetype
,
2174 fold_convert (pointer_sized_int_node
, ptr
),
2175 fold_convert (pointer_sized_int_node
, base_addr
));
2176 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
2178 /* Perhaps we can omit the check. */
2179 if (TREE_CODE (t
) == INTEGER_CST
2180 && TREE_CODE (sizet
) == INTEGER_CST
2181 && tree_int_cst_le (t
, sizet
))
2184 if (index
!= NULL_TREE
2185 && TREE_CODE (index
) == SSA_NAME
2186 && TREE_CODE (sizet
) == INTEGER_CST
)
2188 gimple
*def
= SSA_NAME_DEF_STMT (index
);
2189 if (is_gimple_assign (def
)
2190 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
2191 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
2193 tree cst
= gimple_assign_rhs2 (def
);
2194 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
2195 TYPE_SIZE_UNIT (type
));
2196 if (tree_int_cst_sgn (cst
) >= 0
2197 && tree_int_cst_lt (cst
, sz
))
2202 if (bos_stmt
&& gimple_call_builtin_p (bos_stmt
, BUILT_IN_OBJECT_SIZE
))
2203 ubsan_create_edge (bos_stmt
);
2205 /* We have to emit the check. */
2206 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
2208 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
2210 tree ckind
= build_int_cst (unsigned_char_type_node
,
2211 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
2212 gimple
*g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
2213 ptr
, t
, sizet
, ckind
);
2214 gimple_set_location (g
, loc
);
2215 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
2220 const pass_data pass_data_ubsan
=
2222 GIMPLE_PASS
, /* type */
2224 OPTGROUP_NONE
, /* optinfo_flags */
2225 TV_TREE_UBSAN
, /* tv_id */
2226 ( PROP_cfg
| PROP_ssa
), /* properties_required */
2227 0, /* properties_provided */
2228 0, /* properties_destroyed */
2229 0, /* todo_flags_start */
2230 TODO_update_ssa
, /* todo_flags_finish */
2233 class pass_ubsan
: public gimple_opt_pass
2236 pass_ubsan (gcc::context
*ctxt
)
2237 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
2240 /* opt_pass methods: */
2241 virtual bool gate (function
*)
2243 return sanitize_flags_p ((SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
2244 | SANITIZE_BOOL
| SANITIZE_ENUM
2245 | SANITIZE_ALIGNMENT
2246 | SANITIZE_NONNULL_ATTRIBUTE
2247 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
2248 | SANITIZE_OBJECT_SIZE
2249 | SANITIZE_POINTER_OVERFLOW
));
2252 virtual unsigned int execute (function
*);
2254 }; // class pass_ubsan
2257 pass_ubsan::execute (function
*fun
)
2260 gimple_stmt_iterator gsi
;
2261 unsigned int ret
= 0;
2263 initialize_sanitizer_builtins ();
2265 FOR_EACH_BB_FN (bb
, fun
)
2267 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
2269 gimple
*stmt
= gsi_stmt (gsi
);
2270 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
2276 if ((sanitize_flags_p (SANITIZE_SI_OVERFLOW
, fun
->decl
))
2277 && is_gimple_assign (stmt
))
2278 instrument_si_overflow (gsi
);
2280 if (sanitize_flags_p (SANITIZE_NULL
| SANITIZE_ALIGNMENT
, fun
->decl
))
2282 if (gimple_store_p (stmt
))
2283 instrument_null (gsi
, gimple_get_lhs (stmt
), true);
2284 if (gimple_assign_single_p (stmt
))
2285 instrument_null (gsi
, gimple_assign_rhs1 (stmt
), false);
2286 if (is_gimple_call (stmt
))
2288 unsigned args_num
= gimple_call_num_args (stmt
);
2289 for (unsigned i
= 0; i
< args_num
; ++i
)
2291 tree arg
= gimple_call_arg (stmt
, i
);
2292 if (is_gimple_reg (arg
) || is_gimple_min_invariant (arg
))
2294 instrument_null (gsi
, arg
, false);
2299 if (sanitize_flags_p (SANITIZE_BOOL
| SANITIZE_ENUM
, fun
->decl
)
2300 && gimple_assign_load_p (stmt
))
2302 instrument_bool_enum_load (&gsi
);
2303 bb
= gimple_bb (stmt
);
2306 if (sanitize_flags_p (SANITIZE_NONNULL_ATTRIBUTE
, fun
->decl
)
2307 && is_gimple_call (stmt
)
2308 && !gimple_call_internal_p (stmt
))
2310 instrument_nonnull_arg (&gsi
);
2311 bb
= gimple_bb (stmt
);
2314 if (sanitize_flags_p (SANITIZE_RETURNS_NONNULL_ATTRIBUTE
, fun
->decl
)
2315 && gimple_code (stmt
) == GIMPLE_RETURN
)
2317 instrument_nonnull_return (&gsi
);
2318 bb
= gimple_bb (stmt
);
2321 if (sanitize_flags_p (SANITIZE_OBJECT_SIZE
, fun
->decl
))
2323 if (gimple_store_p (stmt
))
2324 instrument_object_size (&gsi
, gimple_get_lhs (stmt
), true);
2325 if (gimple_assign_load_p (stmt
))
2326 instrument_object_size (&gsi
, gimple_assign_rhs1 (stmt
),
2328 if (is_gimple_call (stmt
))
2330 unsigned args_num
= gimple_call_num_args (stmt
);
2331 for (unsigned i
= 0; i
< args_num
; ++i
)
2333 tree arg
= gimple_call_arg (stmt
, i
);
2334 if (is_gimple_reg (arg
) || is_gimple_min_invariant (arg
))
2336 instrument_object_size (&gsi
, arg
, false);
2341 if (sanitize_flags_p (SANITIZE_POINTER_OVERFLOW
, fun
->decl
))
2343 if (is_gimple_assign (stmt
)
2344 && gimple_assign_rhs_code (stmt
) == POINTER_PLUS_EXPR
)
2345 instrument_pointer_overflow (&gsi
,
2346 gimple_assign_rhs1 (stmt
),
2347 gimple_assign_rhs2 (stmt
));
2348 if (gimple_store_p (stmt
))
2349 maybe_instrument_pointer_overflow (&gsi
,
2350 gimple_get_lhs (stmt
));
2351 if (gimple_assign_single_p (stmt
))
2352 maybe_instrument_pointer_overflow (&gsi
,
2353 gimple_assign_rhs1 (stmt
));
2354 if (is_gimple_call (stmt
))
2356 unsigned args_num
= gimple_call_num_args (stmt
);
2357 for (unsigned i
= 0; i
< args_num
; ++i
)
2359 tree arg
= gimple_call_arg (stmt
, i
);
2360 if (is_gimple_reg (arg
))
2362 maybe_instrument_pointer_overflow (&gsi
, arg
);
2369 if (gimple_purge_dead_eh_edges (bb
))
2370 ret
= TODO_cleanup_cfg
;
2378 make_pass_ubsan (gcc::context
*ctxt
)
2380 return new pass_ubsan (ctxt
);
2383 #include "gt-ubsan.h"