Fix dot dump bug
[official-gcc.git] / gcc / ubsan.c
blob5a8a4479404709d7fb866d78e0b0e4298c1d3bb9
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 add_bb_to_loop (then_bb, cond_bb->loop_father);
575 loops_state_set (LOOPS_NEED_FIXUP);
577 /* Make an edge coming from the 'cond block' into the 'then block';
578 this edge is unlikely taken, so set up the probability accordingly. */
579 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
580 e->probability = PROB_VERY_UNLIKELY;
582 /* Connect 'then block' with the 'else block'. This is needed
583 as the ubsan routines we call in the 'then block' are not noreturn.
584 The 'then block' only has one outcoming edge. */
585 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
587 /* Set up the fallthrough basic block. */
588 e = find_edge (cond_bb, fallthru_bb);
589 e->flags = EDGE_FALSE_VALUE;
590 e->count = cond_bb->count;
591 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
593 /* Update dominance info for the newly created then_bb; note that
594 fallthru_bb's dominance info has already been updated by
595 split_bock. */
596 if (dom_info_available_p (CDI_DOMINATORS))
597 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
599 /* Put the ubsan builtin call into the newly created BB. */
600 gimple g;
601 if (flag_sanitize_undefined_trap_on_error)
602 g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
603 else
605 enum built_in_function bcode
606 = flag_sanitize_recover
607 ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH
608 : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_ABORT;
609 tree fn = builtin_decl_implicit (bcode);
610 const struct ubsan_mismatch_data m
611 = { build_zero_cst (pointer_sized_int_node), ckind };
612 tree data = ubsan_create_data ("__ubsan_null_data", &loc, &m,
613 ubsan_type_descriptor (TREE_TYPE (ptr),
614 true), NULL_TREE);
615 data = build_fold_addr_expr_loc (loc, data);
616 g = gimple_build_call (fn, 2, data,
617 build_zero_cst (pointer_sized_int_node));
619 gimple_set_location (g, loc);
620 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
621 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
623 /* Unlink the UBSAN_NULLs vops before replacing it. */
624 unlink_stmt_vdef (stmt);
626 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
627 NULL_TREE, NULL_TREE);
628 gimple_set_location (g, loc);
630 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
631 gsi_replace (&gsi, g, false);
634 /* Instrument a member call. We check whether 'this' is NULL. */
636 static void
637 instrument_member_call (gimple_stmt_iterator *iter)
639 tree this_parm = gimple_call_arg (gsi_stmt (*iter), 0);
640 tree kind = build_int_cst (unsigned_char_type_node, UBSAN_MEMBER_CALL);
641 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, this_parm, kind);
642 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
643 gsi_insert_before (iter, g, GSI_SAME_STMT);
646 /* Instrument a memory reference. T is the pointer, IS_LHS says
647 whether the pointer is on the left hand side of the assignment. */
649 static void
650 instrument_mem_ref (tree t, gimple_stmt_iterator *iter, bool is_lhs)
652 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
653 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
654 ikind = UBSAN_MEMBER_ACCESS;
655 tree kind = build_int_cst (unsigned_char_type_node, ikind);
656 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, t, kind);
657 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
658 gsi_insert_before (iter, g, GSI_SAME_STMT);
661 /* Perform the pointer instrumentation. */
663 static void
664 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
666 gimple stmt = gsi_stmt (gsi);
667 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
668 t = get_base_address (t);
669 const enum tree_code code = TREE_CODE (t);
670 if (code == MEM_REF
671 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
672 instrument_mem_ref (TREE_OPERAND (t, 0), &gsi, is_lhs);
673 else if (code == ADDR_EXPR
674 && POINTER_TYPE_P (TREE_TYPE (t))
675 && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == METHOD_TYPE)
676 instrument_member_call (&gsi);
679 /* Build an ubsan builtin call for the signed-integer-overflow
680 sanitization. CODE says what kind of builtin are we building,
681 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
682 are operands of the binary operation. */
684 tree
685 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
686 tree op0, tree op1)
688 if (flag_sanitize_undefined_trap_on_error)
689 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
691 tree data = ubsan_create_data ("__ubsan_overflow_data", &loc, NULL,
692 ubsan_type_descriptor (lhstype, false),
693 NULL_TREE);
694 enum built_in_function fn_code;
696 switch (code)
698 case PLUS_EXPR:
699 fn_code = flag_sanitize_recover
700 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
701 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
702 break;
703 case MINUS_EXPR:
704 fn_code = flag_sanitize_recover
705 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
706 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
707 break;
708 case MULT_EXPR:
709 fn_code = flag_sanitize_recover
710 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
711 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
712 break;
713 case NEGATE_EXPR:
714 fn_code = flag_sanitize_recover
715 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
716 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
717 break;
718 default:
719 gcc_unreachable ();
721 tree fn = builtin_decl_explicit (fn_code);
722 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
723 build_fold_addr_expr_loc (loc, data),
724 ubsan_encode_value (op0, true),
725 op1 ? ubsan_encode_value (op1, true)
726 : NULL_TREE);
729 /* Perform the signed integer instrumentation. GSI is the iterator
730 pointing at statement we are trying to instrument. */
732 static void
733 instrument_si_overflow (gimple_stmt_iterator gsi)
735 gimple stmt = gsi_stmt (gsi);
736 tree_code code = gimple_assign_rhs_code (stmt);
737 tree lhs = gimple_assign_lhs (stmt);
738 tree lhstype = TREE_TYPE (lhs);
739 tree a, b;
740 gimple g;
742 /* If this is not a signed operation, don't instrument anything here.
743 Also punt on bit-fields. */
744 if (!INTEGRAL_TYPE_P (lhstype)
745 || TYPE_OVERFLOW_WRAPS (lhstype)
746 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
747 return;
749 switch (code)
751 case MINUS_EXPR:
752 case PLUS_EXPR:
753 case MULT_EXPR:
754 /* Transform
755 i = u {+,-,*} 5;
756 into
757 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
758 a = gimple_assign_rhs1 (stmt);
759 b = gimple_assign_rhs2 (stmt);
760 g = gimple_build_call_internal (code == PLUS_EXPR
761 ? IFN_UBSAN_CHECK_ADD
762 : code == MINUS_EXPR
763 ? IFN_UBSAN_CHECK_SUB
764 : IFN_UBSAN_CHECK_MUL, 2, a, b);
765 gimple_call_set_lhs (g, lhs);
766 gsi_replace (&gsi, g, false);
767 break;
768 case NEGATE_EXPR:
769 /* Represent i = -u;
771 i = UBSAN_CHECK_SUB (0, u); */
772 a = build_int_cst (lhstype, 0);
773 b = gimple_assign_rhs1 (stmt);
774 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
775 gimple_call_set_lhs (g, lhs);
776 gsi_replace (&gsi, g, false);
777 break;
778 case ABS_EXPR:
779 /* Transform i = ABS_EXPR<u>;
780 into
781 _N = UBSAN_CHECK_SUB (0, u);
782 i = ABS_EXPR<_N>; */
783 a = build_int_cst (lhstype, 0);
784 b = gimple_assign_rhs1 (stmt);
785 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
786 a = make_ssa_name (lhstype, NULL);
787 gimple_call_set_lhs (g, a);
788 gimple_set_location (g, gimple_location (stmt));
789 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
790 gimple_assign_set_rhs1 (stmt, a);
791 update_stmt (stmt);
792 break;
793 default:
794 break;
798 /* Instrument loads from (non-bitfield) bool and C++ enum values
799 to check if the memory value is outside of the range of the valid
800 type values. */
802 static void
803 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
805 gimple stmt = gsi_stmt (*gsi);
806 tree rhs = gimple_assign_rhs1 (stmt);
807 tree type = TREE_TYPE (rhs);
808 tree minv = NULL_TREE, maxv = NULL_TREE;
810 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
812 minv = boolean_false_node;
813 maxv = boolean_true_node;
815 else if (TREE_CODE (type) == ENUMERAL_TYPE
816 && (flag_sanitize & SANITIZE_ENUM)
817 && TREE_TYPE (type) != NULL_TREE
818 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
819 && (TYPE_PRECISION (TREE_TYPE (type))
820 < GET_MODE_PRECISION (TYPE_MODE (type))))
822 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
823 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
825 else
826 return;
828 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
829 HOST_WIDE_INT bitsize, bitpos;
830 tree offset;
831 enum machine_mode mode;
832 int volatilep = 0, unsignedp = 0;
833 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
834 &unsignedp, &volatilep, false);
835 tree utype = build_nonstandard_integer_type (modebitsize, 1);
837 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
838 || (bitpos % modebitsize) != 0
839 || bitsize != modebitsize
840 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
841 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
842 return;
844 location_t loc = gimple_location (stmt);
845 tree ptype = build_pointer_type (TREE_TYPE (rhs));
846 tree atype = reference_alias_ptr_type (rhs);
847 gimple g = gimple_build_assign (make_ssa_name (ptype, NULL),
848 build_fold_addr_expr (rhs));
849 gimple_set_location (g, loc);
850 gsi_insert_before (gsi, g, GSI_SAME_STMT);
851 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
852 build_int_cst (atype, 0));
853 tree urhs = make_ssa_name (utype, NULL);
854 g = gimple_build_assign (urhs, mem);
855 gimple_set_location (g, loc);
856 gsi_insert_before (gsi, g, GSI_SAME_STMT);
857 minv = fold_convert (utype, minv);
858 maxv = fold_convert (utype, maxv);
859 if (!integer_zerop (minv))
861 g = gimple_build_assign_with_ops (MINUS_EXPR,
862 make_ssa_name (utype, NULL),
863 urhs, minv);
864 gimple_set_location (g, loc);
865 gsi_insert_before (gsi, g, GSI_SAME_STMT);
868 gimple_stmt_iterator gsi2 = *gsi;
869 basic_block then_bb, fallthru_bb;
870 *gsi = create_cond_insert_point (gsi, true, false, true,
871 &then_bb, &fallthru_bb);
872 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
873 int_const_binop (MINUS_EXPR, maxv, minv),
874 NULL_TREE, NULL_TREE);
875 gimple_set_location (g, loc);
876 gsi_insert_after (gsi, g, GSI_NEW_STMT);
878 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
879 update_stmt (stmt);
881 gsi2 = gsi_after_labels (then_bb);
882 if (flag_sanitize_undefined_trap_on_error)
883 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
884 else
886 tree data = ubsan_create_data ("__ubsan_invalid_value_data", &loc, NULL,
887 ubsan_type_descriptor (type, false),
888 NULL_TREE);
889 data = build_fold_addr_expr_loc (loc, data);
890 enum built_in_function bcode
891 = flag_sanitize_recover
892 ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
893 : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
894 tree fn = builtin_decl_explicit (bcode);
896 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
897 true, NULL_TREE, true,
898 GSI_SAME_STMT);
899 g = gimple_build_call (fn, 2, data, val);
901 gimple_set_location (g, loc);
902 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
905 /* Instrument float point-to-integer conversion. TYPE is an integer type of
906 destination, EXPR is floating-point expression. */
908 tree
909 ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
911 tree expr_type = TREE_TYPE (expr);
912 tree t, tt, fn, min, max;
913 enum machine_mode mode = TYPE_MODE (expr_type);
914 int prec = TYPE_PRECISION (type);
915 bool uns_p = TYPE_UNSIGNED (type);
917 /* Float to integer conversion first truncates toward zero, so
918 even signed char c = 127.875f; is not problematic.
919 Therefore, we should complain only if EXPR is unordered or smaller
920 or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
921 TYPE_MAX_VALUE + 1.0. */
922 if (REAL_MODE_FORMAT (mode)->b == 2)
924 /* For maximum, TYPE_MAX_VALUE might not be representable
925 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
926 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
927 either representable or infinity. */
928 REAL_VALUE_TYPE maxval = dconst1;
929 SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
930 real_convert (&maxval, mode, &maxval);
931 max = build_real (expr_type, maxval);
933 /* For unsigned, assume -1.0 is always representable. */
934 if (uns_p)
935 min = build_minus_one_cst (expr_type);
936 else
938 /* TYPE_MIN_VALUE is generally representable (or -inf),
939 but TYPE_MIN_VALUE - 1.0 might not be. */
940 REAL_VALUE_TYPE minval = dconstm1, minval2;
941 SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
942 real_convert (&minval, mode, &minval);
943 real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
944 real_convert (&minval2, mode, &minval2);
945 if (real_compare (EQ_EXPR, &minval, &minval2)
946 && !real_isinf (&minval))
948 /* If TYPE_MIN_VALUE - 1.0 is not representable and
949 rounds to TYPE_MIN_VALUE, we need to subtract
950 more. As REAL_MODE_FORMAT (mode)->p is the number
951 of base digits, we want to subtract a number that
952 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
953 times smaller than minval. */
954 minval2 = dconst1;
955 gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
956 SET_REAL_EXP (&minval2,
957 REAL_EXP (&minval2) + prec - 1
958 - REAL_MODE_FORMAT (mode)->p + 1);
959 real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
960 real_convert (&minval2, mode, &minval2);
962 min = build_real (expr_type, minval2);
965 else if (REAL_MODE_FORMAT (mode)->b == 10)
967 /* For _Decimal128 up to 34 decimal digits, - sign,
968 dot, e, exponent. */
969 char buf[64];
970 mpfr_t m;
971 int p = REAL_MODE_FORMAT (mode)->p;
972 REAL_VALUE_TYPE maxval, minval;
974 /* Use mpfr_snprintf rounding to compute the smallest
975 representable decimal number greater or equal than
976 1 << (prec - !uns_p). */
977 mpfr_init2 (m, prec + 2);
978 mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
979 mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
980 decimal_real_from_string (&maxval, buf);
981 max = build_real (expr_type, maxval);
983 /* For unsigned, assume -1.0 is always representable. */
984 if (uns_p)
985 min = build_minus_one_cst (expr_type);
986 else
988 /* Use mpfr_snprintf rounding to compute the largest
989 representable decimal number less or equal than
990 (-1 << (prec - 1)) - 1. */
991 mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
992 mpfr_sub_ui (m, m, 1, GMP_RNDN);
993 mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
994 decimal_real_from_string (&minval, buf);
995 min = build_real (expr_type, minval);
997 mpfr_clear (m);
999 else
1000 return NULL_TREE;
1002 if (flag_sanitize_undefined_trap_on_error)
1003 fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
1004 else
1006 /* Create the __ubsan_handle_float_cast_overflow fn call. */
1007 tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", NULL,
1008 NULL,
1009 ubsan_type_descriptor (expr_type, false),
1010 ubsan_type_descriptor (type, false),
1011 NULL_TREE);
1012 enum built_in_function bcode
1013 = flag_sanitize_recover
1014 ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
1015 : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
1016 fn = builtin_decl_explicit (bcode);
1017 fn = build_call_expr_loc (loc, fn, 2,
1018 build_fold_addr_expr_loc (loc, data),
1019 ubsan_encode_value (expr, false));
1022 t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
1023 tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
1024 return fold_build3 (COND_EXPR, void_type_node,
1025 fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt),
1026 fn, integer_zero_node);
1029 namespace {
1031 const pass_data pass_data_ubsan =
1033 GIMPLE_PASS, /* type */
1034 "ubsan", /* name */
1035 OPTGROUP_NONE, /* optinfo_flags */
1036 true, /* has_execute */
1037 TV_TREE_UBSAN, /* tv_id */
1038 ( PROP_cfg | PROP_ssa ), /* properties_required */
1039 0, /* properties_provided */
1040 0, /* properties_destroyed */
1041 0, /* todo_flags_start */
1042 TODO_update_ssa, /* todo_flags_finish */
1045 class pass_ubsan : public gimple_opt_pass
1047 public:
1048 pass_ubsan (gcc::context *ctxt)
1049 : gimple_opt_pass (pass_data_ubsan, ctxt)
1052 /* opt_pass methods: */
1053 virtual bool gate (function *)
1055 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
1056 | SANITIZE_BOOL | SANITIZE_ENUM);
1059 virtual unsigned int execute (function *);
1061 }; // class pass_ubsan
1063 unsigned int
1064 pass_ubsan::execute (function *fun)
1066 basic_block bb;
1067 gimple_stmt_iterator gsi;
1069 initialize_sanitizer_builtins ();
1071 FOR_EACH_BB_FN (bb, fun)
1073 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
1075 gimple stmt = gsi_stmt (gsi);
1076 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
1078 gsi_next (&gsi);
1079 continue;
1082 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
1083 && is_gimple_assign (stmt))
1084 instrument_si_overflow (gsi);
1086 if (flag_sanitize & SANITIZE_NULL)
1088 if (gimple_store_p (stmt))
1089 instrument_null (gsi, true);
1090 if (gimple_assign_load_p (stmt))
1091 instrument_null (gsi, false);
1094 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
1095 && gimple_assign_load_p (stmt))
1096 instrument_bool_enum_load (&gsi);
1098 gsi_next (&gsi);
1101 return 0;
1104 } // anon namespace
1106 gimple_opt_pass *
1107 make_pass_ubsan (gcc::context *ctxt)
1109 return new pass_ubsan (ctxt);
1112 #include "gt-ubsan.h"