* config/rx/rx.c (add_vector_labels): New.
[official-gcc.git] / gcc / ubsan.c
blob4de6d6e8ae3acd9fec6cc06caa45e92b4e419829
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2014 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tree.h"
25 #include "stor-layout.h"
26 #include "stringpool.h"
27 #include "cgraph.h"
28 #include "tree-pass.h"
29 #include "tree-ssa-alias.h"
30 #include "tree-pretty-print.h"
31 #include "internal-fn.h"
32 #include "gimple-expr.h"
33 #include "gimple.h"
34 #include "gimple-iterator.h"
35 #include "gimple-ssa.h"
36 #include "gimple-walk.h"
37 #include "hashtab.h"
38 #include "output.h"
39 #include "tm_p.h"
40 #include "toplev.h"
41 #include "cfgloop.h"
42 #include "ubsan.h"
43 #include "c-family/c-common.h"
44 #include "rtl.h"
45 #include "expr.h"
46 #include "tree-ssanames.h"
47 #include "asan.h"
48 #include "gimplify-me.h"
49 #include "intl.h"
50 #include "realmpfr.h"
51 #include "dfp.h"
53 /* Map from a tree to a VAR_DECL tree. */
55 struct GTY(()) tree_type_map {
56 struct tree_map_base type;
57 tree decl;
60 #define tree_type_map_eq tree_map_base_eq
61 #define tree_type_map_marked_p tree_map_base_marked_p
63 /* Hash from a tree in a tree_type_map. */
65 unsigned int
66 tree_type_map_hash (const void *item)
68 return TYPE_UID (((const struct tree_type_map *)item)->type.from);
71 static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map)))
72 htab_t decl_tree_for_type;
74 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
76 static tree
77 decl_for_type_lookup (tree type)
79 /* If the hash table is not initialized yet, create it now. */
80 if (decl_tree_for_type == NULL)
82 decl_tree_for_type = htab_create_ggc (10, tree_type_map_hash,
83 tree_type_map_eq, 0);
84 /* That also means we don't have to bother with the lookup. */
85 return NULL_TREE;
88 struct tree_type_map *h, in;
89 in.type.from = type;
91 h = (struct tree_type_map *)
92 htab_find_with_hash (decl_tree_for_type, &in, TYPE_UID (type));
93 return h ? h->decl : NULL_TREE;
96 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
98 static void
99 decl_for_type_insert (tree type, tree decl)
101 struct tree_type_map *h;
102 void **slot;
104 h = ggc_alloc<tree_type_map> ();
105 h->type.from = type;
106 h->decl = decl;
107 slot = htab_find_slot_with_hash (decl_tree_for_type, h, TYPE_UID (type),
108 INSERT);
109 *(struct tree_type_map **) slot = h;
112 /* Helper routine, which encodes a value in the pointer_sized_int_node.
113 Arguments with precision <= POINTER_SIZE are passed directly,
114 the rest is passed by reference. T is a value we are to encode.
115 IN_EXPAND_P is true if this function is called during expansion. */
117 tree
118 ubsan_encode_value (tree t, bool in_expand_p)
120 tree type = TREE_TYPE (t);
121 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
122 if (bitsize <= POINTER_SIZE)
123 switch (TREE_CODE (type))
125 case BOOLEAN_TYPE:
126 case ENUMERAL_TYPE:
127 case INTEGER_TYPE:
128 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
129 case REAL_TYPE:
131 tree itype = build_nonstandard_integer_type (bitsize, true);
132 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
133 return fold_convert (pointer_sized_int_node, t);
135 default:
136 gcc_unreachable ();
138 else
140 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
142 /* The reason for this is that we don't want to pessimize
143 code by making vars unnecessarily addressable. */
144 tree var = create_tmp_var (type, NULL);
145 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
146 if (in_expand_p)
148 rtx mem
149 = assign_stack_temp_for_type (TYPE_MODE (type),
150 GET_MODE_SIZE (TYPE_MODE (type)),
151 type);
152 SET_DECL_RTL (var, mem);
153 expand_assignment (var, t, false);
154 return build_fold_addr_expr (var);
156 t = build_fold_addr_expr (var);
157 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
159 else
160 return build_fold_addr_expr (t);
164 /* Build
165 struct __ubsan_type_descriptor
167 unsigned short __typekind;
168 unsigned short __typeinfo;
169 char __typename[];
171 type. */
173 static tree
174 ubsan_type_descriptor_type (void)
176 static const char *field_names[3]
177 = { "__typekind", "__typeinfo", "__typename" };
178 tree fields[3], ret;
179 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
180 tree flex_arr_type = build_array_type (char_type_node, itype);
182 ret = make_node (RECORD_TYPE);
183 for (int i = 0; i < 3; i++)
185 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
186 get_identifier (field_names[i]),
187 (i == 2) ? flex_arr_type
188 : short_unsigned_type_node);
189 DECL_CONTEXT (fields[i]) = ret;
190 if (i)
191 DECL_CHAIN (fields[i - 1]) = fields[i];
193 TYPE_FIELDS (ret) = fields[0];
194 TYPE_NAME (ret) = get_identifier ("__ubsan_type_descriptor");
195 layout_type (ret);
196 return ret;
199 /* Build
200 struct __ubsan_source_location
202 const char *__filename;
203 unsigned int __line;
204 unsigned int __column;
206 type. */
208 static tree
209 ubsan_source_location_type (void)
211 static const char *field_names[3]
212 = { "__filename", "__line", "__column" };
213 tree fields[3], ret;
214 tree const_char_type = build_qualified_type (char_type_node,
215 TYPE_QUAL_CONST);
217 ret = make_node (RECORD_TYPE);
218 for (int i = 0; i < 3; i++)
220 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
221 get_identifier (field_names[i]),
222 (i == 0) ? build_pointer_type (const_char_type)
223 : unsigned_type_node);
224 DECL_CONTEXT (fields[i]) = ret;
225 if (i)
226 DECL_CHAIN (fields[i - 1]) = fields[i];
228 TYPE_FIELDS (ret) = fields[0];
229 TYPE_NAME (ret) = get_identifier ("__ubsan_source_location");
230 layout_type (ret);
231 return ret;
234 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
235 type with its fields filled from a location_t LOC. */
237 static tree
238 ubsan_source_location (location_t loc)
240 expanded_location xloc;
241 tree type = ubsan_source_location_type ();
243 xloc = expand_location (loc);
244 if (xloc.file == NULL)
245 xloc.file = "<unknown>";
247 /* Fill in the values from LOC. */
248 size_t len = strlen (xloc.file);
249 tree str = build_string (len + 1, xloc.file);
250 TREE_TYPE (str) = build_array_type (char_type_node,
251 build_index_type (size_int (len)));
252 TREE_READONLY (str) = 1;
253 TREE_STATIC (str) = 1;
254 str = build_fold_addr_expr (str);
255 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
256 build_int_cst (unsigned_type_node,
257 xloc.line), NULL_TREE,
258 build_int_cst (unsigned_type_node,
259 xloc.column));
260 TREE_CONSTANT (ctor) = 1;
261 TREE_STATIC (ctor) = 1;
263 return ctor;
266 /* This routine returns a magic number for TYPE. */
268 static unsigned short
269 get_ubsan_type_info_for_type (tree type)
271 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
272 if (TREE_CODE (type) == REAL_TYPE)
273 return tree_to_uhwi (TYPE_SIZE (type));
274 else
276 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
277 gcc_assert (prec != -1);
278 return (prec << 1) | !TYPE_UNSIGNED (type);
282 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
283 descriptor. It first looks into the hash table; if not found,
284 create the VAR_DECL, put it into the hash table and return the
285 ADDR_EXPR of it. TYPE describes a particular type. WANT_POINTER_TYPE_P
286 means whether we are interested in the pointer type and not the pointer
287 itself. */
289 tree
290 ubsan_type_descriptor (tree type, bool want_pointer_type_p)
292 /* See through any typedefs. */
293 type = TYPE_MAIN_VARIANT (type);
295 tree decl = decl_for_type_lookup (type);
296 /* It is possible that some of the earlier created DECLs were found
297 unused, in that case they weren't emitted and varpool_get_node
298 returns NULL node on them. But now we really need them. Thus,
299 renew them here. */
300 if (decl != NULL_TREE && varpool_get_node (decl))
301 return build_fold_addr_expr (decl);
303 tree dtype = ubsan_type_descriptor_type ();
304 tree type2 = type;
305 const char *tname = NULL;
306 char *pretty_name;
307 unsigned char deref_depth = 0;
308 unsigned short tkind, tinfo;
310 /* Get the name of the type, or the name of the pointer type. */
311 if (want_pointer_type_p)
313 gcc_assert (POINTER_TYPE_P (type));
314 type2 = TREE_TYPE (type);
316 /* Remove any '*' operators from TYPE. */
317 while (POINTER_TYPE_P (type2))
318 deref_depth++, type2 = TREE_TYPE (type2);
320 if (TREE_CODE (type2) == METHOD_TYPE)
321 type2 = TYPE_METHOD_BASETYPE (type2);
324 /* If an array, get its type. */
325 type2 = strip_array_types (type2);
327 if (TYPE_NAME (type2) != NULL)
329 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
330 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
331 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
332 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
335 if (tname == NULL)
336 /* We weren't able to determine the type name. */
337 tname = "<unknown>";
339 /* Decorate the type name with '', '*', "struct", or "union". */
340 pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
341 if (want_pointer_type_p)
343 int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
344 TYPE_VOLATILE (type2) ? "volatile " : "",
345 TYPE_READONLY (type2) ? "const " : "",
346 TYPE_RESTRICT (type2) ? "restrict " : "",
347 TYPE_ATOMIC (type2) ? "_Atomic " : "",
348 TREE_CODE (type2) == RECORD_TYPE
349 ? "struct "
350 : TREE_CODE (type2) == UNION_TYPE
351 ? "union " : "", tname,
352 deref_depth == 0 ? "" : " ");
353 while (deref_depth-- > 0)
354 pretty_name[pos++] = '*';
355 pretty_name[pos++] = '\'';
356 pretty_name[pos] = '\0';
358 else
359 sprintf (pretty_name, "'%s'", tname);
361 switch (TREE_CODE (type))
363 case BOOLEAN_TYPE:
364 case ENUMERAL_TYPE:
365 case INTEGER_TYPE:
366 tkind = 0x0000;
367 break;
368 case REAL_TYPE:
369 /* FIXME: libubsan right now only supports float, double and
370 long double type formats. */
371 if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
372 || TYPE_MODE (type) == TYPE_MODE (double_type_node)
373 || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
374 tkind = 0x0001;
375 else
376 tkind = 0xffff;
377 break;
378 default:
379 tkind = 0xffff;
380 break;
382 tinfo = get_ubsan_type_info_for_type (type);
384 /* Create a new VAR_DECL of type descriptor. */
385 char tmp_name[32];
386 static unsigned int type_var_id_num;
387 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
388 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
389 dtype);
390 TREE_STATIC (decl) = 1;
391 TREE_PUBLIC (decl) = 0;
392 DECL_ARTIFICIAL (decl) = 1;
393 DECL_IGNORED_P (decl) = 1;
394 DECL_EXTERNAL (decl) = 0;
396 size_t len = strlen (pretty_name);
397 tree str = build_string (len + 1, pretty_name);
398 TREE_TYPE (str) = build_array_type (char_type_node,
399 build_index_type (size_int (len)));
400 TREE_READONLY (str) = 1;
401 TREE_STATIC (str) = 1;
402 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
403 build_int_cst (short_unsigned_type_node,
404 tkind), NULL_TREE,
405 build_int_cst (short_unsigned_type_node,
406 tinfo), NULL_TREE, str);
407 TREE_CONSTANT (ctor) = 1;
408 TREE_STATIC (ctor) = 1;
409 DECL_INITIAL (decl) = ctor;
410 varpool_finalize_decl (decl);
412 /* Save the VAR_DECL into the hash table. */
413 decl_for_type_insert (type, decl);
415 return build_fold_addr_expr (decl);
418 /* Create a structure for the ubsan library. NAME is a name of the new
419 structure. The arguments in ... are of __ubsan_type_descriptor type
420 and there are at most two of them. MISMATCH are data used by ubsan
421 pointer checking. */
423 tree
424 ubsan_create_data (const char *name, const location_t *ploc,
425 const struct ubsan_mismatch_data *mismatch, ...)
427 va_list args;
428 tree ret, t;
429 tree fields[5];
430 vec<tree, va_gc> *saved_args = NULL;
431 size_t i = 0;
432 location_t loc = UNKNOWN_LOCATION;
434 /* Firstly, create a pointer to type descriptor type. */
435 tree td_type = ubsan_type_descriptor_type ();
436 TYPE_READONLY (td_type) = 1;
437 td_type = build_pointer_type (td_type);
439 /* Create the structure type. */
440 ret = make_node (RECORD_TYPE);
441 if (ploc != NULL)
443 loc = LOCATION_LOCUS (*ploc);
444 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
445 ubsan_source_location_type ());
446 DECL_CONTEXT (fields[i]) = ret;
447 i++;
450 va_start (args, mismatch);
451 for (t = va_arg (args, tree); t != NULL_TREE;
452 i++, t = va_arg (args, tree))
454 gcc_checking_assert (i < 3);
455 /* Save the tree arguments for later use. */
456 vec_safe_push (saved_args, t);
457 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
458 td_type);
459 DECL_CONTEXT (fields[i]) = ret;
460 if (i)
461 DECL_CHAIN (fields[i - 1]) = fields[i];
463 va_end (args);
465 if (mismatch != NULL)
467 /* We have to add two more decls. */
468 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
469 pointer_sized_int_node);
470 DECL_CONTEXT (fields[i]) = ret;
471 DECL_CHAIN (fields[i - 1]) = fields[i];
472 i++;
474 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
475 unsigned_char_type_node);
476 DECL_CONTEXT (fields[i]) = ret;
477 DECL_CHAIN (fields[i - 1]) = fields[i];
478 i++;
481 TYPE_FIELDS (ret) = fields[0];
482 TYPE_NAME (ret) = get_identifier (name);
483 layout_type (ret);
485 /* Now, fill in the type. */
486 char tmp_name[32];
487 static unsigned int ubsan_var_id_num;
488 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
489 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
490 ret);
491 TREE_STATIC (var) = 1;
492 TREE_PUBLIC (var) = 0;
493 DECL_ARTIFICIAL (var) = 1;
494 DECL_IGNORED_P (var) = 1;
495 DECL_EXTERNAL (var) = 0;
497 vec<constructor_elt, va_gc> *v;
498 vec_alloc (v, i);
499 tree ctor = build_constructor (ret, v);
501 /* If desirable, set the __ubsan_source_location element. */
502 if (ploc != NULL)
503 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
505 size_t nelts = vec_safe_length (saved_args);
506 for (i = 0; i < nelts; i++)
508 t = (*saved_args)[i];
509 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
512 if (mismatch != NULL)
514 /* Append the pointer data. */
515 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->align);
516 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->ckind);
519 TREE_CONSTANT (ctor) = 1;
520 TREE_STATIC (ctor) = 1;
521 DECL_INITIAL (var) = ctor;
522 varpool_finalize_decl (var);
524 return var;
527 /* Instrument the __builtin_unreachable call. We just call the libubsan
528 routine instead. */
530 tree
531 ubsan_instrument_unreachable (location_t loc)
533 if (flag_sanitize_undefined_trap_on_error)
534 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
536 initialize_sanitizer_builtins ();
537 tree data = ubsan_create_data ("__ubsan_unreachable_data", &loc, NULL,
538 NULL_TREE);
539 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
540 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
543 /* Return true if T is a call to a libubsan routine. */
545 bool
546 is_ubsan_builtin_p (tree t)
548 return TREE_CODE (t) == FUNCTION_DECL
549 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
550 "__builtin___ubsan_", 18) == 0;
553 /* Expand UBSAN_NULL internal call. */
555 void
556 ubsan_expand_null_ifn (gimple_stmt_iterator gsi)
558 gimple stmt = gsi_stmt (gsi);
559 location_t loc = gimple_location (stmt);
560 gcc_assert (gimple_call_num_args (stmt) == 2);
561 tree ptr = gimple_call_arg (stmt, 0);
562 tree ckind = gimple_call_arg (stmt, 1);
564 basic_block cur_bb = gsi_bb (gsi);
566 /* Split the original block holding the pointer dereference. */
567 edge e = split_block (cur_bb, stmt);
569 /* Get a hold on the 'condition block', the 'then block' and the
570 'else block'. */
571 basic_block cond_bb = e->src;
572 basic_block fallthru_bb = e->dest;
573 basic_block then_bb = create_empty_bb (cond_bb);
574 if (current_loops)
576 add_bb_to_loop (then_bb, cond_bb->loop_father);
577 loops_state_set (LOOPS_NEED_FIXUP);
580 /* Make an edge coming from the 'cond block' into the 'then block';
581 this edge is unlikely taken, so set up the probability accordingly. */
582 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
583 e->probability = PROB_VERY_UNLIKELY;
585 /* Connect 'then block' with the 'else block'. This is needed
586 as the ubsan routines we call in the 'then block' are not noreturn.
587 The 'then block' only has one outcoming edge. */
588 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
590 /* Set up the fallthrough basic block. */
591 e = find_edge (cond_bb, fallthru_bb);
592 e->flags = EDGE_FALSE_VALUE;
593 e->count = cond_bb->count;
594 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
596 /* Update dominance info for the newly created then_bb; note that
597 fallthru_bb's dominance info has already been updated by
598 split_bock. */
599 if (dom_info_available_p (CDI_DOMINATORS))
600 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
602 /* Put the ubsan builtin call into the newly created BB. */
603 gimple g;
604 if (flag_sanitize_undefined_trap_on_error)
605 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
606 else
608 enum built_in_function bcode
609 = flag_sanitize_recover
610 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
611 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
612 tree fn = builtin_decl_implicit (bcode);
613 const struct ubsan_mismatch_data m
614 = { build_zero_cst (pointer_sized_int_node), ckind };
615 tree data = ubsan_create_data ("__ubsan_null_data", &loc, &m,
616 ubsan_type_descriptor (TREE_TYPE (ptr),
617 true), NULL_TREE);
618 data = build_fold_addr_expr_loc (loc, data);
619 g = gimple_build_call (fn, 2, data,
620 build_zero_cst (pointer_sized_int_node));
622 gimple_set_location (g, loc);
623 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
624 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
626 /* Unlink the UBSAN_NULLs vops before replacing it. */
627 unlink_stmt_vdef (stmt);
629 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
630 NULL_TREE, NULL_TREE);
631 gimple_set_location (g, loc);
633 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
634 gsi_replace (&gsi, g, false);
637 /* Instrument a member call. We check whether 'this' is NULL. */
639 static void
640 instrument_member_call (gimple_stmt_iterator *iter)
642 tree this_parm = gimple_call_arg (gsi_stmt (*iter), 0);
643 tree kind = build_int_cst (unsigned_char_type_node, UBSAN_MEMBER_CALL);
644 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, this_parm, kind);
645 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
646 gsi_insert_before (iter, g, GSI_SAME_STMT);
649 /* Instrument a memory reference. T is the pointer, IS_LHS says
650 whether the pointer is on the left hand side of the assignment. */
652 static void
653 instrument_mem_ref (tree t, gimple_stmt_iterator *iter, bool is_lhs)
655 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
656 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
657 ikind = UBSAN_MEMBER_ACCESS;
658 tree kind = build_int_cst (unsigned_char_type_node, ikind);
659 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, t, kind);
660 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
661 gsi_insert_before (iter, g, GSI_SAME_STMT);
664 /* Perform the pointer instrumentation. */
666 static void
667 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
669 gimple stmt = gsi_stmt (gsi);
670 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
671 t = get_base_address (t);
672 const enum tree_code code = TREE_CODE (t);
673 if (code == MEM_REF
674 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
675 instrument_mem_ref (TREE_OPERAND (t, 0), &gsi, is_lhs);
676 else if (code == ADDR_EXPR
677 && POINTER_TYPE_P (TREE_TYPE (t))
678 && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == METHOD_TYPE)
679 instrument_member_call (&gsi);
682 /* Build an ubsan builtin call for the signed-integer-overflow
683 sanitization. CODE says what kind of builtin are we building,
684 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
685 are operands of the binary operation. */
687 tree
688 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
689 tree op0, tree op1)
691 if (flag_sanitize_undefined_trap_on_error)
692 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
694 tree data = ubsan_create_data ("__ubsan_overflow_data", &loc, NULL,
695 ubsan_type_descriptor (lhstype, false),
696 NULL_TREE);
697 enum built_in_function fn_code;
699 switch (code)
701 case PLUS_EXPR:
702 fn_code = flag_sanitize_recover
703 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
704 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
705 break;
706 case MINUS_EXPR:
707 fn_code = flag_sanitize_recover
708 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
709 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
710 break;
711 case MULT_EXPR:
712 fn_code = flag_sanitize_recover
713 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
714 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
715 break;
716 case NEGATE_EXPR:
717 fn_code = flag_sanitize_recover
718 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
719 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
720 break;
721 default:
722 gcc_unreachable ();
724 tree fn = builtin_decl_explicit (fn_code);
725 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
726 build_fold_addr_expr_loc (loc, data),
727 ubsan_encode_value (op0, true),
728 op1 ? ubsan_encode_value (op1, true)
729 : NULL_TREE);
732 /* Perform the signed integer instrumentation. GSI is the iterator
733 pointing at statement we are trying to instrument. */
735 static void
736 instrument_si_overflow (gimple_stmt_iterator gsi)
738 gimple stmt = gsi_stmt (gsi);
739 tree_code code = gimple_assign_rhs_code (stmt);
740 tree lhs = gimple_assign_lhs (stmt);
741 tree lhstype = TREE_TYPE (lhs);
742 tree a, b;
743 gimple g;
745 /* If this is not a signed operation, don't instrument anything here.
746 Also punt on bit-fields. */
747 if (!INTEGRAL_TYPE_P (lhstype)
748 || TYPE_OVERFLOW_WRAPS (lhstype)
749 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
750 return;
752 switch (code)
754 case MINUS_EXPR:
755 case PLUS_EXPR:
756 case MULT_EXPR:
757 /* Transform
758 i = u {+,-,*} 5;
759 into
760 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
761 a = gimple_assign_rhs1 (stmt);
762 b = gimple_assign_rhs2 (stmt);
763 g = gimple_build_call_internal (code == PLUS_EXPR
764 ? IFN_UBSAN_CHECK_ADD
765 : code == MINUS_EXPR
766 ? IFN_UBSAN_CHECK_SUB
767 : IFN_UBSAN_CHECK_MUL, 2, a, b);
768 gimple_call_set_lhs (g, lhs);
769 gsi_replace (&gsi, g, false);
770 break;
771 case NEGATE_EXPR:
772 /* Represent i = -u;
774 i = UBSAN_CHECK_SUB (0, u); */
775 a = build_int_cst (lhstype, 0);
776 b = gimple_assign_rhs1 (stmt);
777 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
778 gimple_call_set_lhs (g, lhs);
779 gsi_replace (&gsi, g, false);
780 break;
781 case ABS_EXPR:
782 /* Transform i = ABS_EXPR<u>;
783 into
784 _N = UBSAN_CHECK_SUB (0, u);
785 i = ABS_EXPR<_N>; */
786 a = build_int_cst (lhstype, 0);
787 b = gimple_assign_rhs1 (stmt);
788 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
789 a = make_ssa_name (lhstype, NULL);
790 gimple_call_set_lhs (g, a);
791 gimple_set_location (g, gimple_location (stmt));
792 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
793 gimple_assign_set_rhs1 (stmt, a);
794 update_stmt (stmt);
795 break;
796 default:
797 break;
801 /* Instrument loads from (non-bitfield) bool and C++ enum values
802 to check if the memory value is outside of the range of the valid
803 type values. */
805 static void
806 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
808 gimple stmt = gsi_stmt (*gsi);
809 tree rhs = gimple_assign_rhs1 (stmt);
810 tree type = TREE_TYPE (rhs);
811 tree minv = NULL_TREE, maxv = NULL_TREE;
813 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
815 minv = boolean_false_node;
816 maxv = boolean_true_node;
818 else if (TREE_CODE (type) == ENUMERAL_TYPE
819 && (flag_sanitize & SANITIZE_ENUM)
820 && TREE_TYPE (type) != NULL_TREE
821 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
822 && (TYPE_PRECISION (TREE_TYPE (type))
823 < GET_MODE_PRECISION (TYPE_MODE (type))))
825 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
826 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
828 else
829 return;
831 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
832 HOST_WIDE_INT bitsize, bitpos;
833 tree offset;
834 enum machine_mode mode;
835 int volatilep = 0, unsignedp = 0;
836 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
837 &unsignedp, &volatilep, false);
838 tree utype = build_nonstandard_integer_type (modebitsize, 1);
840 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
841 || (bitpos % modebitsize) != 0
842 || bitsize != modebitsize
843 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
844 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
845 return;
847 location_t loc = gimple_location (stmt);
848 tree ptype = build_pointer_type (TREE_TYPE (rhs));
849 tree atype = reference_alias_ptr_type (rhs);
850 gimple g = gimple_build_assign (make_ssa_name (ptype, NULL),
851 build_fold_addr_expr (rhs));
852 gimple_set_location (g, loc);
853 gsi_insert_before (gsi, g, GSI_SAME_STMT);
854 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
855 build_int_cst (atype, 0));
856 tree urhs = make_ssa_name (utype, NULL);
857 g = gimple_build_assign (urhs, mem);
858 gimple_set_location (g, loc);
859 gsi_insert_before (gsi, g, GSI_SAME_STMT);
860 minv = fold_convert (utype, minv);
861 maxv = fold_convert (utype, maxv);
862 if (!integer_zerop (minv))
864 g = gimple_build_assign_with_ops (MINUS_EXPR,
865 make_ssa_name (utype, NULL),
866 urhs, minv);
867 gimple_set_location (g, loc);
868 gsi_insert_before (gsi, g, GSI_SAME_STMT);
871 gimple_stmt_iterator gsi2 = *gsi;
872 basic_block then_bb, fallthru_bb;
873 *gsi = create_cond_insert_point (gsi, true, false, true,
874 &then_bb, &fallthru_bb);
875 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
876 int_const_binop (MINUS_EXPR, maxv, minv),
877 NULL_TREE, NULL_TREE);
878 gimple_set_location (g, loc);
879 gsi_insert_after (gsi, g, GSI_NEW_STMT);
881 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
882 update_stmt (stmt);
884 gsi2 = gsi_after_labels (then_bb);
885 if (flag_sanitize_undefined_trap_on_error)
886 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
887 else
889 tree data = ubsan_create_data ("__ubsan_invalid_value_data", &loc, NULL,
890 ubsan_type_descriptor (type, false),
891 NULL_TREE);
892 data = build_fold_addr_expr_loc (loc, data);
893 enum built_in_function bcode
894 = flag_sanitize_recover
895 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
896 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
897 tree fn = builtin_decl_explicit (bcode);
899 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
900 true, NULL_TREE, true,
901 GSI_SAME_STMT);
902 g = gimple_build_call (fn, 2, data, val);
904 gimple_set_location (g, loc);
905 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
908 /* Instrument float point-to-integer conversion. TYPE is an integer type of
909 destination, EXPR is floating-point expression. */
911 tree
912 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
914 tree expr_type = TREE_TYPE (expr);
915 tree t, tt, fn, min, max;
916 enum machine_mode mode = TYPE_MODE (expr_type);
917 int prec = TYPE_PRECISION (type);
918 bool uns_p = TYPE_UNSIGNED (type);
920 /* Float to integer conversion first truncates toward zero, so
921 even signed char c = 127.875f; is not problematic.
922 Therefore, we should complain only if EXPR is unordered or smaller
923 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
924 TYPE_MAX_VALUE + 1.0. */
925 if (REAL_MODE_FORMAT (mode)->b == 2)
927 /* For maximum, TYPE_MAX_VALUE might not be representable
928 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
929 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
930 either representable or infinity. */
931 REAL_VALUE_TYPE maxval = dconst1;
932 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
933 real_convert (&maxval, mode, &maxval);
934 max = build_real (expr_type, maxval);
936 /* For unsigned, assume -1.0 is always representable. */
937 if (uns_p)
938 min = build_minus_one_cst (expr_type);
939 else
941 /* TYPE_MIN_VALUE is generally representable (or -inf),
942 but TYPE_MIN_VALUE - 1.0 might not be. */
943 REAL_VALUE_TYPE minval = dconstm1, minval2;
944 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
945 real_convert (&minval, mode, &minval);
946 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
947 real_convert (&minval2, mode, &minval2);
948 if (real_compare (EQ_EXPR, &minval, &minval2)
949 && !real_isinf (&minval))
951 /* If TYPE_MIN_VALUE - 1.0 is not representable and
952 rounds to TYPE_MIN_VALUE, we need to subtract
953 more. As REAL_MODE_FORMAT (mode)->p is the number
954 of base digits, we want to subtract a number that
955 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
956 times smaller than minval. */
957 minval2 = dconst1;
958 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
959 SET_REAL_EXP (&minval2,
960 REAL_EXP (&minval2) + prec - 1
961 - REAL_MODE_FORMAT (mode)->p + 1);
962 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
963 real_convert (&minval2, mode, &minval2);
965 min = build_real (expr_type, minval2);
968 else if (REAL_MODE_FORMAT (mode)->b == 10)
970 /* For _Decimal128 up to 34 decimal digits, - sign,
971 dot, e, exponent. */
972 char buf[64];
973 mpfr_t m;
974 int p = REAL_MODE_FORMAT (mode)->p;
975 REAL_VALUE_TYPE maxval, minval;
977 /* Use mpfr_snprintf rounding to compute the smallest
978 representable decimal number greater or equal than
979 1 << (prec - !uns_p). */
980 mpfr_init2 (m, prec + 2);
981 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
982 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
983 decimal_real_from_string (&maxval, buf);
984 max = build_real (expr_type, maxval);
986 /* For unsigned, assume -1.0 is always representable. */
987 if (uns_p)
988 min = build_minus_one_cst (expr_type);
989 else
991 /* Use mpfr_snprintf rounding to compute the largest
992 representable decimal number less or equal than
993 (-1 << (prec - 1)) - 1. */
994 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
995 mpfr_sub_ui (m, m, 1, GMP_RNDN);
996 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
997 decimal_real_from_string (&minval, buf);
998 min = build_real (expr_type, minval);
1000 mpfr_clear (m);
1002 else
1003 return NULL_TREE;
1005 if (flag_sanitize_undefined_trap_on_error)
1006 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1007 else
1009 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1010 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", NULL,
1011 NULL,
1012 ubsan_type_descriptor (expr_type, false),
1013 ubsan_type_descriptor (type, false),
1014 NULL_TREE);
1015 enum built_in_function bcode
1016 = flag_sanitize_recover
1017 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1018 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1019 fn = builtin_decl_explicit (bcode);
1020 fn = build_call_expr_loc (loc, fn, 2,
1021 build_fold_addr_expr_loc (loc, data),
1022 ubsan_encode_value (expr, false));
1025 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1026 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1027 return fold_build3 (COND_EXPR, void_type_node,
1028 fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt),
1029 fn, integer_zero_node);
1032 namespace {
1034 const pass_data pass_data_ubsan =
1036 GIMPLE_PASS, /* type */
1037 "ubsan", /* name */
1038 OPTGROUP_NONE, /* optinfo_flags */
1039 true, /* has_execute */
1040 TV_TREE_UBSAN, /* tv_id */
1041 ( PROP_cfg | PROP_ssa ), /* properties_required */
1042 0, /* properties_provided */
1043 0, /* properties_destroyed */
1044 0, /* todo_flags_start */
1045 TODO_update_ssa, /* todo_flags_finish */
1048 class pass_ubsan : public gimple_opt_pass
1050 public:
1051 pass_ubsan (gcc::context *ctxt)
1052 : gimple_opt_pass (pass_data_ubsan, ctxt)
1055 /* opt_pass methods: */
1056 virtual bool gate (function *)
1058 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1059 | SANITIZE_BOOL | SANITIZE_ENUM);
1062 virtual unsigned int execute (function *);
1064 }; // class pass_ubsan
1066 unsigned int
1067 pass_ubsan::execute (function *fun)
1069 basic_block bb;
1070 gimple_stmt_iterator gsi;
1072 initialize_sanitizer_builtins ();
1074 FOR_EACH_BB_FN (bb, fun)
1076 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1078 gimple stmt = gsi_stmt (gsi);
1079 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1081 gsi_next (&gsi);
1082 continue;
1085 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1086 && is_gimple_assign (stmt))
1087 instrument_si_overflow (gsi);
1089 if (flag_sanitize & SANITIZE_NULL)
1091 if (gimple_store_p (stmt))
1092 instrument_null (gsi, true);
1093 if (gimple_assign_load_p (stmt))
1094 instrument_null (gsi, false);
1097 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1098 && gimple_assign_load_p (stmt))
1099 instrument_bool_enum_load (&gsi);
1101 gsi_next (&gsi);
1104 return 0;
1107 } // anon namespace
1109 gimple_opt_pass *
1110 make_pass_ubsan (gcc::context *ctxt)
1112 return new pass_ubsan (ctxt);
1115 #include "gt-ubsan.h"