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"
49 /* Map from a tree to a VAR_DECL tree. */
51 struct GTY((for_user
)) tree_type_map
{
52 struct tree_map_base type
;
56 struct tree_type_map_cache_hasher
: ggc_cache_ptr_hash
<tree_type_map
>
58 static inline hashval_t
59 hash (tree_type_map
*t
)
61 return TYPE_UID (t
->type
.from
);
65 equal (tree_type_map
*a
, tree_type_map
*b
)
67 return a
->type
.from
== b
->type
.from
;
71 keep_cache_entry (tree_type_map
*&m
)
73 return ggc_marked_p (m
->type
.from
);
78 hash_table
<tree_type_map_cache_hasher
> *decl_tree_for_type
;
80 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
83 decl_for_type_lookup (tree type
)
85 /* If the hash table is not initialized yet, create it now. */
86 if (decl_tree_for_type
== NULL
)
89 = hash_table
<tree_type_map_cache_hasher
>::create_ggc (10);
90 /* That also means we don't have to bother with the lookup. */
94 struct tree_type_map
*h
, in
;
97 h
= decl_tree_for_type
->find_with_hash (&in
, TYPE_UID (type
));
98 return h
? h
->decl
: NULL_TREE
;
101 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
104 decl_for_type_insert (tree type
, tree decl
)
106 struct tree_type_map
*h
;
108 h
= ggc_alloc
<tree_type_map
> ();
111 *decl_tree_for_type
->find_slot_with_hash (h
, TYPE_UID (type
), INSERT
) = h
;
114 /* Helper routine, which encodes a value in the pointer_sized_int_node.
115 Arguments with precision <= POINTER_SIZE are passed directly,
116 the rest is passed by reference. T is a value we are to encode.
117 PHASE determines when this function is called. */
120 ubsan_encode_value (tree t
, enum ubsan_encode_value_phase phase
)
122 tree type
= TREE_TYPE (t
);
123 const unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
124 if (bitsize
<= POINTER_SIZE
)
125 switch (TREE_CODE (type
))
130 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
133 tree itype
= build_nonstandard_integer_type (bitsize
, true);
134 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
135 return fold_convert (pointer_sized_int_node
, t
);
142 if (!DECL_P (t
) || !TREE_ADDRESSABLE (t
))
144 /* The reason for this is that we don't want to pessimize
145 code by making vars unnecessarily addressable. */
147 if (phase
!= UBSAN_ENCODE_VALUE_GENERIC
)
149 var
= create_tmp_var (type
);
150 mark_addressable (var
);
154 var
= create_tmp_var_raw (type
);
155 TREE_ADDRESSABLE (var
) = 1;
157 if (phase
== UBSAN_ENCODE_VALUE_RTL
)
160 = assign_stack_temp_for_type (TYPE_MODE (type
),
161 GET_MODE_SIZE (TYPE_MODE (type
)),
163 SET_DECL_RTL (var
, mem
);
164 expand_assignment (var
, t
, false);
165 return build_fold_addr_expr (var
);
167 if (phase
!= UBSAN_ENCODE_VALUE_GENERIC
)
169 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
170 t
= build_fold_addr_expr (var
);
171 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
175 var
= build4 (TARGET_EXPR
, type
, var
, t
, NULL_TREE
, NULL_TREE
);
176 return build_fold_addr_expr (var
);
180 return build_fold_addr_expr (t
);
184 /* Cached ubsan_get_type_descriptor_type () return value. */
185 static GTY(()) tree ubsan_type_descriptor_type
;
188 struct __ubsan_type_descriptor
190 unsigned short __typekind;
191 unsigned short __typeinfo;
197 ubsan_get_type_descriptor_type (void)
199 static const char *field_names
[3]
200 = { "__typekind", "__typeinfo", "__typename" };
203 if (ubsan_type_descriptor_type
)
204 return ubsan_type_descriptor_type
;
206 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
207 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
209 ret
= make_node (RECORD_TYPE
);
210 for (int i
= 0; i
< 3; i
++)
212 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
213 get_identifier (field_names
[i
]),
214 (i
== 2) ? flex_arr_type
215 : short_unsigned_type_node
);
216 DECL_CONTEXT (fields
[i
]) = ret
;
218 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
220 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
221 get_identifier ("__ubsan_type_descriptor"),
223 DECL_IGNORED_P (type_decl
) = 1;
224 DECL_ARTIFICIAL (type_decl
) = 1;
225 TYPE_FIELDS (ret
) = fields
[0];
226 TYPE_NAME (ret
) = type_decl
;
227 TYPE_STUB_DECL (ret
) = type_decl
;
229 ubsan_type_descriptor_type
= ret
;
233 /* Cached ubsan_get_source_location_type () return value. */
234 static GTY(()) tree ubsan_source_location_type
;
237 struct __ubsan_source_location
239 const char *__filename;
241 unsigned int __column;
246 ubsan_get_source_location_type (void)
248 static const char *field_names
[3]
249 = { "__filename", "__line", "__column" };
251 if (ubsan_source_location_type
)
252 return ubsan_source_location_type
;
254 tree const_char_type
= build_qualified_type (char_type_node
,
257 ret
= make_node (RECORD_TYPE
);
258 for (int i
= 0; i
< 3; i
++)
260 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
261 get_identifier (field_names
[i
]),
262 (i
== 0) ? build_pointer_type (const_char_type
)
263 : unsigned_type_node
);
264 DECL_CONTEXT (fields
[i
]) = ret
;
266 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
268 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
269 get_identifier ("__ubsan_source_location"),
271 DECL_IGNORED_P (type_decl
) = 1;
272 DECL_ARTIFICIAL (type_decl
) = 1;
273 TYPE_FIELDS (ret
) = fields
[0];
274 TYPE_NAME (ret
) = type_decl
;
275 TYPE_STUB_DECL (ret
) = type_decl
;
277 ubsan_source_location_type
= ret
;
281 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
282 type with its fields filled from a location_t LOC. */
285 ubsan_source_location (location_t loc
)
287 expanded_location xloc
;
288 tree type
= ubsan_get_source_location_type ();
290 xloc
= expand_location (loc
);
292 if (xloc
.file
== NULL
)
294 str
= build_int_cst (ptr_type_node
, 0);
300 /* Fill in the values from LOC. */
301 size_t len
= strlen (xloc
.file
) + 1;
302 str
= build_string (len
, xloc
.file
);
303 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
304 TREE_READONLY (str
) = 1;
305 TREE_STATIC (str
) = 1;
306 str
= build_fold_addr_expr (str
);
308 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
309 build_int_cst (unsigned_type_node
,
310 xloc
.line
), NULL_TREE
,
311 build_int_cst (unsigned_type_node
,
313 TREE_CONSTANT (ctor
) = 1;
314 TREE_STATIC (ctor
) = 1;
319 /* This routine returns a magic number for TYPE. */
321 static unsigned short
322 get_ubsan_type_info_for_type (tree type
)
324 if (TREE_CODE (type
) == REAL_TYPE
)
325 return tree_to_uhwi (TYPE_SIZE (type
));
326 else if (INTEGRAL_TYPE_P (type
))
328 int prec
= exact_log2 (tree_to_uhwi (TYPE_SIZE (type
)));
329 gcc_assert (prec
!= -1);
330 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
336 /* Counters for internal labels. ubsan_ids[0] for Lubsan_type,
337 ubsan_ids[1] for Lubsan_data labels. */
338 static GTY(()) unsigned int ubsan_ids
[2];
340 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
341 descriptor. It first looks into the hash table; if not found,
342 create the VAR_DECL, put it into the hash table and return the
343 ADDR_EXPR of it. TYPE describes a particular type. PSTYLE is
344 an enum controlling how we want to print the type. */
347 ubsan_type_descriptor (tree type
, enum ubsan_print_style pstyle
)
349 /* See through any typedefs. */
350 type
= TYPE_MAIN_VARIANT (type
);
352 tree decl
= decl_for_type_lookup (type
);
353 /* It is possible that some of the earlier created DECLs were found
354 unused, in that case they weren't emitted and varpool_node::get
355 returns NULL node on them. But now we really need them. Thus,
357 if (decl
!= NULL_TREE
&& varpool_node::get (decl
))
358 return build_fold_addr_expr (decl
);
360 tree dtype
= ubsan_get_type_descriptor_type ();
362 const char *tname
= NULL
;
363 pretty_printer pretty_name
;
364 unsigned char deref_depth
= 0;
365 unsigned short tkind
, tinfo
;
367 /* Get the name of the type, or the name of the pointer type. */
368 if (pstyle
== UBSAN_PRINT_POINTER
)
370 gcc_assert (POINTER_TYPE_P (type
));
371 type2
= TREE_TYPE (type
);
373 /* Remove any '*' operators from TYPE. */
374 while (POINTER_TYPE_P (type2
))
375 deref_depth
++, type2
= TREE_TYPE (type2
);
377 if (TREE_CODE (type2
) == METHOD_TYPE
)
378 type2
= TYPE_METHOD_BASETYPE (type2
);
381 /* If an array, get its type. */
382 type2
= strip_array_types (type2
);
384 if (pstyle
== UBSAN_PRINT_ARRAY
)
386 while (POINTER_TYPE_P (type2
))
387 deref_depth
++, type2
= TREE_TYPE (type2
);
390 if (TYPE_NAME (type2
) != NULL
)
392 if (TREE_CODE (TYPE_NAME (type2
)) == IDENTIFIER_NODE
)
393 tname
= IDENTIFIER_POINTER (TYPE_NAME (type2
));
394 else if (DECL_NAME (TYPE_NAME (type2
)) != NULL
)
395 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2
)));
399 /* We weren't able to determine the type name. */
402 if (pstyle
== UBSAN_PRINT_POINTER
)
404 pp_printf (&pretty_name
, "'%s%s%s%s%s%s%s",
405 TYPE_VOLATILE (type2
) ? "volatile " : "",
406 TYPE_READONLY (type2
) ? "const " : "",
407 TYPE_RESTRICT (type2
) ? "restrict " : "",
408 TYPE_ATOMIC (type2
) ? "_Atomic " : "",
409 TREE_CODE (type2
) == RECORD_TYPE
411 : TREE_CODE (type2
) == UNION_TYPE
412 ? "union " : "", tname
,
413 deref_depth
== 0 ? "" : " ");
414 while (deref_depth
-- > 0)
415 pp_star (&pretty_name
);
416 pp_quote (&pretty_name
);
418 else if (pstyle
== UBSAN_PRINT_ARRAY
)
420 /* Pretty print the array dimensions. */
421 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
423 pp_printf (&pretty_name
, "'%s ", tname
);
424 while (deref_depth
-- > 0)
425 pp_star (&pretty_name
);
426 while (TREE_CODE (t
) == ARRAY_TYPE
)
428 pp_left_bracket (&pretty_name
);
429 tree dom
= TYPE_DOMAIN (t
);
431 && TYPE_MAX_VALUE (dom
) != NULL_TREE
432 && TREE_CODE (TYPE_MAX_VALUE (dom
)) == INTEGER_CST
)
434 if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom
))
435 && tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1 != 0)
436 pp_printf (&pretty_name
, HOST_WIDE_INT_PRINT_DEC
,
437 tree_to_uhwi (TYPE_MAX_VALUE (dom
)) + 1);
439 pp_wide_int (&pretty_name
,
440 wi::add (wi::to_widest (TYPE_MAX_VALUE (dom
)), 1),
441 TYPE_SIGN (TREE_TYPE (dom
)));
444 /* ??? We can't determine the variable name; print VLA unspec. */
445 pp_star (&pretty_name
);
446 pp_right_bracket (&pretty_name
);
449 pp_quote (&pretty_name
);
451 /* Save the tree with stripped types. */
455 pp_printf (&pretty_name
, "'%s'", tname
);
457 switch (TREE_CODE (type
))
465 /* FIXME: libubsan right now only supports float, double and
466 long double type formats. */
467 if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
)
468 || TYPE_MODE (type
) == TYPE_MODE (double_type_node
)
469 || TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
478 tinfo
= get_ubsan_type_info_for_type (type
);
480 /* Create a new VAR_DECL of type descriptor. */
481 const char *tmp
= pp_formatted_text (&pretty_name
);
482 size_t len
= strlen (tmp
) + 1;
483 tree str
= build_string (len
, tmp
);
484 TREE_TYPE (str
) = build_array_type_nelts (char_type_node
, len
);
485 TREE_READONLY (str
) = 1;
486 TREE_STATIC (str
) = 1;
489 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", ubsan_ids
[0]++);
490 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
492 TREE_STATIC (decl
) = 1;
493 TREE_PUBLIC (decl
) = 0;
494 DECL_ARTIFICIAL (decl
) = 1;
495 DECL_IGNORED_P (decl
) = 1;
496 DECL_EXTERNAL (decl
) = 0;
498 = size_binop (PLUS_EXPR
, DECL_SIZE (decl
), TYPE_SIZE (TREE_TYPE (str
)));
499 DECL_SIZE_UNIT (decl
)
500 = size_binop (PLUS_EXPR
, DECL_SIZE_UNIT (decl
),
501 TYPE_SIZE_UNIT (TREE_TYPE (str
)));
503 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
504 build_int_cst (short_unsigned_type_node
,
506 build_int_cst (short_unsigned_type_node
,
507 tinfo
), NULL_TREE
, str
);
508 TREE_CONSTANT (ctor
) = 1;
509 TREE_STATIC (ctor
) = 1;
510 DECL_INITIAL (decl
) = ctor
;
511 varpool_node::finalize_decl (decl
);
513 /* Save the VAR_DECL into the hash table. */
514 decl_for_type_insert (type
, decl
);
516 return build_fold_addr_expr (decl
);
519 /* Create a structure for the ubsan library. NAME is a name of the new
520 structure. LOCCNT is number of locations, PLOC points to array of
521 locations. The arguments in ... are of __ubsan_type_descriptor type
522 and there are at most two of them, followed by NULL_TREE, followed
523 by optional extra arguments and another NULL_TREE. */
526 ubsan_create_data (const char *name
, int loccnt
, const location_t
*ploc
, ...)
531 vec
<tree
, va_gc
> *saved_args
= NULL
;
535 /* It is possible that PCH zapped table with definitions of sanitizer
536 builtins. Reinitialize them if needed. */
537 initialize_sanitizer_builtins ();
539 /* Firstly, create a pointer to type descriptor type. */
540 tree td_type
= ubsan_get_type_descriptor_type ();
541 td_type
= build_pointer_type (td_type
);
543 /* Create the structure type. */
544 ret
= make_node (RECORD_TYPE
);
545 for (j
= 0; j
< loccnt
; j
++)
547 gcc_checking_assert (i
< 2);
548 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
549 ubsan_get_source_location_type ());
550 DECL_CONTEXT (fields
[i
]) = ret
;
552 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
556 va_start (args
, ploc
);
557 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
558 i
++, t
= va_arg (args
, tree
))
560 gcc_checking_assert (i
< 4);
561 /* Save the tree arguments for later use. */
562 vec_safe_push (saved_args
, t
);
563 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
565 DECL_CONTEXT (fields
[i
]) = ret
;
567 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
570 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
571 i
++, t
= va_arg (args
, tree
))
573 gcc_checking_assert (i
< 6);
574 /* Save the tree arguments for later use. */
575 vec_safe_push (saved_args
, t
);
576 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
578 DECL_CONTEXT (fields
[i
]) = ret
;
580 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
584 tree type_decl
= build_decl (input_location
, TYPE_DECL
,
585 get_identifier (name
), ret
);
586 DECL_IGNORED_P (type_decl
) = 1;
587 DECL_ARTIFICIAL (type_decl
) = 1;
588 TYPE_FIELDS (ret
) = fields
[0];
589 TYPE_NAME (ret
) = type_decl
;
590 TYPE_STUB_DECL (ret
) = type_decl
;
593 /* Now, fill in the type. */
595 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_ids
[1]++);
596 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
598 TREE_STATIC (var
) = 1;
599 TREE_PUBLIC (var
) = 0;
600 DECL_ARTIFICIAL (var
) = 1;
601 DECL_IGNORED_P (var
) = 1;
602 DECL_EXTERNAL (var
) = 0;
604 vec
<constructor_elt
, va_gc
> *v
;
606 tree ctor
= build_constructor (ret
, v
);
608 /* If desirable, set the __ubsan_source_location element. */
609 for (j
= 0; j
< loccnt
; j
++)
611 location_t loc
= LOCATION_LOCUS (ploc
[j
]);
612 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
615 size_t nelts
= vec_safe_length (saved_args
);
616 for (i
= 0; i
< nelts
; i
++)
618 t
= (*saved_args
)[i
];
619 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
622 TREE_CONSTANT (ctor
) = 1;
623 TREE_STATIC (ctor
) = 1;
624 DECL_INITIAL (var
) = ctor
;
625 varpool_node::finalize_decl (var
);
630 /* Instrument the __builtin_unreachable call. We just call the libubsan
634 ubsan_instrument_unreachable (gimple_stmt_iterator
*gsi
)
637 location_t loc
= gimple_location (gsi_stmt (*gsi
));
639 if (flag_sanitize_undefined_trap_on_error
)
640 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
643 tree data
= ubsan_create_data ("__ubsan_unreachable_data", 1, &loc
,
644 NULL_TREE
, NULL_TREE
);
645 data
= build_fold_addr_expr_loc (loc
, data
);
647 = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
648 g
= gimple_build_call (fn
, 1, data
);
650 gimple_set_location (g
, loc
);
651 gsi_replace (gsi
, g
, false);
655 /* Return true if T is a call to a libubsan routine. */
658 is_ubsan_builtin_p (tree t
)
660 return TREE_CODE (t
) == FUNCTION_DECL
661 && DECL_BUILT_IN_CLASS (t
) == BUILT_IN_NORMAL
662 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
663 "__builtin___ubsan_", 18) == 0;
666 /* Create a callgraph edge for statement STMT. */
669 ubsan_create_edge (gimple
*stmt
)
671 gcall
*call_stmt
= dyn_cast
<gcall
*> (stmt
);
672 basic_block bb
= gimple_bb (stmt
);
673 int freq
= compute_call_stmt_bb_frequency (current_function_decl
, bb
);
674 cgraph_node
*node
= cgraph_node::get (current_function_decl
);
675 tree decl
= gimple_call_fndecl (call_stmt
);
677 node
->create_edge (cgraph_node::get_create (decl
), call_stmt
, bb
->count
,
681 /* Expand the UBSAN_BOUNDS special builtin function. */
684 ubsan_expand_bounds_ifn (gimple_stmt_iterator
*gsi
)
686 gimple
*stmt
= gsi_stmt (*gsi
);
687 location_t loc
= gimple_location (stmt
);
688 gcc_assert (gimple_call_num_args (stmt
) == 3);
690 /* Pick up the arguments of the UBSAN_BOUNDS call. */
691 tree type
= TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt
, 0)));
692 tree index
= gimple_call_arg (stmt
, 1);
693 tree orig_index
= index
;
694 tree bound
= gimple_call_arg (stmt
, 2);
696 gimple_stmt_iterator gsi_orig
= *gsi
;
698 /* Create condition "if (index > bound)". */
699 basic_block then_bb
, fallthru_bb
;
700 gimple_stmt_iterator cond_insert_point
701 = create_cond_insert_point (gsi
, false, false, true,
702 &then_bb
, &fallthru_bb
);
703 index
= fold_convert (TREE_TYPE (bound
), index
);
704 index
= force_gimple_operand_gsi (&cond_insert_point
, index
,
706 false, GSI_NEW_STMT
);
707 gimple
*g
= gimple_build_cond (GT_EXPR
, index
, bound
, NULL_TREE
, NULL_TREE
);
708 gimple_set_location (g
, loc
);
709 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
711 /* Generate __ubsan_handle_out_of_bounds call. */
712 *gsi
= gsi_after_labels (then_bb
);
713 if (flag_sanitize_undefined_trap_on_error
)
714 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
718 = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc
,
719 ubsan_type_descriptor (type
, UBSAN_PRINT_ARRAY
),
720 ubsan_type_descriptor (TREE_TYPE (orig_index
)),
721 NULL_TREE
, NULL_TREE
);
722 data
= build_fold_addr_expr_loc (loc
, data
);
723 enum built_in_function bcode
724 = (flag_sanitize_recover
& SANITIZE_BOUNDS
)
725 ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
726 : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT
;
727 tree fn
= builtin_decl_explicit (bcode
);
728 tree val
= ubsan_encode_value (orig_index
, UBSAN_ENCODE_VALUE_GIMPLE
);
729 val
= force_gimple_operand_gsi (gsi
, val
, true, NULL_TREE
, true,
731 g
= gimple_build_call (fn
, 2, data
, val
);
733 gimple_set_location (g
, loc
);
734 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
736 /* Get rid of the UBSAN_BOUNDS call from the IR. */
737 unlink_stmt_vdef (stmt
);
738 gsi_remove (&gsi_orig
, true);
740 /* Point GSI to next logical statement. */
741 *gsi
= gsi_start_bb (fallthru_bb
);
745 /* Expand UBSAN_NULL internal call. The type is kept on the ckind
746 argument which is a constant, because the middle-end treats pointer
747 conversions as useless and therefore the type of the first argument
748 could be changed to any other pointer type. */
751 ubsan_expand_null_ifn (gimple_stmt_iterator
*gsip
)
753 gimple_stmt_iterator gsi
= *gsip
;
754 gimple
*stmt
= gsi_stmt (gsi
);
755 location_t loc
= gimple_location (stmt
);
756 gcc_assert (gimple_call_num_args (stmt
) == 3);
757 tree ptr
= gimple_call_arg (stmt
, 0);
758 tree ckind
= gimple_call_arg (stmt
, 1);
759 tree align
= gimple_call_arg (stmt
, 2);
760 tree check_align
= NULL_TREE
;
763 basic_block cur_bb
= gsi_bb (gsi
);
766 if (!integer_zerop (align
))
768 unsigned int ptralign
= get_pointer_alignment (ptr
) / BITS_PER_UNIT
;
769 if (compare_tree_int (align
, ptralign
) == 1)
771 check_align
= make_ssa_name (pointer_sized_int_node
);
772 g
= gimple_build_assign (check_align
, NOP_EXPR
, ptr
);
773 gimple_set_location (g
, loc
);
774 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
777 check_null
= sanitize_flags_p (SANITIZE_NULL
);
779 if (check_align
== NULL_TREE
&& !check_null
)
781 gsi_remove (gsip
, true);
782 /* Unlink the UBSAN_NULLs vops before replacing it. */
783 unlink_stmt_vdef (stmt
);
787 /* Split the original block holding the pointer dereference. */
788 edge e
= split_block (cur_bb
, stmt
);
790 /* Get a hold on the 'condition block', the 'then block' and the
792 basic_block cond_bb
= e
->src
;
793 basic_block fallthru_bb
= e
->dest
;
794 basic_block then_bb
= create_empty_bb (cond_bb
);
795 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
796 loops_state_set (LOOPS_NEED_FIXUP
);
798 /* Make an edge coming from the 'cond block' into the 'then block';
799 this edge is unlikely taken, so set up the probability accordingly. */
800 e
= make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
801 e
->probability
= PROB_VERY_UNLIKELY
;
803 /* Connect 'then block' with the 'else block'. This is needed
804 as the ubsan routines we call in the 'then block' are not noreturn.
805 The 'then block' only has one outcoming edge. */
806 make_single_succ_edge (then_bb
, fallthru_bb
, EDGE_FALLTHRU
);
808 /* Set up the fallthrough basic block. */
809 e
= find_edge (cond_bb
, fallthru_bb
);
810 e
->flags
= EDGE_FALSE_VALUE
;
811 e
->count
= cond_bb
->count
;
812 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
814 /* Update dominance info for the newly created then_bb; note that
815 fallthru_bb's dominance info has already been updated by
817 if (dom_info_available_p (CDI_DOMINATORS
))
818 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
820 /* Put the ubsan builtin call into the newly created BB. */
821 if (flag_sanitize_undefined_trap_on_error
)
822 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP
), 0);
825 enum built_in_function bcode
826 = (flag_sanitize_recover
& ((check_align
? SANITIZE_ALIGNMENT
: 0)
827 | (check_null
? SANITIZE_NULL
: 0)))
828 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
829 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
830 tree fn
= builtin_decl_implicit (bcode
);
832 = ubsan_create_data ("__ubsan_null_data", 1, &loc
,
833 ubsan_type_descriptor (TREE_TYPE (ckind
),
834 UBSAN_PRINT_POINTER
),
837 fold_convert (unsigned_char_type_node
, ckind
),
839 data
= build_fold_addr_expr_loc (loc
, data
);
840 g
= gimple_build_call (fn
, 2, data
,
841 check_align
? check_align
842 : build_zero_cst (pointer_sized_int_node
));
844 gimple_stmt_iterator gsi2
= gsi_start_bb (then_bb
);
845 gimple_set_location (g
, loc
);
846 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
848 /* Unlink the UBSAN_NULLs vops before replacing it. */
849 unlink_stmt_vdef (stmt
);
853 g
= gimple_build_cond (EQ_EXPR
, ptr
, build_int_cst (TREE_TYPE (ptr
), 0),
854 NULL_TREE
, NULL_TREE
);
855 gimple_set_location (g
, loc
);
857 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
858 gsi_replace (&gsi
, g
, false);
866 /* Split the block with the condition again. */
867 e
= split_block (cond_bb
, stmt
);
868 basic_block cond1_bb
= e
->src
;
869 basic_block cond2_bb
= e
->dest
;
871 /* Make an edge coming from the 'cond1 block' into the 'then block';
872 this edge is unlikely taken, so set up the probability
874 e
= make_edge (cond1_bb
, then_bb
, EDGE_TRUE_VALUE
);
875 e
->probability
= PROB_VERY_UNLIKELY
;
877 /* Set up the fallthrough basic block. */
878 e
= find_edge (cond1_bb
, cond2_bb
);
879 e
->flags
= EDGE_FALSE_VALUE
;
880 e
->count
= cond1_bb
->count
;
881 e
->probability
= REG_BR_PROB_BASE
- PROB_VERY_UNLIKELY
;
883 /* Update dominance info. */
884 if (dom_info_available_p (CDI_DOMINATORS
))
886 set_immediate_dominator (CDI_DOMINATORS
, fallthru_bb
, cond1_bb
);
887 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond1_bb
);
890 gsi2
= gsi_start_bb (cond2_bb
);
893 tree mask
= build_int_cst (pointer_sized_int_node
,
894 tree_to_uhwi (align
) - 1);
895 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
896 BIT_AND_EXPR
, check_align
, mask
);
897 gimple_set_location (g
, loc
);
899 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
901 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
903 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
),
904 build_int_cst (pointer_sized_int_node
, 0),
905 NULL_TREE
, NULL_TREE
);
906 gimple_set_location (g
, loc
);
908 gsi_insert_after (&gsi2
, g
, GSI_NEW_STMT
);
910 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
911 gsi_replace (&gsi
, g
, false);
916 #define OBJSZ_MAX_OFFSET (1024 * 16)
918 /* Expand UBSAN_OBJECT_SIZE internal call. */
921 ubsan_expand_objsize_ifn (gimple_stmt_iterator
*gsi
)
923 gimple
*stmt
= gsi_stmt (*gsi
);
924 location_t loc
= gimple_location (stmt
);
925 gcc_assert (gimple_call_num_args (stmt
) == 4);
927 tree ptr
= gimple_call_arg (stmt
, 0);
928 tree offset
= gimple_call_arg (stmt
, 1);
929 tree size
= gimple_call_arg (stmt
, 2);
930 tree ckind
= gimple_call_arg (stmt
, 3);
931 gimple_stmt_iterator gsi_orig
= *gsi
;
934 /* See if we can discard the check. */
935 if (TREE_CODE (size
) != INTEGER_CST
936 || integer_all_onesp (size
))
937 /* Yes, __builtin_object_size couldn't determine the
939 else if (TREE_CODE (offset
) == INTEGER_CST
940 && wi::to_widest (offset
) >= -OBJSZ_MAX_OFFSET
941 && wi::to_widest (offset
) <= -1)
942 /* The offset is in range [-16K, -1]. */;
945 /* if (offset > objsize) */
946 basic_block then_bb
, fallthru_bb
;
947 gimple_stmt_iterator cond_insert_point
948 = create_cond_insert_point (gsi
, false, false, true,
949 &then_bb
, &fallthru_bb
);
950 g
= gimple_build_cond (GT_EXPR
, offset
, size
, NULL_TREE
, NULL_TREE
);
951 gimple_set_location (g
, loc
);
952 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
954 /* If the offset is small enough, we don't need the second
956 if (TREE_CODE (offset
) == INTEGER_CST
957 && wi::to_widest (offset
) >= 0
958 && wi::to_widest (offset
) <= OBJSZ_MAX_OFFSET
)
959 *gsi
= gsi_after_labels (then_bb
);
962 /* Don't issue run-time error if (ptr > ptr + offset). That
963 may happen when computing a POINTER_PLUS_EXPR. */
964 basic_block then2_bb
, fallthru2_bb
;
966 gimple_stmt_iterator gsi2
= gsi_after_labels (then_bb
);
967 cond_insert_point
= create_cond_insert_point (&gsi2
, false, false,
970 /* Convert the pointer to an integer type. */
971 tree p
= make_ssa_name (pointer_sized_int_node
);
972 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
973 gimple_set_location (g
, loc
);
974 gsi_insert_before (&cond_insert_point
, g
, GSI_NEW_STMT
);
975 p
= gimple_assign_lhs (g
);
976 /* Compute ptr + offset. */
977 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
978 PLUS_EXPR
, p
, offset
);
979 gimple_set_location (g
, loc
);
980 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
981 /* Now build the conditional and put it into the IR. */
982 g
= gimple_build_cond (LE_EXPR
, p
, gimple_assign_lhs (g
),
983 NULL_TREE
, NULL_TREE
);
984 gimple_set_location (g
, loc
);
985 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
986 *gsi
= gsi_after_labels (then2_bb
);
989 /* Generate __ubsan_handle_type_mismatch call. */
990 if (flag_sanitize_undefined_trap_on_error
)
991 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
995 = ubsan_create_data ("__ubsan_objsz_data", 1, &loc
,
996 ubsan_type_descriptor (TREE_TYPE (ptr
),
997 UBSAN_PRINT_POINTER
),
999 build_zero_cst (pointer_sized_int_node
),
1002 data
= build_fold_addr_expr_loc (loc
, data
);
1003 enum built_in_function bcode
1004 = (flag_sanitize_recover
& SANITIZE_OBJECT_SIZE
)
1005 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
1006 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT
;
1007 tree p
= make_ssa_name (pointer_sized_int_node
);
1008 g
= gimple_build_assign (p
, NOP_EXPR
, ptr
);
1009 gimple_set_location (g
, loc
);
1010 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1011 g
= gimple_build_call (builtin_decl_explicit (bcode
), 2, data
, p
);
1013 gimple_set_location (g
, loc
);
1014 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1016 /* Point GSI to next logical statement. */
1017 *gsi
= gsi_start_bb (fallthru_bb
);
1019 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1020 unlink_stmt_vdef (stmt
);
1021 gsi_remove (&gsi_orig
, true);
1025 /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */
1026 unlink_stmt_vdef (stmt
);
1027 gsi_remove (gsi
, true);
1031 /* Cached __ubsan_vptr_type_cache decl. */
1032 static GTY(()) tree ubsan_vptr_type_cache_decl
;
1034 /* Expand UBSAN_VPTR internal call. The type is kept on the ckind
1035 argument which is a constant, because the middle-end treats pointer
1036 conversions as useless and therefore the type of the first argument
1037 could be changed to any other pointer type. */
1040 ubsan_expand_vptr_ifn (gimple_stmt_iterator
*gsip
)
1042 gimple_stmt_iterator gsi
= *gsip
;
1043 gimple
*stmt
= gsi_stmt (gsi
);
1044 location_t loc
= gimple_location (stmt
);
1045 gcc_assert (gimple_call_num_args (stmt
) == 5);
1046 tree op
= gimple_call_arg (stmt
, 0);
1047 tree vptr
= gimple_call_arg (stmt
, 1);
1048 tree str_hash
= gimple_call_arg (stmt
, 2);
1049 tree ti_decl_addr
= gimple_call_arg (stmt
, 3);
1050 tree ckind_tree
= gimple_call_arg (stmt
, 4);
1051 ubsan_null_ckind ckind
= (ubsan_null_ckind
) tree_to_uhwi (ckind_tree
);
1052 tree type
= TREE_TYPE (TREE_TYPE (ckind_tree
));
1054 basic_block fallthru_bb
= NULL
;
1056 if (ckind
== UBSAN_DOWNCAST_POINTER
)
1058 /* Guard everything with if (op != NULL) { ... }. */
1059 basic_block then_bb
;
1060 gimple_stmt_iterator cond_insert_point
1061 = create_cond_insert_point (gsip
, false, false, true,
1062 &then_bb
, &fallthru_bb
);
1063 g
= gimple_build_cond (NE_EXPR
, op
, build_zero_cst (TREE_TYPE (op
)),
1064 NULL_TREE
, NULL_TREE
);
1065 gimple_set_location (g
, loc
);
1066 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1067 *gsip
= gsi_after_labels (then_bb
);
1068 gsi_remove (&gsi
, false);
1069 gsi_insert_before (gsip
, stmt
, GSI_NEW_STMT
);
1073 tree htype
= TREE_TYPE (str_hash
);
1074 tree cst
= wide_int_to_tree (htype
,
1075 wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
1077 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1079 gimple_set_location (g
, loc
);
1080 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1081 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1082 gimple_assign_lhs (g
), cst
);
1083 gimple_set_location (g
, loc
);
1084 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1085 tree t1
= gimple_assign_lhs (g
);
1086 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1087 t1
, build_int_cst (integer_type_node
, 47));
1088 gimple_set_location (g
, loc
);
1089 tree t2
= gimple_assign_lhs (g
);
1090 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1091 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1093 gimple_set_location (g
, loc
);
1094 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1095 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1096 t2
, gimple_assign_lhs (g
));
1097 gimple_set_location (g
, loc
);
1098 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1099 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1100 gimple_assign_lhs (g
), cst
);
1101 gimple_set_location (g
, loc
);
1102 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1103 tree t3
= gimple_assign_lhs (g
);
1104 g
= gimple_build_assign (make_ssa_name (htype
), LSHIFT_EXPR
,
1105 t3
, build_int_cst (integer_type_node
, 47));
1106 gimple_set_location (g
, loc
);
1107 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1108 g
= gimple_build_assign (make_ssa_name (htype
), BIT_XOR_EXPR
,
1109 t3
, gimple_assign_lhs (g
));
1110 gimple_set_location (g
, loc
);
1111 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1112 g
= gimple_build_assign (make_ssa_name (htype
), MULT_EXPR
,
1113 gimple_assign_lhs (g
), cst
);
1114 gimple_set_location (g
, loc
);
1115 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1116 if (!useless_type_conversion_p (pointer_sized_int_node
, htype
))
1118 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1119 NOP_EXPR
, gimple_assign_lhs (g
));
1120 gimple_set_location (g
, loc
);
1121 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1123 tree hash
= gimple_assign_lhs (g
);
1125 if (ubsan_vptr_type_cache_decl
== NULL_TREE
)
1127 tree atype
= build_array_type_nelts (pointer_sized_int_node
, 128);
1128 tree array
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1129 get_identifier ("__ubsan_vptr_type_cache"),
1131 DECL_ARTIFICIAL (array
) = 1;
1132 DECL_IGNORED_P (array
) = 1;
1133 TREE_PUBLIC (array
) = 1;
1134 TREE_STATIC (array
) = 1;
1135 DECL_EXTERNAL (array
) = 1;
1136 DECL_VISIBILITY (array
) = VISIBILITY_DEFAULT
;
1137 DECL_VISIBILITY_SPECIFIED (array
) = 1;
1138 varpool_node::finalize_decl (array
);
1139 ubsan_vptr_type_cache_decl
= array
;
1142 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1144 build_int_cst (pointer_sized_int_node
, 127));
1145 gimple_set_location (g
, loc
);
1146 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1148 tree c
= build4_loc (loc
, ARRAY_REF
, pointer_sized_int_node
,
1149 ubsan_vptr_type_cache_decl
, gimple_assign_lhs (g
),
1150 NULL_TREE
, NULL_TREE
);
1151 g
= gimple_build_assign (make_ssa_name (pointer_sized_int_node
),
1153 gimple_set_location (g
, loc
);
1154 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1156 basic_block then_bb
, fallthru2_bb
;
1157 gimple_stmt_iterator cond_insert_point
1158 = create_cond_insert_point (gsip
, false, false, true,
1159 &then_bb
, &fallthru2_bb
);
1160 g
= gimple_build_cond (NE_EXPR
, gimple_assign_lhs (g
), hash
,
1161 NULL_TREE
, NULL_TREE
);
1162 gimple_set_location (g
, loc
);
1163 gsi_insert_after (&cond_insert_point
, g
, GSI_NEW_STMT
);
1164 *gsip
= gsi_after_labels (then_bb
);
1165 if (fallthru_bb
== NULL
)
1166 fallthru_bb
= fallthru2_bb
;
1169 = ubsan_create_data ("__ubsan_vptr_data", 1, &loc
,
1170 ubsan_type_descriptor (type
), NULL_TREE
, ti_decl_addr
,
1171 build_int_cst (unsigned_char_type_node
, ckind
),
1173 data
= build_fold_addr_expr_loc (loc
, data
);
1174 enum built_in_function bcode
1175 = (flag_sanitize_recover
& SANITIZE_VPTR
)
1176 ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
1177 : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT
;
1179 g
= gimple_build_call (builtin_decl_explicit (bcode
), 3, data
, op
, hash
);
1180 gimple_set_location (g
, loc
);
1181 gsi_insert_before (gsip
, g
, GSI_SAME_STMT
);
1183 /* Point GSI to next logical statement. */
1184 *gsip
= gsi_start_bb (fallthru_bb
);
1186 /* Get rid of the UBSAN_VPTR call from the IR. */
1187 unlink_stmt_vdef (stmt
);
1188 gsi_remove (&gsi
, true);
1192 /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says
1193 whether the pointer is on the left hand side of the assignment. */
1196 instrument_mem_ref (tree mem
, tree base
, gimple_stmt_iterator
*iter
,
1199 enum ubsan_null_ckind ikind
= is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
;
1200 unsigned int align
= 0;
1201 if (sanitize_flags_p (SANITIZE_ALIGNMENT
))
1203 align
= min_align_of_type (TREE_TYPE (base
));
1207 if (align
== 0 && !sanitize_flags_p (SANITIZE_NULL
))
1209 tree t
= TREE_OPERAND (base
, 0);
1210 if (!POINTER_TYPE_P (TREE_TYPE (t
)))
1212 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base
)) && mem
!= base
)
1213 ikind
= UBSAN_MEMBER_ACCESS
;
1214 tree kind
= build_int_cst (build_pointer_type (TREE_TYPE (base
)), ikind
);
1215 tree alignt
= build_int_cst (pointer_sized_int_node
, align
);
1216 gcall
*g
= gimple_build_call_internal (IFN_UBSAN_NULL
, 3, t
, kind
, alignt
);
1217 gimple_set_location (g
, gimple_location (gsi_stmt (*iter
)));
1218 gsi_insert_before (iter
, g
, GSI_SAME_STMT
);
1221 /* Perform the pointer instrumentation. */
1224 instrument_null (gimple_stmt_iterator gsi
, tree t
, bool is_lhs
)
1226 /* Handle also e.g. &s->i. */
1227 if (TREE_CODE (t
) == ADDR_EXPR
)
1228 t
= TREE_OPERAND (t
, 0);
1229 tree base
= get_base_address (t
);
1230 if (TREE_CODE (base
) == MEM_REF
1231 && TREE_CODE (TREE_OPERAND (base
, 0)) == SSA_NAME
)
1232 instrument_mem_ref (t
, base
, &gsi
, is_lhs
);
1235 /* Build an ubsan builtin call for the signed-integer-overflow
1236 sanitization. CODE says what kind of builtin are we building,
1237 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
1238 are operands of the binary operation. */
1241 ubsan_build_overflow_builtin (tree_code code
, location_t loc
, tree lhstype
,
1242 tree op0
, tree op1
, tree
*datap
)
1244 if (flag_sanitize_undefined_trap_on_error
)
1245 return build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1248 if (datap
&& *datap
)
1251 data
= ubsan_create_data ("__ubsan_overflow_data", 1, &loc
,
1252 ubsan_type_descriptor (lhstype
), NULL_TREE
,
1256 enum built_in_function fn_code
;
1261 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1262 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
1263 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT
;
1266 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1267 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
1268 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT
;
1271 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1272 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
1273 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT
;
1276 fn_code
= (flag_sanitize_recover
& SANITIZE_SI_OVERFLOW
)
1277 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
1278 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT
;
1283 tree fn
= builtin_decl_explicit (fn_code
);
1284 return build_call_expr_loc (loc
, fn
, 2 + (code
!= NEGATE_EXPR
),
1285 build_fold_addr_expr_loc (loc
, data
),
1286 ubsan_encode_value (op0
, UBSAN_ENCODE_VALUE_RTL
),
1288 ? ubsan_encode_value (op1
,
1289 UBSAN_ENCODE_VALUE_RTL
)
1293 /* Perform the signed integer instrumentation. GSI is the iterator
1294 pointing at statement we are trying to instrument. */
1297 instrument_si_overflow (gimple_stmt_iterator gsi
)
1299 gimple
*stmt
= gsi_stmt (gsi
);
1300 tree_code code
= gimple_assign_rhs_code (stmt
);
1301 tree lhs
= gimple_assign_lhs (stmt
);
1302 tree lhstype
= TREE_TYPE (lhs
);
1303 tree lhsinner
= VECTOR_TYPE_P (lhstype
) ? TREE_TYPE (lhstype
) : lhstype
;
1307 /* If this is not a signed operation, don't instrument anything here.
1308 Also punt on bit-fields. */
1309 if (!INTEGRAL_TYPE_P (lhsinner
)
1310 || TYPE_OVERFLOW_WRAPS (lhsinner
)
1311 || GET_MODE_BITSIZE (TYPE_MODE (lhsinner
)) != TYPE_PRECISION (lhsinner
))
1322 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
1323 a
= gimple_assign_rhs1 (stmt
);
1324 b
= gimple_assign_rhs2 (stmt
);
1325 g
= gimple_build_call_internal (code
== PLUS_EXPR
1326 ? IFN_UBSAN_CHECK_ADD
1327 : code
== MINUS_EXPR
1328 ? IFN_UBSAN_CHECK_SUB
1329 : IFN_UBSAN_CHECK_MUL
, 2, a
, b
);
1330 gimple_call_set_lhs (g
, lhs
);
1331 gsi_replace (&gsi
, g
, true);
1334 /* Represent i = -u;
1336 i = UBSAN_CHECK_SUB (0, u); */
1337 a
= build_zero_cst (lhstype
);
1338 b
= gimple_assign_rhs1 (stmt
);
1339 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1340 gimple_call_set_lhs (g
, lhs
);
1341 gsi_replace (&gsi
, g
, true);
1344 /* Transform i = ABS_EXPR<u>;
1346 _N = UBSAN_CHECK_SUB (0, u);
1347 i = ABS_EXPR<_N>; */
1348 a
= build_zero_cst (lhstype
);
1349 b
= gimple_assign_rhs1 (stmt
);
1350 g
= gimple_build_call_internal (IFN_UBSAN_CHECK_SUB
, 2, a
, b
);
1351 a
= make_ssa_name (lhstype
);
1352 gimple_call_set_lhs (g
, a
);
1353 gimple_set_location (g
, gimple_location (stmt
));
1354 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
1355 gimple_assign_set_rhs1 (stmt
, a
);
1363 /* Instrument loads from (non-bitfield) bool and C++ enum values
1364 to check if the memory value is outside of the range of the valid
1368 instrument_bool_enum_load (gimple_stmt_iterator
*gsi
)
1370 gimple
*stmt
= gsi_stmt (*gsi
);
1371 tree rhs
= gimple_assign_rhs1 (stmt
);
1372 tree type
= TREE_TYPE (rhs
);
1373 tree minv
= NULL_TREE
, maxv
= NULL_TREE
;
1375 if (TREE_CODE (type
) == BOOLEAN_TYPE
1376 && sanitize_flags_p (SANITIZE_BOOL
))
1378 minv
= boolean_false_node
;
1379 maxv
= boolean_true_node
;
1381 else if (TREE_CODE (type
) == ENUMERAL_TYPE
1382 && sanitize_flags_p (SANITIZE_ENUM
)
1383 && TREE_TYPE (type
) != NULL_TREE
1384 && TREE_CODE (TREE_TYPE (type
)) == INTEGER_TYPE
1385 && (TYPE_PRECISION (TREE_TYPE (type
))
1386 < GET_MODE_PRECISION (TYPE_MODE (type
))))
1388 minv
= TYPE_MIN_VALUE (TREE_TYPE (type
));
1389 maxv
= TYPE_MAX_VALUE (TREE_TYPE (type
));
1394 int modebitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
1395 HOST_WIDE_INT bitsize
, bitpos
;
1398 int volatilep
= 0, reversep
, unsignedp
= 0;
1399 tree base
= get_inner_reference (rhs
, &bitsize
, &bitpos
, &offset
, &mode
,
1400 &unsignedp
, &reversep
, &volatilep
);
1401 tree utype
= build_nonstandard_integer_type (modebitsize
, 1);
1403 if ((VAR_P (base
) && DECL_HARD_REGISTER (base
))
1404 || (bitpos
% modebitsize
) != 0
1405 || bitsize
!= modebitsize
1406 || GET_MODE_BITSIZE (TYPE_MODE (utype
)) != modebitsize
1407 || TREE_CODE (gimple_assign_lhs (stmt
)) != SSA_NAME
)
1410 bool ends_bb
= stmt_ends_bb_p (stmt
);
1411 location_t loc
= gimple_location (stmt
);
1412 tree lhs
= gimple_assign_lhs (stmt
);
1413 tree ptype
= build_pointer_type (TREE_TYPE (rhs
));
1414 tree atype
= reference_alias_ptr_type (rhs
);
1415 gimple
*g
= gimple_build_assign (make_ssa_name (ptype
),
1416 build_fold_addr_expr (rhs
));
1417 gimple_set_location (g
, loc
);
1418 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1419 tree mem
= build2 (MEM_REF
, utype
, gimple_assign_lhs (g
),
1420 build_int_cst (atype
, 0));
1421 tree urhs
= make_ssa_name (utype
);
1424 gimple_assign_set_lhs (stmt
, urhs
);
1425 g
= gimple_build_assign (lhs
, NOP_EXPR
, urhs
);
1426 gimple_set_location (g
, loc
);
1427 edge e
= find_fallthru_edge (gimple_bb (stmt
)->succs
);
1428 gsi_insert_on_edge_immediate (e
, g
);
1429 gimple_assign_set_rhs_from_tree (gsi
, mem
);
1431 *gsi
= gsi_for_stmt (g
);
1436 g
= gimple_build_assign (urhs
, mem
);
1437 gimple_set_location (g
, loc
);
1438 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1440 minv
= fold_convert (utype
, minv
);
1441 maxv
= fold_convert (utype
, maxv
);
1442 if (!integer_zerop (minv
))
1444 g
= gimple_build_assign (make_ssa_name (utype
), MINUS_EXPR
, urhs
, minv
);
1445 gimple_set_location (g
, loc
);
1446 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1449 gimple_stmt_iterator gsi2
= *gsi
;
1450 basic_block then_bb
, fallthru_bb
;
1451 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1452 &then_bb
, &fallthru_bb
);
1453 g
= gimple_build_cond (GT_EXPR
, gimple_assign_lhs (g
),
1454 int_const_binop (MINUS_EXPR
, maxv
, minv
),
1455 NULL_TREE
, NULL_TREE
);
1456 gimple_set_location (g
, loc
);
1457 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1461 gimple_assign_set_rhs_with_ops (&gsi2
, NOP_EXPR
, urhs
);
1465 gsi2
= gsi_after_labels (then_bb
);
1466 if (flag_sanitize_undefined_trap_on_error
)
1467 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1470 tree data
= ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc
,
1471 ubsan_type_descriptor (type
), NULL_TREE
,
1473 data
= build_fold_addr_expr_loc (loc
, data
);
1474 enum built_in_function bcode
1475 = (flag_sanitize_recover
& (TREE_CODE (type
) == BOOLEAN_TYPE
1476 ? SANITIZE_BOOL
: SANITIZE_ENUM
))
1477 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
1478 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT
;
1479 tree fn
= builtin_decl_explicit (bcode
);
1481 tree val
= ubsan_encode_value (urhs
, UBSAN_ENCODE_VALUE_GIMPLE
);
1482 val
= force_gimple_operand_gsi (&gsi2
, val
, true, NULL_TREE
, true,
1484 g
= gimple_build_call (fn
, 2, data
, val
);
1486 gimple_set_location (g
, loc
);
1487 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
1488 ubsan_create_edge (g
);
1489 *gsi
= gsi_for_stmt (stmt
);
1492 /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
1493 new style handlers. Libubsan uses heuristics to destinguish between old and
1494 new styles and relies on these properties for filename:
1496 a) Location's filename must not be NULL.
1497 b) Location's filename must not be equal to "".
1498 c) Location's filename must not be equal to "\1".
1499 d) First two bytes of filename must not contain '\xff' symbol. */
1502 ubsan_use_new_style_p (location_t loc
)
1504 if (loc
== UNKNOWN_LOCATION
)
1507 expanded_location xloc
= expand_location (loc
);
1508 if (xloc
.file
== NULL
|| strncmp (xloc
.file
, "\1", 2) == 0
1509 || xloc
.file
[0] == '\0' || xloc
.file
[0] == '\xff'
1510 || xloc
.file
[1] == '\xff')
1516 /* Instrument float point-to-integer conversion. TYPE is an integer type of
1517 destination, EXPR is floating-point expression. */
1520 ubsan_instrument_float_cast (location_t loc
, tree type
, tree expr
)
1522 tree expr_type
= TREE_TYPE (expr
);
1523 tree t
, tt
, fn
, min
, max
;
1524 machine_mode mode
= TYPE_MODE (expr_type
);
1525 int prec
= TYPE_PRECISION (type
);
1526 bool uns_p
= TYPE_UNSIGNED (type
);
1527 if (loc
== UNKNOWN_LOCATION
)
1528 loc
= input_location
;
1530 /* Float to integer conversion first truncates toward zero, so
1531 even signed char c = 127.875f; is not problematic.
1532 Therefore, we should complain only if EXPR is unordered or smaller
1533 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
1534 TYPE_MAX_VALUE + 1.0. */
1535 if (REAL_MODE_FORMAT (mode
)->b
== 2)
1537 /* For maximum, TYPE_MAX_VALUE might not be representable
1538 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
1539 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
1540 either representable or infinity. */
1541 REAL_VALUE_TYPE maxval
= dconst1
;
1542 SET_REAL_EXP (&maxval
, REAL_EXP (&maxval
) + prec
- !uns_p
);
1543 real_convert (&maxval
, mode
, &maxval
);
1544 max
= build_real (expr_type
, maxval
);
1546 /* For unsigned, assume -1.0 is always representable. */
1548 min
= build_minus_one_cst (expr_type
);
1551 /* TYPE_MIN_VALUE is generally representable (or -inf),
1552 but TYPE_MIN_VALUE - 1.0 might not be. */
1553 REAL_VALUE_TYPE minval
= dconstm1
, minval2
;
1554 SET_REAL_EXP (&minval
, REAL_EXP (&minval
) + prec
- 1);
1555 real_convert (&minval
, mode
, &minval
);
1556 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &dconst1
);
1557 real_convert (&minval2
, mode
, &minval2
);
1558 if (real_compare (EQ_EXPR
, &minval
, &minval2
)
1559 && !real_isinf (&minval
))
1561 /* If TYPE_MIN_VALUE - 1.0 is not representable and
1562 rounds to TYPE_MIN_VALUE, we need to subtract
1563 more. As REAL_MODE_FORMAT (mode)->p is the number
1564 of base digits, we want to subtract a number that
1565 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
1566 times smaller than minval. */
1568 gcc_assert (prec
> REAL_MODE_FORMAT (mode
)->p
);
1569 SET_REAL_EXP (&minval2
,
1570 REAL_EXP (&minval2
) + prec
- 1
1571 - REAL_MODE_FORMAT (mode
)->p
+ 1);
1572 real_arithmetic (&minval2
, MINUS_EXPR
, &minval
, &minval2
);
1573 real_convert (&minval2
, mode
, &minval2
);
1575 min
= build_real (expr_type
, minval2
);
1578 else if (REAL_MODE_FORMAT (mode
)->b
== 10)
1580 /* For _Decimal128 up to 34 decimal digits, - sign,
1581 dot, e, exponent. */
1584 int p
= REAL_MODE_FORMAT (mode
)->p
;
1585 REAL_VALUE_TYPE maxval
, minval
;
1587 /* Use mpfr_snprintf rounding to compute the smallest
1588 representable decimal number greater or equal than
1589 1 << (prec - !uns_p). */
1590 mpfr_init2 (m
, prec
+ 2);
1591 mpfr_set_ui_2exp (m
, 1, prec
- !uns_p
, GMP_RNDN
);
1592 mpfr_snprintf (buf
, sizeof buf
, "%.*RUe", p
- 1, m
);
1593 decimal_real_from_string (&maxval
, buf
);
1594 max
= build_real (expr_type
, maxval
);
1596 /* For unsigned, assume -1.0 is always representable. */
1598 min
= build_minus_one_cst (expr_type
);
1601 /* Use mpfr_snprintf rounding to compute the largest
1602 representable decimal number less or equal than
1603 (-1 << (prec - 1)) - 1. */
1604 mpfr_set_si_2exp (m
, -1, prec
- 1, GMP_RNDN
);
1605 mpfr_sub_ui (m
, m
, 1, GMP_RNDN
);
1606 mpfr_snprintf (buf
, sizeof buf
, "%.*RDe", p
- 1, m
);
1607 decimal_real_from_string (&minval
, buf
);
1608 min
= build_real (expr_type
, minval
);
1615 t
= fold_build2 (UNLE_EXPR
, boolean_type_node
, expr
, min
);
1616 tt
= fold_build2 (UNGE_EXPR
, boolean_type_node
, expr
, max
);
1617 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, tt
);
1618 if (integer_zerop (t
))
1621 if (flag_sanitize_undefined_trap_on_error
)
1622 fn
= build_call_expr_loc (loc
, builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1625 location_t
*loc_ptr
= NULL
;
1626 unsigned num_locations
= 0;
1627 /* Figure out if we can propagate location to ubsan_data and use new
1628 style handlers in libubsan. */
1629 if (ubsan_use_new_style_p (loc
))
1634 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1635 tree data
= ubsan_create_data ("__ubsan_float_cast_overflow_data",
1636 num_locations
, loc_ptr
,
1637 ubsan_type_descriptor (expr_type
),
1638 ubsan_type_descriptor (type
), NULL_TREE
,
1640 enum built_in_function bcode
1641 = (flag_sanitize_recover
& SANITIZE_FLOAT_CAST
)
1642 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1643 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT
;
1644 fn
= builtin_decl_explicit (bcode
);
1645 fn
= build_call_expr_loc (loc
, fn
, 2,
1646 build_fold_addr_expr_loc (loc
, data
),
1647 ubsan_encode_value (expr
));
1650 return fold_build3 (COND_EXPR
, void_type_node
, t
, fn
, integer_zero_node
);
1653 /* Instrument values passed to function arguments with nonnull attribute. */
1656 instrument_nonnull_arg (gimple_stmt_iterator
*gsi
)
1658 gimple
*stmt
= gsi_stmt (*gsi
);
1660 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1661 while for nonnull sanitization it is clear. */
1662 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1663 flag_delete_null_pointer_checks
= 1;
1664 loc
[0] = gimple_location (stmt
);
1665 loc
[1] = UNKNOWN_LOCATION
;
1666 for (unsigned int i
= 0; i
< gimple_call_num_args (stmt
); i
++)
1668 tree arg
= gimple_call_arg (stmt
, i
);
1669 if (POINTER_TYPE_P (TREE_TYPE (arg
))
1670 && infer_nonnull_range_by_attribute (stmt
, arg
))
1673 if (!is_gimple_val (arg
))
1675 g
= gimple_build_assign (make_ssa_name (TREE_TYPE (arg
)), arg
);
1676 gimple_set_location (g
, loc
[0]);
1677 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1678 arg
= gimple_assign_lhs (g
);
1681 basic_block then_bb
, fallthru_bb
;
1682 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1683 &then_bb
, &fallthru_bb
);
1684 g
= gimple_build_cond (EQ_EXPR
, arg
,
1685 build_zero_cst (TREE_TYPE (arg
)),
1686 NULL_TREE
, NULL_TREE
);
1687 gimple_set_location (g
, loc
[0]);
1688 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1690 *gsi
= gsi_after_labels (then_bb
);
1691 if (flag_sanitize_undefined_trap_on_error
)
1692 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1695 tree data
= ubsan_create_data ("__ubsan_nonnull_arg_data",
1697 build_int_cst (integer_type_node
,
1700 data
= build_fold_addr_expr_loc (loc
[0], data
);
1701 enum built_in_function bcode
1702 = (flag_sanitize_recover
& SANITIZE_NONNULL_ATTRIBUTE
)
1703 ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
1704 : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT
;
1705 tree fn
= builtin_decl_explicit (bcode
);
1707 g
= gimple_build_call (fn
, 1, data
);
1709 gimple_set_location (g
, loc
[0]);
1710 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1711 ubsan_create_edge (g
);
1713 *gsi
= gsi_for_stmt (stmt
);
1715 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1718 /* Instrument returns in functions with returns_nonnull attribute. */
1721 instrument_nonnull_return (gimple_stmt_iterator
*gsi
)
1723 greturn
*stmt
= as_a
<greturn
*> (gsi_stmt (*gsi
));
1725 tree arg
= gimple_return_retval (stmt
);
1726 /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
1727 while for nonnull return sanitization it is clear. */
1728 int save_flag_delete_null_pointer_checks
= flag_delete_null_pointer_checks
;
1729 flag_delete_null_pointer_checks
= 1;
1730 loc
[0] = gimple_location (stmt
);
1731 loc
[1] = UNKNOWN_LOCATION
;
1733 && POINTER_TYPE_P (TREE_TYPE (arg
))
1734 && is_gimple_val (arg
)
1735 && infer_nonnull_range_by_attribute (stmt
, arg
))
1737 basic_block then_bb
, fallthru_bb
;
1738 *gsi
= create_cond_insert_point (gsi
, true, false, true,
1739 &then_bb
, &fallthru_bb
);
1740 gimple
*g
= gimple_build_cond (EQ_EXPR
, arg
,
1741 build_zero_cst (TREE_TYPE (arg
)),
1742 NULL_TREE
, NULL_TREE
);
1743 gimple_set_location (g
, loc
[0]);
1744 gsi_insert_after (gsi
, g
, GSI_NEW_STMT
);
1746 *gsi
= gsi_after_labels (then_bb
);
1747 if (flag_sanitize_undefined_trap_on_error
)
1748 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1751 tree data
= ubsan_create_data ("__ubsan_nonnull_return_data",
1752 2, loc
, NULL_TREE
, NULL_TREE
);
1753 data
= build_fold_addr_expr_loc (loc
[0], data
);
1754 enum built_in_function bcode
1755 = (flag_sanitize_recover
& SANITIZE_RETURNS_NONNULL_ATTRIBUTE
)
1756 ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN
1757 : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_ABORT
;
1758 tree fn
= builtin_decl_explicit (bcode
);
1760 g
= gimple_build_call (fn
, 1, data
);
1762 gimple_set_location (g
, loc
[0]);
1763 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1764 ubsan_create_edge (g
);
1765 *gsi
= gsi_for_stmt (stmt
);
1767 flag_delete_null_pointer_checks
= save_flag_delete_null_pointer_checks
;
1770 /* Instrument memory references. Here we check whether the pointer
1771 points to an out-of-bounds location. */
1774 instrument_object_size (gimple_stmt_iterator
*gsi
, tree t
, bool is_lhs
)
1776 gimple
*stmt
= gsi_stmt (*gsi
);
1777 location_t loc
= gimple_location (stmt
);
1779 tree index
= NULL_TREE
;
1780 HOST_WIDE_INT size_in_bytes
;
1782 type
= TREE_TYPE (t
);
1783 if (VOID_TYPE_P (type
))
1786 switch (TREE_CODE (t
))
1789 if (TREE_CODE (t
) == COMPONENT_REF
1790 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1)) != NULL_TREE
)
1792 tree repr
= DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t
, 1));
1793 t
= build3 (COMPONENT_REF
, TREE_TYPE (repr
), TREE_OPERAND (t
, 0),
1794 repr
, TREE_OPERAND (t
, 2));
1798 index
= TREE_OPERAND (t
, 1);
1810 size_in_bytes
= int_size_in_bytes (type
);
1811 if (size_in_bytes
<= 0)
1814 HOST_WIDE_INT bitsize
, bitpos
;
1817 int volatilep
= 0, reversep
, unsignedp
= 0;
1818 tree inner
= get_inner_reference (t
, &bitsize
, &bitpos
, &offset
, &mode
,
1819 &unsignedp
, &reversep
, &volatilep
);
1821 if (bitpos
% BITS_PER_UNIT
!= 0
1822 || bitsize
!= size_in_bytes
* BITS_PER_UNIT
)
1825 bool decl_p
= DECL_P (inner
);
1829 if (DECL_REGISTER (inner
))
1833 else if (TREE_CODE (inner
) == MEM_REF
)
1834 base
= TREE_OPERAND (inner
, 0);
1837 tree ptr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (t
)), t
);
1839 while (TREE_CODE (base
) == SSA_NAME
)
1841 gimple
*def_stmt
= SSA_NAME_DEF_STMT (base
);
1842 if (gimple_assign_ssa_name_copy_p (def_stmt
)
1843 || (gimple_assign_cast_p (def_stmt
)
1844 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt
))))
1845 || (is_gimple_assign (def_stmt
)
1846 && gimple_assign_rhs_code (def_stmt
) == POINTER_PLUS_EXPR
))
1848 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
1849 if (TREE_CODE (rhs1
) == SSA_NAME
1850 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1
))
1859 if (!POINTER_TYPE_P (TREE_TYPE (base
)) && !DECL_P (base
))
1863 tree base_addr
= base
;
1864 gimple
*bos_stmt
= NULL
;
1866 base_addr
= build1 (ADDR_EXPR
,
1867 build_pointer_type (TREE_TYPE (base
)), base
);
1868 unsigned HOST_WIDE_INT size
;
1869 if (compute_builtin_object_size (base_addr
, 0, &size
))
1870 sizet
= build_int_cst (sizetype
, size
);
1873 if (LOCATION_LOCUS (loc
) == UNKNOWN_LOCATION
)
1874 loc
= input_location
;
1875 /* Generate __builtin_object_size call. */
1876 sizet
= builtin_decl_explicit (BUILT_IN_OBJECT_SIZE
);
1877 sizet
= build_call_expr_loc (loc
, sizet
, 2, base_addr
,
1879 sizet
= force_gimple_operand_gsi (gsi
, sizet
, false, NULL_TREE
, true,
1881 /* If the call above didn't end up being an integer constant, go one
1882 statement back and get the __builtin_object_size stmt. Save it,
1883 we might need it later. */
1884 if (SSA_VAR_P (sizet
))
1887 bos_stmt
= gsi_stmt (*gsi
);
1889 /* Move on to where we were. */
1896 /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
1898 /* ptr + sizeof (*ptr) - base */
1899 t
= fold_build2 (MINUS_EXPR
, sizetype
,
1900 fold_convert (pointer_sized_int_node
, ptr
),
1901 fold_convert (pointer_sized_int_node
, base_addr
));
1902 t
= fold_build2 (PLUS_EXPR
, sizetype
, t
, TYPE_SIZE_UNIT (type
));
1904 /* Perhaps we can omit the check. */
1905 if (TREE_CODE (t
) == INTEGER_CST
1906 && TREE_CODE (sizet
) == INTEGER_CST
1907 && tree_int_cst_le (t
, sizet
))
1910 if (index
!= NULL_TREE
1911 && TREE_CODE (index
) == SSA_NAME
1912 && TREE_CODE (sizet
) == INTEGER_CST
)
1914 gimple
*def
= SSA_NAME_DEF_STMT (index
);
1915 if (is_gimple_assign (def
)
1916 && gimple_assign_rhs_code (def
) == BIT_AND_EXPR
1917 && TREE_CODE (gimple_assign_rhs2 (def
)) == INTEGER_CST
)
1919 tree cst
= gimple_assign_rhs2 (def
);
1920 tree sz
= fold_build2 (EXACT_DIV_EXPR
, sizetype
, sizet
,
1921 TYPE_SIZE_UNIT (type
));
1922 if (tree_int_cst_sgn (cst
) >= 0
1923 && tree_int_cst_lt (cst
, sz
))
1928 if (bos_stmt
&& gimple_call_builtin_p (bos_stmt
, BUILT_IN_OBJECT_SIZE
))
1929 ubsan_create_edge (bos_stmt
);
1931 /* We have to emit the check. */
1932 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, true,
1934 ptr
= force_gimple_operand_gsi (gsi
, ptr
, true, NULL_TREE
, true,
1936 tree ckind
= build_int_cst (unsigned_char_type_node
,
1937 is_lhs
? UBSAN_STORE_OF
: UBSAN_LOAD_OF
);
1938 gimple
*g
= gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE
, 4,
1939 ptr
, t
, sizet
, ckind
);
1940 gimple_set_location (g
, loc
);
1941 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
1946 const pass_data pass_data_ubsan
=
1948 GIMPLE_PASS
, /* type */
1950 OPTGROUP_NONE
, /* optinfo_flags */
1951 TV_TREE_UBSAN
, /* tv_id */
1952 ( PROP_cfg
| PROP_ssa
), /* properties_required */
1953 0, /* properties_provided */
1954 0, /* properties_destroyed */
1955 0, /* todo_flags_start */
1956 TODO_update_ssa
, /* todo_flags_finish */
1959 class pass_ubsan
: public gimple_opt_pass
1962 pass_ubsan (gcc::context
*ctxt
)
1963 : gimple_opt_pass (pass_data_ubsan
, ctxt
)
1966 /* opt_pass methods: */
1967 virtual bool gate (function
*)
1969 return sanitize_flags_p ((SANITIZE_NULL
| SANITIZE_SI_OVERFLOW
1970 | SANITIZE_BOOL
| SANITIZE_ENUM
1971 | SANITIZE_ALIGNMENT
1972 | SANITIZE_NONNULL_ATTRIBUTE
1973 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
1974 | SANITIZE_OBJECT_SIZE
));
1977 virtual unsigned int execute (function
*);
1979 }; // class pass_ubsan
1982 pass_ubsan::execute (function
*fun
)
1985 gimple_stmt_iterator gsi
;
1986 unsigned int ret
= 0;
1988 initialize_sanitizer_builtins ();
1990 FOR_EACH_BB_FN (bb
, fun
)
1992 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
);)
1994 gimple
*stmt
= gsi_stmt (gsi
);
1995 if (is_gimple_debug (stmt
) || gimple_clobber_p (stmt
))
2001 if ((sanitize_flags_p (SANITIZE_SI_OVERFLOW
, fun
->decl
))
2002 && is_gimple_assign (stmt
))
2003 instrument_si_overflow (gsi
);
2005 if (sanitize_flags_p (SANITIZE_NULL
| SANITIZE_ALIGNMENT
, fun
->decl
))
2007 if (gimple_store_p (stmt
))
2008 instrument_null (gsi
, gimple_get_lhs (stmt
), true);
2009 if (gimple_assign_single_p (stmt
))
2010 instrument_null (gsi
, gimple_assign_rhs1 (stmt
), false);
2011 if (is_gimple_call (stmt
))
2013 unsigned args_num
= gimple_call_num_args (stmt
);
2014 for (unsigned i
= 0; i
< args_num
; ++i
)
2016 tree arg
= gimple_call_arg (stmt
, i
);
2017 if (is_gimple_reg (arg
) || is_gimple_min_invariant (arg
))
2019 instrument_null (gsi
, arg
, false);
2024 if (sanitize_flags_p (SANITIZE_BOOL
| SANITIZE_ENUM
, fun
->decl
)
2025 && gimple_assign_load_p (stmt
))
2027 instrument_bool_enum_load (&gsi
);
2028 bb
= gimple_bb (stmt
);
2031 if (sanitize_flags_p (SANITIZE_NONNULL_ATTRIBUTE
, fun
->decl
)
2032 && is_gimple_call (stmt
)
2033 && !gimple_call_internal_p (stmt
))
2035 instrument_nonnull_arg (&gsi
);
2036 bb
= gimple_bb (stmt
);
2039 if (sanitize_flags_p (SANITIZE_RETURNS_NONNULL_ATTRIBUTE
, fun
->decl
)
2040 && gimple_code (stmt
) == GIMPLE_RETURN
)
2042 instrument_nonnull_return (&gsi
);
2043 bb
= gimple_bb (stmt
);
2046 if (sanitize_flags_p (SANITIZE_OBJECT_SIZE
, fun
->decl
))
2048 if (gimple_store_p (stmt
))
2049 instrument_object_size (&gsi
, gimple_get_lhs (stmt
), true);
2050 if (gimple_assign_load_p (stmt
))
2051 instrument_object_size (&gsi
, gimple_assign_rhs1 (stmt
),
2053 if (is_gimple_call (stmt
))
2055 unsigned args_num
= gimple_call_num_args (stmt
);
2056 for (unsigned i
= 0; i
< args_num
; ++i
)
2058 tree arg
= gimple_call_arg (stmt
, i
);
2059 if (is_gimple_reg (arg
) || is_gimple_min_invariant (arg
))
2061 instrument_object_size (&gsi
, arg
, false);
2068 if (gimple_purge_dead_eh_edges (bb
))
2069 ret
= TODO_cleanup_cfg
;
2077 make_pass_ubsan (gcc::context
*ctxt
)
2079 return new pass_ubsan (ctxt
);
2082 #include "gt-ubsan.h"