Daily bump.
[official-gcc.git] / gcc / ubsan.c
blob25c2cde60401790c6cd1df4b28a19360ec7baa2c
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 "tree-eh.h"
52 /* Map from a tree to a VAR_DECL tree. */
54 struct GTY(()) tree_type_map {
55 struct tree_map_base type;
56 tree decl;
59 #define tree_type_map_eq tree_map_base_eq
60 #define tree_type_map_marked_p tree_map_base_marked_p
62 /* Hash from a tree in a tree_type_map. */
64 unsigned int
65 tree_type_map_hash (const void *item)
67 return TYPE_UID (((const struct tree_type_map *)item)->type.from);
70 static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map)))
71 htab_t decl_tree_for_type;
73 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
75 static tree
76 decl_for_type_lookup (tree type)
78 /* If the hash table is not initialized yet, create it now. */
79 if (decl_tree_for_type == NULL)
81 decl_tree_for_type = htab_create_ggc (10, tree_type_map_hash,
82 tree_type_map_eq, 0);
83 /* That also means we don't have to bother with the lookup. */
84 return NULL_TREE;
87 struct tree_type_map *h, in;
88 in.type.from = type;
90 h = (struct tree_type_map *)
91 htab_find_with_hash (decl_tree_for_type, &in, TYPE_UID (type));
92 return h ? h->decl : NULL_TREE;
95 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
97 static void
98 decl_for_type_insert (tree type, tree decl)
100 struct tree_type_map *h;
101 void **slot;
103 h = ggc_alloc_tree_type_map ();
104 h->type.from = type;
105 h->decl = decl;
106 slot = htab_find_slot_with_hash (decl_tree_for_type, h, TYPE_UID (type),
107 INSERT);
108 *(struct tree_type_map **) slot = h;
111 /* Helper routine, which encodes a value in the pointer_sized_int_node.
112 Arguments with precision <= POINTER_SIZE are passed directly,
113 the rest is passed by reference. T is a value we are to encode.
114 IN_EXPAND_P is true if this function is called during expansion. */
116 tree
117 ubsan_encode_value (tree t, bool in_expand_p)
119 tree type = TREE_TYPE (t);
120 const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
121 if (bitsize <= POINTER_SIZE)
122 switch (TREE_CODE (type))
124 case BOOLEAN_TYPE:
125 case ENUMERAL_TYPE:
126 case INTEGER_TYPE:
127 return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
128 case REAL_TYPE:
130 tree itype = build_nonstandard_integer_type (bitsize, true);
131 t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
132 return fold_convert (pointer_sized_int_node, t);
134 default:
135 gcc_unreachable ();
137 else
139 if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
141 /* The reason for this is that we don't want to pessimize
142 code by making vars unnecessarily addressable. */
143 tree var = create_tmp_var (type, NULL);
144 tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
145 if (in_expand_p)
147 rtx mem
148 = assign_stack_temp_for_type (TYPE_MODE (type),
149 GET_MODE_SIZE (TYPE_MODE (type)),
150 type);
151 SET_DECL_RTL (var, mem);
152 expand_assignment (var, t, false);
153 return build_fold_addr_expr (var);
155 t = build_fold_addr_expr (var);
156 return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
158 else
159 return build_fold_addr_expr (t);
163 /* Build
164 struct __ubsan_type_descriptor
166 unsigned short __typekind;
167 unsigned short __typeinfo;
168 char __typename[];
170 type. */
172 static tree
173 ubsan_type_descriptor_type (void)
175 static const char *field_names[3]
176 = { "__typekind", "__typeinfo", "__typename" };
177 tree fields[3], ret;
178 tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
179 tree flex_arr_type = build_array_type (char_type_node, itype);
181 ret = make_node (RECORD_TYPE);
182 for (int i = 0; i < 3; i++)
184 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
185 get_identifier (field_names[i]),
186 (i == 2) ? flex_arr_type
187 : short_unsigned_type_node);
188 DECL_CONTEXT (fields[i]) = ret;
189 if (i)
190 DECL_CHAIN (fields[i - 1]) = fields[i];
192 TYPE_FIELDS (ret) = fields[0];
193 TYPE_NAME (ret) = get_identifier ("__ubsan_type_descriptor");
194 layout_type (ret);
195 return ret;
198 /* Build
199 struct __ubsan_source_location
201 const char *__filename;
202 unsigned int __line;
203 unsigned int __column;
205 type. */
207 static tree
208 ubsan_source_location_type (void)
210 static const char *field_names[3]
211 = { "__filename", "__line", "__column" };
212 tree fields[3], ret;
213 tree const_char_type = build_qualified_type (char_type_node,
214 TYPE_QUAL_CONST);
216 ret = make_node (RECORD_TYPE);
217 for (int i = 0; i < 3; i++)
219 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
220 get_identifier (field_names[i]),
221 (i == 0) ? build_pointer_type (const_char_type)
222 : unsigned_type_node);
223 DECL_CONTEXT (fields[i]) = ret;
224 if (i)
225 DECL_CHAIN (fields[i - 1]) = fields[i];
227 TYPE_FIELDS (ret) = fields[0];
228 TYPE_NAME (ret) = get_identifier ("__ubsan_source_location");
229 layout_type (ret);
230 return ret;
233 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
234 type with its fields filled from a location_t LOC. */
236 static tree
237 ubsan_source_location (location_t loc)
239 expanded_location xloc;
240 tree type = ubsan_source_location_type ();
242 xloc = expand_location (loc);
243 if (xloc.file == NULL)
244 xloc.file = "<unknown>";
246 /* Fill in the values from LOC. */
247 size_t len = strlen (xloc.file);
248 tree str = build_string (len + 1, xloc.file);
249 TREE_TYPE (str) = build_array_type (char_type_node,
250 build_index_type (size_int (len)));
251 TREE_READONLY (str) = 1;
252 TREE_STATIC (str) = 1;
253 str = build_fold_addr_expr (str);
254 tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
255 build_int_cst (unsigned_type_node,
256 xloc.line), NULL_TREE,
257 build_int_cst (unsigned_type_node,
258 xloc.column));
259 TREE_CONSTANT (ctor) = 1;
260 TREE_STATIC (ctor) = 1;
262 return ctor;
265 /* This routine returns a magic number for TYPE. */
267 static unsigned short
268 get_ubsan_type_info_for_type (tree type)
270 gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
271 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
272 gcc_assert (prec != -1);
273 return (prec << 1) | !TYPE_UNSIGNED (type);
276 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
277 descriptor. It first looks into the hash table; if not found,
278 create the VAR_DECL, put it into the hash table and return the
279 ADDR_EXPR of it. TYPE describes a particular type. WANT_POINTER_TYPE_P
280 means whether we are interested in the pointer type and not the pointer
281 itself. */
283 tree
284 ubsan_type_descriptor (tree type, bool want_pointer_type_p)
286 /* See through any typedefs. */
287 type = TYPE_MAIN_VARIANT (type);
289 tree decl = decl_for_type_lookup (type);
290 /* It is possible that some of the earlier created DECLs were found
291 unused, in that case they weren't emitted and varpool_get_node
292 returns NULL node on them. But now we really need them. Thus,
293 renew them here. */
294 if (decl != NULL_TREE && varpool_get_node (decl))
295 return build_fold_addr_expr (decl);
297 tree dtype = ubsan_type_descriptor_type ();
298 tree type2 = type;
299 const char *tname = NULL;
300 char *pretty_name;
301 unsigned char deref_depth = 0;
302 unsigned short tkind, tinfo;
304 /* Get the name of the type, or the name of the pointer type. */
305 if (want_pointer_type_p)
307 gcc_assert (POINTER_TYPE_P (type));
308 type2 = TREE_TYPE (type);
310 /* Remove any '*' operators from TYPE. */
311 while (POINTER_TYPE_P (type2))
312 deref_depth++, type2 = TREE_TYPE (type2);
314 if (TREE_CODE (type2) == METHOD_TYPE)
315 type2 = TYPE_METHOD_BASETYPE (type2);
318 /* If an array, get its type. */
319 type2 = strip_array_types (type2);
321 if (TYPE_NAME (type2) != NULL)
323 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
324 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
325 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
326 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
329 if (tname == NULL)
330 /* We weren't able to determine the type name. */
331 tname = "<unknown>";
333 /* Decorate the type name with '', '*', "struct", or "union". */
334 pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
335 if (want_pointer_type_p)
337 int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
338 TYPE_VOLATILE (type2) ? "volatile " : "",
339 TYPE_READONLY (type2) ? "const " : "",
340 TYPE_RESTRICT (type2) ? "restrict " : "",
341 TYPE_ATOMIC (type2) ? "_Atomic " : "",
342 TREE_CODE (type2) == RECORD_TYPE
343 ? "struct "
344 : TREE_CODE (type2) == UNION_TYPE
345 ? "union " : "", tname,
346 deref_depth == 0 ? "" : " ");
347 while (deref_depth-- > 0)
348 pretty_name[pos++] = '*';
349 pretty_name[pos++] = '\'';
350 pretty_name[pos] = '\0';
352 else
353 sprintf (pretty_name, "'%s'", tname);
355 switch (TREE_CODE (type))
357 case BOOLEAN_TYPE:
358 case ENUMERAL_TYPE:
359 case INTEGER_TYPE:
360 tkind = 0x0000;
361 break;
362 case REAL_TYPE:
363 tkind = 0x0001;
364 break;
365 default:
366 tkind = 0xffff;
367 break;
369 tinfo = get_ubsan_type_info_for_type (type);
371 /* Create a new VAR_DECL of type descriptor. */
372 char tmp_name[32];
373 static unsigned int type_var_id_num;
374 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
375 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
376 dtype);
377 TREE_STATIC (decl) = 1;
378 TREE_PUBLIC (decl) = 0;
379 DECL_ARTIFICIAL (decl) = 1;
380 DECL_IGNORED_P (decl) = 1;
381 DECL_EXTERNAL (decl) = 0;
383 size_t len = strlen (pretty_name);
384 tree str = build_string (len + 1, pretty_name);
385 TREE_TYPE (str) = build_array_type (char_type_node,
386 build_index_type (size_int (len)));
387 TREE_READONLY (str) = 1;
388 TREE_STATIC (str) = 1;
389 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
390 build_int_cst (short_unsigned_type_node,
391 tkind), NULL_TREE,
392 build_int_cst (short_unsigned_type_node,
393 tinfo), NULL_TREE, str);
394 TREE_CONSTANT (ctor) = 1;
395 TREE_STATIC (ctor) = 1;
396 DECL_INITIAL (decl) = ctor;
397 varpool_finalize_decl (decl);
399 /* Save the VAR_DECL into the hash table. */
400 decl_for_type_insert (type, decl);
402 return build_fold_addr_expr (decl);
405 /* Create a structure for the ubsan library. NAME is a name of the new
406 structure. The arguments in ... are of __ubsan_type_descriptor type
407 and there are at most two of them. MISMATCH are data used by ubsan
408 pointer checking. */
410 tree
411 ubsan_create_data (const char *name, const location_t *ploc,
412 const struct ubsan_mismatch_data *mismatch, ...)
414 va_list args;
415 tree ret, t;
416 tree fields[5];
417 vec<tree, va_gc> *saved_args = NULL;
418 size_t i = 0;
419 location_t loc = UNKNOWN_LOCATION;
421 /* Firstly, create a pointer to type descriptor type. */
422 tree td_type = ubsan_type_descriptor_type ();
423 TYPE_READONLY (td_type) = 1;
424 td_type = build_pointer_type (td_type);
426 /* Create the structure type. */
427 ret = make_node (RECORD_TYPE);
428 if (ploc != NULL)
430 loc = LOCATION_LOCUS (*ploc);
431 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
432 ubsan_source_location_type ());
433 DECL_CONTEXT (fields[i]) = ret;
434 i++;
437 va_start (args, mismatch);
438 for (t = va_arg (args, tree); t != NULL_TREE;
439 i++, t = va_arg (args, tree))
441 gcc_checking_assert (i < 3);
442 /* Save the tree arguments for later use. */
443 vec_safe_push (saved_args, t);
444 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
445 td_type);
446 DECL_CONTEXT (fields[i]) = ret;
447 if (i)
448 DECL_CHAIN (fields[i - 1]) = fields[i];
450 va_end (args);
452 if (mismatch != NULL)
454 /* We have to add two more decls. */
455 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
456 pointer_sized_int_node);
457 DECL_CONTEXT (fields[i]) = ret;
458 DECL_CHAIN (fields[i - 1]) = fields[i];
459 i++;
461 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
462 unsigned_char_type_node);
463 DECL_CONTEXT (fields[i]) = ret;
464 DECL_CHAIN (fields[i - 1]) = fields[i];
465 i++;
468 TYPE_FIELDS (ret) = fields[0];
469 TYPE_NAME (ret) = get_identifier (name);
470 layout_type (ret);
472 /* Now, fill in the type. */
473 char tmp_name[32];
474 static unsigned int ubsan_var_id_num;
475 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
476 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
477 ret);
478 TREE_STATIC (var) = 1;
479 TREE_PUBLIC (var) = 0;
480 DECL_ARTIFICIAL (var) = 1;
481 DECL_IGNORED_P (var) = 1;
482 DECL_EXTERNAL (var) = 0;
484 vec<constructor_elt, va_gc> *v;
485 vec_alloc (v, i);
486 tree ctor = build_constructor (ret, v);
488 /* If desirable, set the __ubsan_source_location element. */
489 if (ploc != NULL)
490 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
492 size_t nelts = vec_safe_length (saved_args);
493 for (i = 0; i < nelts; i++)
495 t = (*saved_args)[i];
496 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
499 if (mismatch != NULL)
501 /* Append the pointer data. */
502 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->align);
503 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->ckind);
506 TREE_CONSTANT (ctor) = 1;
507 TREE_STATIC (ctor) = 1;
508 DECL_INITIAL (var) = ctor;
509 varpool_finalize_decl (var);
511 return var;
514 /* Instrument the __builtin_unreachable call. We just call the libubsan
515 routine instead. */
517 tree
518 ubsan_instrument_unreachable (location_t loc)
520 initialize_sanitizer_builtins ();
521 tree data = ubsan_create_data ("__ubsan_unreachable_data", &loc, NULL,
522 NULL_TREE);
523 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
524 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
527 /* Return true if T is a call to a libubsan routine. */
529 bool
530 is_ubsan_builtin_p (tree t)
532 return TREE_CODE (t) == FUNCTION_DECL
533 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
534 "__builtin___ubsan_", 18) == 0;
537 /* Expand UBSAN_NULL internal call. */
539 void
540 ubsan_expand_null_ifn (gimple_stmt_iterator gsi)
542 gimple stmt = gsi_stmt (gsi);
543 location_t loc = gimple_location (stmt);
544 gcc_assert (gimple_call_num_args (stmt) == 2);
545 tree ptr = gimple_call_arg (stmt, 0);
546 tree ckind = gimple_call_arg (stmt, 1);
548 basic_block cur_bb = gsi_bb (gsi);
550 /* Split the original block holding the pointer dereference. */
551 edge e = split_block (cur_bb, stmt);
553 /* Get a hold on the 'condition block', the 'then block' and the
554 'else block'. */
555 basic_block cond_bb = e->src;
556 basic_block fallthru_bb = e->dest;
557 basic_block then_bb = create_empty_bb (cond_bb);
558 if (current_loops)
560 add_bb_to_loop (then_bb, cond_bb->loop_father);
561 loops_state_set (LOOPS_NEED_FIXUP);
564 /* Make an edge coming from the 'cond block' into the 'then block';
565 this edge is unlikely taken, so set up the probability accordingly. */
566 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
567 e->probability = PROB_VERY_UNLIKELY;
569 /* Connect 'then block' with the 'else block'. This is needed
570 as the ubsan routines we call in the 'then block' are not noreturn.
571 The 'then block' only has one outcoming edge. */
572 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
574 /* Set up the fallthrough basic block. */
575 e = find_edge (cond_bb, fallthru_bb);
576 e->flags = EDGE_FALSE_VALUE;
577 e->count = cond_bb->count;
578 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
580 /* Update dominance info for the newly created then_bb; note that
581 fallthru_bb's dominance info has already been updated by
582 split_bock. */
583 if (dom_info_available_p (CDI_DOMINATORS))
584 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
586 /* Put the ubsan builtin call into the newly created BB. */
587 tree fn = builtin_decl_implicit (BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH);
588 const struct ubsan_mismatch_data m
589 = { build_zero_cst (pointer_sized_int_node), ckind };
590 tree data = ubsan_create_data ("__ubsan_null_data",
591 &loc, &m,
592 ubsan_type_descriptor (TREE_TYPE (ptr), true),
593 NULL_TREE);
594 data = build_fold_addr_expr_loc (loc, data);
595 gimple g = gimple_build_call (fn, 2, data,
596 build_zero_cst (pointer_sized_int_node));
597 gimple_set_location (g, loc);
598 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
599 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
601 /* Unlink the UBSAN_NULLs vops before replacing it. */
602 unlink_stmt_vdef (stmt);
604 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
605 NULL_TREE, NULL_TREE);
606 gimple_set_location (g, loc);
608 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
609 gsi_replace (&gsi, g, false);
612 /* Instrument a member call. We check whether 'this' is NULL. */
614 static void
615 instrument_member_call (gimple_stmt_iterator *iter)
617 tree this_parm = gimple_call_arg (gsi_stmt (*iter), 0);
618 tree kind = build_int_cst (unsigned_char_type_node, UBSAN_MEMBER_CALL);
619 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, this_parm, kind);
620 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
621 gsi_insert_before (iter, g, GSI_SAME_STMT);
624 /* Instrument a memory reference. T is the pointer, IS_LHS says
625 whether the pointer is on the left hand side of the assignment. */
627 static void
628 instrument_mem_ref (tree t, gimple_stmt_iterator *iter, bool is_lhs)
630 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
631 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
632 ikind = UBSAN_MEMBER_ACCESS;
633 tree kind = build_int_cst (unsigned_char_type_node, ikind);
634 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, t, kind);
635 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
636 gsi_insert_before (iter, g, GSI_SAME_STMT);
639 /* Perform the pointer instrumentation. */
641 static void
642 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
644 gimple stmt = gsi_stmt (gsi);
645 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
646 t = get_base_address (t);
647 const enum tree_code code = TREE_CODE (t);
648 if (code == MEM_REF
649 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
650 instrument_mem_ref (TREE_OPERAND (t, 0), &gsi, is_lhs);
651 else if (code == ADDR_EXPR
652 && POINTER_TYPE_P (TREE_TYPE (t))
653 && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == METHOD_TYPE)
654 instrument_member_call (&gsi);
657 /* Build an ubsan builtin call for the signed-integer-overflow
658 sanitization. CODE says what kind of builtin are we building,
659 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
660 are operands of the binary operation. */
662 tree
663 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
664 tree op0, tree op1)
666 tree data = ubsan_create_data ("__ubsan_overflow_data", &loc, NULL,
667 ubsan_type_descriptor (lhstype, false),
668 NULL_TREE);
669 enum built_in_function fn_code;
671 switch (code)
673 case PLUS_EXPR:
674 fn_code = BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW;
675 break;
676 case MINUS_EXPR:
677 fn_code = BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW;
678 break;
679 case MULT_EXPR:
680 fn_code = BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW;
681 break;
682 case NEGATE_EXPR:
683 fn_code = BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW;
684 break;
685 default:
686 gcc_unreachable ();
688 tree fn = builtin_decl_explicit (fn_code);
689 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
690 build_fold_addr_expr_loc (loc, data),
691 ubsan_encode_value (op0, true),
692 op1 ? ubsan_encode_value (op1, true)
693 : NULL_TREE);
696 /* Perform the signed integer instrumentation. GSI is the iterator
697 pointing at statement we are trying to instrument. */
699 static void
700 instrument_si_overflow (gimple_stmt_iterator gsi)
702 gimple stmt = gsi_stmt (gsi);
703 tree_code code = gimple_assign_rhs_code (stmt);
704 tree lhs = gimple_assign_lhs (stmt);
705 tree lhstype = TREE_TYPE (lhs);
706 tree a, b;
707 gimple g;
709 /* If this is not a signed operation, don't instrument anything here.
710 Also punt on bit-fields. */
711 if (!INTEGRAL_TYPE_P (lhstype)
712 || TYPE_OVERFLOW_WRAPS (lhstype)
713 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
714 return;
716 switch (code)
718 case MINUS_EXPR:
719 case PLUS_EXPR:
720 case MULT_EXPR:
721 /* Transform
722 i = u {+,-,*} 5;
723 into
724 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
725 a = gimple_assign_rhs1 (stmt);
726 b = gimple_assign_rhs2 (stmt);
727 g = gimple_build_call_internal (code == PLUS_EXPR
728 ? IFN_UBSAN_CHECK_ADD
729 : code == MINUS_EXPR
730 ? IFN_UBSAN_CHECK_SUB
731 : IFN_UBSAN_CHECK_MUL, 2, a, b);
732 gimple_call_set_lhs (g, lhs);
733 gsi_replace (&gsi, g, false);
734 break;
735 case NEGATE_EXPR:
736 /* Represent i = -u;
738 i = UBSAN_CHECK_SUB (0, u); */
739 a = build_int_cst (lhstype, 0);
740 b = gimple_assign_rhs1 (stmt);
741 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
742 gimple_call_set_lhs (g, lhs);
743 gsi_replace (&gsi, g, false);
744 break;
745 case ABS_EXPR:
746 /* Transform i = ABS_EXPR<u>;
747 into
748 _N = UBSAN_CHECK_SUB (0, u);
749 i = ABS_EXPR<_N>; */
750 a = build_int_cst (lhstype, 0);
751 b = gimple_assign_rhs1 (stmt);
752 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
753 a = make_ssa_name (lhstype, NULL);
754 gimple_call_set_lhs (g, a);
755 gimple_set_location (g, gimple_location (stmt));
756 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
757 gimple_assign_set_rhs1 (stmt, a);
758 update_stmt (stmt);
759 break;
760 default:
761 break;
765 /* Instrument loads from (non-bitfield) bool and C++ enum values
766 to check if the memory value is outside of the range of the valid
767 type values. */
769 static void
770 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
772 gimple stmt = gsi_stmt (*gsi);
773 tree rhs = gimple_assign_rhs1 (stmt);
774 tree type = TREE_TYPE (rhs);
775 tree minv = NULL_TREE, maxv = NULL_TREE;
777 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
779 minv = boolean_false_node;
780 maxv = boolean_true_node;
782 else if (TREE_CODE (type) == ENUMERAL_TYPE
783 && (flag_sanitize & SANITIZE_ENUM)
784 && TREE_TYPE (type) != NULL_TREE
785 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
786 && (TYPE_PRECISION (TREE_TYPE (type))
787 < GET_MODE_PRECISION (TYPE_MODE (type))))
789 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
790 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
792 else
793 return;
795 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
796 HOST_WIDE_INT bitsize, bitpos;
797 tree offset;
798 enum machine_mode mode;
799 int volatilep = 0, unsignedp = 0;
800 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
801 &unsignedp, &volatilep, false);
802 tree utype = build_nonstandard_integer_type (modebitsize, 1);
804 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
805 || (bitpos % modebitsize) != 0
806 || bitsize != modebitsize
807 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
808 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
809 return;
811 bool can_throw = stmt_could_throw_p (stmt);
812 location_t loc = gimple_location (stmt);
813 tree lhs = gimple_assign_lhs (stmt);
814 tree ptype = build_pointer_type (TREE_TYPE (rhs));
815 tree atype = reference_alias_ptr_type (rhs);
816 gimple g = gimple_build_assign (make_ssa_name (ptype, NULL),
817 build_fold_addr_expr (rhs));
818 gimple_set_location (g, loc);
819 gsi_insert_before (gsi, g, GSI_SAME_STMT);
820 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
821 build_int_cst (atype, 0));
822 tree urhs = make_ssa_name (utype, NULL);
823 if (can_throw)
825 gimple_assign_set_lhs (stmt, urhs);
826 g = gimple_build_assign_with_ops (NOP_EXPR, lhs, urhs, NULL_TREE);
827 gimple_set_location (g, loc);
828 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
829 gsi_insert_on_edge_immediate (e, g);
830 gimple_assign_set_rhs_from_tree (gsi, mem);
831 update_stmt (stmt);
832 *gsi = gsi_for_stmt (g);
833 g = stmt;
835 else
837 g = gimple_build_assign (urhs, mem);
838 gimple_set_location (g, loc);
839 gsi_insert_before (gsi, g, GSI_SAME_STMT);
841 minv = fold_convert (utype, minv);
842 maxv = fold_convert (utype, maxv);
843 if (!integer_zerop (minv))
845 g = gimple_build_assign_with_ops (MINUS_EXPR,
846 make_ssa_name (utype, NULL),
847 urhs, minv);
848 gimple_set_location (g, loc);
849 gsi_insert_before (gsi, g, GSI_SAME_STMT);
852 gimple_stmt_iterator gsi2 = *gsi;
853 basic_block then_bb, fallthru_bb;
854 *gsi = create_cond_insert_point (gsi, true, false, true,
855 &then_bb, &fallthru_bb);
856 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
857 int_const_binop (MINUS_EXPR, maxv, minv),
858 NULL_TREE, NULL_TREE);
859 gimple_set_location (g, loc);
860 gsi_insert_after (gsi, g, GSI_NEW_STMT);
862 if (!can_throw)
864 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
865 update_stmt (stmt);
868 tree data = ubsan_create_data ("__ubsan_invalid_value_data",
869 &loc, NULL,
870 ubsan_type_descriptor (type, false),
871 NULL_TREE);
872 data = build_fold_addr_expr_loc (loc, data);
873 tree fn = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE);
875 gsi2 = gsi_after_labels (then_bb);
876 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
877 true, NULL_TREE, true, GSI_SAME_STMT);
878 g = gimple_build_call (fn, 2, data, val);
879 gimple_set_location (g, loc);
880 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
883 /* Gate and execute functions for ubsan pass. */
885 static unsigned int
886 ubsan_pass (void)
888 basic_block bb;
889 gimple_stmt_iterator gsi;
891 initialize_sanitizer_builtins ();
893 FOR_EACH_BB_FN (bb, cfun)
895 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
897 gimple stmt = gsi_stmt (gsi);
898 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
900 gsi_next (&gsi);
901 continue;
904 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
905 && is_gimple_assign (stmt))
906 instrument_si_overflow (gsi);
908 if (flag_sanitize & SANITIZE_NULL)
910 if (gimple_store_p (stmt))
911 instrument_null (gsi, true);
912 if (gimple_assign_load_p (stmt))
913 instrument_null (gsi, false);
916 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
917 && gimple_assign_load_p (stmt))
918 instrument_bool_enum_load (&gsi);
920 gsi_next (&gsi);
923 return 0;
926 static bool
927 gate_ubsan (void)
929 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
930 | SANITIZE_BOOL | SANITIZE_ENUM);
933 namespace {
935 const pass_data pass_data_ubsan =
937 GIMPLE_PASS, /* type */
938 "ubsan", /* name */
939 OPTGROUP_NONE, /* optinfo_flags */
940 true, /* has_gate */
941 true, /* has_execute */
942 TV_TREE_UBSAN, /* tv_id */
943 ( PROP_cfg | PROP_ssa ), /* properties_required */
944 0, /* properties_provided */
945 0, /* properties_destroyed */
946 0, /* todo_flags_start */
947 TODO_update_ssa, /* todo_flags_finish */
950 class pass_ubsan : public gimple_opt_pass
952 public:
953 pass_ubsan (gcc::context *ctxt)
954 : gimple_opt_pass (pass_data_ubsan, ctxt)
957 /* opt_pass methods: */
958 bool gate () { return gate_ubsan (); }
959 unsigned int execute () { return ubsan_pass (); }
961 }; // class pass_ubsan
963 } // anon namespace
965 gimple_opt_pass *
966 make_pass_ubsan (gcc::context *ctxt)
968 return new pass_ubsan (ctxt);
971 #include "gt-ubsan.h"