Merge branches/gcc-4_9-branch rev 225109.
[official-gcc.git] / gcc-4_9-branch / gcc / ubsan.c
blob106cba41ead4bb3d5da59522608b8bac9a3137f0
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"
51 #include "tree-cfg.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 int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
273 gcc_assert (prec != -1);
274 return (prec << 1) | !TYPE_UNSIGNED (type);
277 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
278 descriptor. It first looks into the hash table; if not found,
279 create the VAR_DECL, put it into the hash table and return the
280 ADDR_EXPR of it. TYPE describes a particular type. WANT_POINTER_TYPE_P
281 means whether we are interested in the pointer type and not the pointer
282 itself. */
284 tree
285 ubsan_type_descriptor (tree type, bool want_pointer_type_p)
287 /* See through any typedefs. */
288 type = TYPE_MAIN_VARIANT (type);
290 tree decl = decl_for_type_lookup (type);
291 /* It is possible that some of the earlier created DECLs were found
292 unused, in that case they weren't emitted and varpool_get_node
293 returns NULL node on them. But now we really need them. Thus,
294 renew them here. */
295 if (decl != NULL_TREE && varpool_get_node (decl))
296 return build_fold_addr_expr (decl);
298 tree dtype = ubsan_type_descriptor_type ();
299 tree type2 = type;
300 const char *tname = NULL;
301 char *pretty_name;
302 unsigned char deref_depth = 0;
303 unsigned short tkind, tinfo;
305 /* Get the name of the type, or the name of the pointer type. */
306 if (want_pointer_type_p)
308 gcc_assert (POINTER_TYPE_P (type));
309 type2 = TREE_TYPE (type);
311 /* Remove any '*' operators from TYPE. */
312 while (POINTER_TYPE_P (type2))
313 deref_depth++, type2 = TREE_TYPE (type2);
315 if (TREE_CODE (type2) == METHOD_TYPE)
316 type2 = TYPE_METHOD_BASETYPE (type2);
319 /* If an array, get its type. */
320 type2 = strip_array_types (type2);
322 if (TYPE_NAME (type2) != NULL)
324 if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
325 tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
326 else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
327 tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
330 if (tname == NULL)
331 /* We weren't able to determine the type name. */
332 tname = "<unknown>";
334 /* Decorate the type name with '', '*', "struct", or "union". */
335 pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
336 if (want_pointer_type_p)
338 int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
339 TYPE_VOLATILE (type2) ? "volatile " : "",
340 TYPE_READONLY (type2) ? "const " : "",
341 TYPE_RESTRICT (type2) ? "restrict " : "",
342 TYPE_ATOMIC (type2) ? "_Atomic " : "",
343 TREE_CODE (type2) == RECORD_TYPE
344 ? "struct "
345 : TREE_CODE (type2) == UNION_TYPE
346 ? "union " : "", tname,
347 deref_depth == 0 ? "" : " ");
348 while (deref_depth-- > 0)
349 pretty_name[pos++] = '*';
350 pretty_name[pos++] = '\'';
351 pretty_name[pos] = '\0';
353 else
354 sprintf (pretty_name, "'%s'", tname);
356 switch (TREE_CODE (type))
358 case BOOLEAN_TYPE:
359 case ENUMERAL_TYPE:
360 case INTEGER_TYPE:
361 tkind = 0x0000;
362 break;
363 case REAL_TYPE:
364 tkind = 0x0001;
365 break;
366 default:
367 tkind = 0xffff;
368 break;
370 tinfo = get_ubsan_type_info_for_type (type);
372 /* Create a new VAR_DECL of type descriptor. */
373 char tmp_name[32];
374 static unsigned int type_var_id_num;
375 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
376 decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
377 dtype);
378 TREE_STATIC (decl) = 1;
379 TREE_PUBLIC (decl) = 0;
380 DECL_ARTIFICIAL (decl) = 1;
381 DECL_IGNORED_P (decl) = 1;
382 DECL_EXTERNAL (decl) = 0;
384 size_t len = strlen (pretty_name);
385 tree str = build_string (len + 1, pretty_name);
386 TREE_TYPE (str) = build_array_type (char_type_node,
387 build_index_type (size_int (len)));
388 TREE_READONLY (str) = 1;
389 TREE_STATIC (str) = 1;
390 tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
391 build_int_cst (short_unsigned_type_node,
392 tkind), NULL_TREE,
393 build_int_cst (short_unsigned_type_node,
394 tinfo), NULL_TREE, str);
395 TREE_CONSTANT (ctor) = 1;
396 TREE_STATIC (ctor) = 1;
397 DECL_INITIAL (decl) = ctor;
398 varpool_finalize_decl (decl);
400 /* Save the VAR_DECL into the hash table. */
401 decl_for_type_insert (type, decl);
403 return build_fold_addr_expr (decl);
406 /* Create a structure for the ubsan library. NAME is a name of the new
407 structure. The arguments in ... are of __ubsan_type_descriptor type
408 and there are at most two of them. MISMATCH are data used by ubsan
409 pointer checking. */
411 tree
412 ubsan_create_data (const char *name, const location_t *ploc,
413 const struct ubsan_mismatch_data *mismatch, ...)
415 va_list args;
416 tree ret, t;
417 tree fields[5];
418 vec<tree, va_gc> *saved_args = NULL;
419 size_t i = 0;
420 location_t loc = UNKNOWN_LOCATION;
422 /* Firstly, create a pointer to type descriptor type. */
423 tree td_type = ubsan_type_descriptor_type ();
424 TYPE_READONLY (td_type) = 1;
425 td_type = build_pointer_type (td_type);
427 /* Create the structure type. */
428 ret = make_node (RECORD_TYPE);
429 if (ploc != NULL)
431 loc = LOCATION_LOCUS (*ploc);
432 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
433 ubsan_source_location_type ());
434 DECL_CONTEXT (fields[i]) = ret;
435 i++;
438 va_start (args, mismatch);
439 for (t = va_arg (args, tree); t != NULL_TREE;
440 i++, t = va_arg (args, tree))
442 gcc_checking_assert (i < 3);
443 /* Save the tree arguments for later use. */
444 vec_safe_push (saved_args, t);
445 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
446 td_type);
447 DECL_CONTEXT (fields[i]) = ret;
448 if (i)
449 DECL_CHAIN (fields[i - 1]) = fields[i];
451 va_end (args);
453 if (mismatch != NULL)
455 /* We have to add two more decls. */
456 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
457 pointer_sized_int_node);
458 DECL_CONTEXT (fields[i]) = ret;
459 DECL_CHAIN (fields[i - 1]) = fields[i];
460 i++;
462 fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
463 unsigned_char_type_node);
464 DECL_CONTEXT (fields[i]) = ret;
465 DECL_CHAIN (fields[i - 1]) = fields[i];
466 i++;
469 TYPE_FIELDS (ret) = fields[0];
470 TYPE_NAME (ret) = get_identifier (name);
471 layout_type (ret);
473 /* Now, fill in the type. */
474 char tmp_name[32];
475 static unsigned int ubsan_var_id_num;
476 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
477 tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
478 ret);
479 TREE_STATIC (var) = 1;
480 TREE_PUBLIC (var) = 0;
481 DECL_ARTIFICIAL (var) = 1;
482 DECL_IGNORED_P (var) = 1;
483 DECL_EXTERNAL (var) = 0;
485 vec<constructor_elt, va_gc> *v;
486 vec_alloc (v, i);
487 tree ctor = build_constructor (ret, v);
489 /* If desirable, set the __ubsan_source_location element. */
490 if (ploc != NULL)
491 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
493 size_t nelts = vec_safe_length (saved_args);
494 for (i = 0; i < nelts; i++)
496 t = (*saved_args)[i];
497 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
500 if (mismatch != NULL)
502 /* Append the pointer data. */
503 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->align);
504 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, mismatch->ckind);
507 TREE_CONSTANT (ctor) = 1;
508 TREE_STATIC (ctor) = 1;
509 DECL_INITIAL (var) = ctor;
510 varpool_finalize_decl (var);
512 return var;
515 /* Instrument the __builtin_unreachable call. We just call the libubsan
516 routine instead. */
518 tree
519 ubsan_instrument_unreachable (location_t loc)
521 initialize_sanitizer_builtins ();
522 tree data = ubsan_create_data ("__ubsan_unreachable_data", &loc, NULL,
523 NULL_TREE);
524 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
525 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
528 /* Return true if T is a call to a libubsan routine. */
530 bool
531 is_ubsan_builtin_p (tree t)
533 return TREE_CODE (t) == FUNCTION_DECL
534 && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
535 "__builtin___ubsan_", 18) == 0;
538 /* Expand UBSAN_NULL internal call. */
540 void
541 ubsan_expand_null_ifn (gimple_stmt_iterator gsi)
543 gimple stmt = gsi_stmt (gsi);
544 location_t loc = gimple_location (stmt);
545 gcc_assert (gimple_call_num_args (stmt) == 2);
546 tree ptr = gimple_call_arg (stmt, 0);
547 tree ckind = gimple_call_arg (stmt, 1);
549 basic_block cur_bb = gsi_bb (gsi);
551 /* Split the original block holding the pointer dereference. */
552 edge e = split_block (cur_bb, stmt);
554 /* Get a hold on the 'condition block', the 'then block' and the
555 'else block'. */
556 basic_block cond_bb = e->src;
557 basic_block fallthru_bb = e->dest;
558 basic_block then_bb = create_empty_bb (cond_bb);
559 if (current_loops)
561 add_bb_to_loop (then_bb, cond_bb->loop_father);
562 loops_state_set (LOOPS_NEED_FIXUP);
565 /* Make an edge coming from the 'cond block' into the 'then block';
566 this edge is unlikely taken, so set up the probability accordingly. */
567 e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
568 e->probability = PROB_VERY_UNLIKELY;
570 /* Connect 'then block' with the 'else block'. This is needed
571 as the ubsan routines we call in the 'then block' are not noreturn.
572 The 'then block' only has one outcoming edge. */
573 make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
575 /* Set up the fallthrough basic block. */
576 e = find_edge (cond_bb, fallthru_bb);
577 e->flags = EDGE_FALSE_VALUE;
578 e->count = cond_bb->count;
579 e->probability = REG_BR_PROB_BASE - PROB_VERY_UNLIKELY;
581 /* Update dominance info for the newly created then_bb; note that
582 fallthru_bb's dominance info has already been updated by
583 split_bock. */
584 if (dom_info_available_p (CDI_DOMINATORS))
585 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
587 /* Put the ubsan builtin call into the newly created BB. */
588 tree fn = builtin_decl_implicit (BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH);
589 const struct ubsan_mismatch_data m
590 = { build_zero_cst (pointer_sized_int_node), ckind };
591 tree data = ubsan_create_data ("__ubsan_null_data",
592 &loc, &m,
593 ubsan_type_descriptor (TREE_TYPE (ptr), true),
594 NULL_TREE);
595 data = build_fold_addr_expr_loc (loc, data);
596 gimple g = gimple_build_call (fn, 2, data,
597 build_zero_cst (pointer_sized_int_node));
598 gimple_set_location (g, loc);
599 gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
600 gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
602 /* Unlink the UBSAN_NULLs vops before replacing it. */
603 unlink_stmt_vdef (stmt);
605 g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
606 NULL_TREE, NULL_TREE);
607 gimple_set_location (g, loc);
609 /* Replace the UBSAN_NULL with a GIMPLE_COND stmt. */
610 gsi_replace (&gsi, g, false);
613 /* Instrument a member call. We check whether 'this' is NULL. */
615 static void
616 instrument_member_call (gimple_stmt_iterator *iter)
618 tree this_parm = gimple_call_arg (gsi_stmt (*iter), 0);
619 tree kind = build_int_cst (unsigned_char_type_node, UBSAN_MEMBER_CALL);
620 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, this_parm, kind);
621 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
622 gsi_insert_before (iter, g, GSI_SAME_STMT);
625 /* Instrument a memory reference. T is the pointer, IS_LHS says
626 whether the pointer is on the left hand side of the assignment. */
628 static void
629 instrument_mem_ref (tree t, gimple_stmt_iterator *iter, bool is_lhs)
631 enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
632 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
633 ikind = UBSAN_MEMBER_ACCESS;
634 tree kind = build_int_cst (unsigned_char_type_node, ikind);
635 gimple g = gimple_build_call_internal (IFN_UBSAN_NULL, 2, t, kind);
636 gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
637 gsi_insert_before (iter, g, GSI_SAME_STMT);
640 /* Perform the pointer instrumentation. */
642 static void
643 instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
645 gimple stmt = gsi_stmt (gsi);
646 tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
647 t = get_base_address (t);
648 const enum tree_code code = TREE_CODE (t);
649 if (code == MEM_REF
650 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
651 instrument_mem_ref (TREE_OPERAND (t, 0), &gsi, is_lhs);
652 else if (code == ADDR_EXPR
653 && POINTER_TYPE_P (TREE_TYPE (t))
654 && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == METHOD_TYPE)
655 instrument_member_call (&gsi);
658 /* Build an ubsan builtin call for the signed-integer-overflow
659 sanitization. CODE says what kind of builtin are we building,
660 LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
661 are operands of the binary operation. */
663 tree
664 ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
665 tree op0, tree op1)
667 tree data = ubsan_create_data ("__ubsan_overflow_data", &loc, NULL,
668 ubsan_type_descriptor (lhstype, false),
669 NULL_TREE);
670 enum built_in_function fn_code;
672 switch (code)
674 case PLUS_EXPR:
675 fn_code = BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW;
676 break;
677 case MINUS_EXPR:
678 fn_code = BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW;
679 break;
680 case MULT_EXPR:
681 fn_code = BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW;
682 break;
683 case NEGATE_EXPR:
684 fn_code = BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW;
685 break;
686 default:
687 gcc_unreachable ();
689 tree fn = builtin_decl_explicit (fn_code);
690 return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
691 build_fold_addr_expr_loc (loc, data),
692 ubsan_encode_value (op0, true),
693 op1 ? ubsan_encode_value (op1, true)
694 : NULL_TREE);
697 /* Perform the signed integer instrumentation. GSI is the iterator
698 pointing at statement we are trying to instrument. */
700 static void
701 instrument_si_overflow (gimple_stmt_iterator gsi)
703 gimple stmt = gsi_stmt (gsi);
704 tree_code code = gimple_assign_rhs_code (stmt);
705 tree lhs = gimple_assign_lhs (stmt);
706 tree lhstype = TREE_TYPE (lhs);
707 tree a, b;
708 gimple g;
710 /* If this is not a signed operation, don't instrument anything here.
711 Also punt on bit-fields. */
712 if (!INTEGRAL_TYPE_P (lhstype)
713 || TYPE_OVERFLOW_WRAPS (lhstype)
714 || GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
715 return;
717 switch (code)
719 case MINUS_EXPR:
720 case PLUS_EXPR:
721 case MULT_EXPR:
722 /* Transform
723 i = u {+,-,*} 5;
724 into
725 i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
726 a = gimple_assign_rhs1 (stmt);
727 b = gimple_assign_rhs2 (stmt);
728 g = gimple_build_call_internal (code == PLUS_EXPR
729 ? IFN_UBSAN_CHECK_ADD
730 : code == MINUS_EXPR
731 ? IFN_UBSAN_CHECK_SUB
732 : IFN_UBSAN_CHECK_MUL, 2, a, b);
733 gimple_call_set_lhs (g, lhs);
734 gsi_replace (&gsi, g, false);
735 break;
736 case NEGATE_EXPR:
737 /* Represent i = -u;
739 i = UBSAN_CHECK_SUB (0, u); */
740 a = build_int_cst (lhstype, 0);
741 b = gimple_assign_rhs1 (stmt);
742 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
743 gimple_call_set_lhs (g, lhs);
744 gsi_replace (&gsi, g, false);
745 break;
746 case ABS_EXPR:
747 /* Transform i = ABS_EXPR<u>;
748 into
749 _N = UBSAN_CHECK_SUB (0, u);
750 i = ABS_EXPR<_N>; */
751 a = build_int_cst (lhstype, 0);
752 b = gimple_assign_rhs1 (stmt);
753 g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
754 a = make_ssa_name (lhstype, NULL);
755 gimple_call_set_lhs (g, a);
756 gimple_set_location (g, gimple_location (stmt));
757 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
758 gimple_assign_set_rhs1 (stmt, a);
759 update_stmt (stmt);
760 break;
761 default:
762 break;
766 /* Instrument loads from (non-bitfield) bool and C++ enum values
767 to check if the memory value is outside of the range of the valid
768 type values. */
770 static void
771 instrument_bool_enum_load (gimple_stmt_iterator *gsi)
773 gimple stmt = gsi_stmt (*gsi);
774 tree rhs = gimple_assign_rhs1 (stmt);
775 tree type = TREE_TYPE (rhs);
776 tree minv = NULL_TREE, maxv = NULL_TREE;
778 if (TREE_CODE (type) == BOOLEAN_TYPE && (flag_sanitize & SANITIZE_BOOL))
780 minv = boolean_false_node;
781 maxv = boolean_true_node;
783 else if (TREE_CODE (type) == ENUMERAL_TYPE
784 && (flag_sanitize & SANITIZE_ENUM)
785 && TREE_TYPE (type) != NULL_TREE
786 && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
787 && (TYPE_PRECISION (TREE_TYPE (type))
788 < GET_MODE_PRECISION (TYPE_MODE (type))))
790 minv = TYPE_MIN_VALUE (TREE_TYPE (type));
791 maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
793 else
794 return;
796 int modebitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
797 HOST_WIDE_INT bitsize, bitpos;
798 tree offset;
799 enum machine_mode mode;
800 int volatilep = 0, unsignedp = 0;
801 tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
802 &unsignedp, &volatilep, false);
803 tree utype = build_nonstandard_integer_type (modebitsize, 1);
805 if ((TREE_CODE (base) == VAR_DECL && DECL_HARD_REGISTER (base))
806 || (bitpos % modebitsize) != 0
807 || bitsize != modebitsize
808 || GET_MODE_BITSIZE (TYPE_MODE (utype)) != modebitsize
809 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
810 return;
812 bool ends_bb = stmt_ends_bb_p (stmt);
813 location_t loc = gimple_location (stmt);
814 tree lhs = gimple_assign_lhs (stmt);
815 tree ptype = build_pointer_type (TREE_TYPE (rhs));
816 tree atype = reference_alias_ptr_type (rhs);
817 gimple g = gimple_build_assign (make_ssa_name (ptype, NULL),
818 build_fold_addr_expr (rhs));
819 gimple_set_location (g, loc);
820 gsi_insert_before (gsi, g, GSI_SAME_STMT);
821 tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
822 build_int_cst (atype, 0));
823 tree urhs = make_ssa_name (utype, NULL);
824 if (ends_bb)
826 gimple_assign_set_lhs (stmt, urhs);
827 g = gimple_build_assign_with_ops (NOP_EXPR, lhs, urhs, NULL_TREE);
828 gimple_set_location (g, loc);
829 edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
830 gsi_insert_on_edge_immediate (e, g);
831 gimple_assign_set_rhs_from_tree (gsi, mem);
832 update_stmt (stmt);
833 *gsi = gsi_for_stmt (g);
834 g = stmt;
836 else
838 g = gimple_build_assign (urhs, mem);
839 gimple_set_location (g, loc);
840 gsi_insert_before (gsi, g, GSI_SAME_STMT);
842 minv = fold_convert (utype, minv);
843 maxv = fold_convert (utype, maxv);
844 if (!integer_zerop (minv))
846 g = gimple_build_assign_with_ops (MINUS_EXPR,
847 make_ssa_name (utype, NULL),
848 urhs, minv);
849 gimple_set_location (g, loc);
850 gsi_insert_before (gsi, g, GSI_SAME_STMT);
853 gimple_stmt_iterator gsi2 = *gsi;
854 basic_block then_bb, fallthru_bb;
855 *gsi = create_cond_insert_point (gsi, true, false, true,
856 &then_bb, &fallthru_bb);
857 g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
858 int_const_binop (MINUS_EXPR, maxv, minv),
859 NULL_TREE, NULL_TREE);
860 gimple_set_location (g, loc);
861 gsi_insert_after (gsi, g, GSI_NEW_STMT);
863 if (!ends_bb)
865 gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE);
866 update_stmt (stmt);
869 tree data = ubsan_create_data ("__ubsan_invalid_value_data",
870 &loc, NULL,
871 ubsan_type_descriptor (type, false),
872 NULL_TREE);
873 data = build_fold_addr_expr_loc (loc, data);
874 tree fn = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE);
876 gsi2 = gsi_after_labels (then_bb);
877 tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
878 true, NULL_TREE, true, GSI_SAME_STMT);
879 g = gimple_build_call (fn, 2, data, val);
880 gimple_set_location (g, loc);
881 gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
884 /* Gate and execute functions for ubsan pass. */
886 static unsigned int
887 ubsan_pass (void)
889 basic_block bb;
890 gimple_stmt_iterator gsi;
892 initialize_sanitizer_builtins ();
894 FOR_EACH_BB_FN (bb, cfun)
896 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
898 gimple stmt = gsi_stmt (gsi);
899 if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
901 gsi_next (&gsi);
902 continue;
905 if ((flag_sanitize & SANITIZE_SI_OVERFLOW)
906 && is_gimple_assign (stmt))
907 instrument_si_overflow (gsi);
909 if (flag_sanitize & SANITIZE_NULL)
911 if (gimple_store_p (stmt))
912 instrument_null (gsi, true);
913 if (gimple_assign_load_p (stmt))
914 instrument_null (gsi, false);
917 if (flag_sanitize & (SANITIZE_BOOL | SANITIZE_ENUM)
918 && gimple_assign_load_p (stmt))
919 instrument_bool_enum_load (&gsi);
921 gsi_next (&gsi);
924 return 0;
927 static bool
928 gate_ubsan (void)
930 return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
931 | SANITIZE_BOOL | SANITIZE_ENUM);
934 namespace {
936 const pass_data pass_data_ubsan =
938 GIMPLE_PASS, /* type */
939 "ubsan", /* name */
940 OPTGROUP_NONE, /* optinfo_flags */
941 true, /* has_gate */
942 true, /* has_execute */
943 TV_TREE_UBSAN, /* tv_id */
944 ( PROP_cfg | PROP_ssa ), /* properties_required */
945 0, /* properties_provided */
946 0, /* properties_destroyed */
947 0, /* todo_flags_start */
948 TODO_update_ssa, /* todo_flags_finish */
951 class pass_ubsan : public gimple_opt_pass
953 public:
954 pass_ubsan (gcc::context *ctxt)
955 : gimple_opt_pass (pass_data_ubsan, ctxt)
958 /* opt_pass methods: */
959 bool gate () { return gate_ubsan (); }
960 unsigned int execute () { return ubsan_pass (); }
962 }; // class pass_ubsan
964 } // anon namespace
966 gimple_opt_pass *
967 make_pass_ubsan (gcc::context *ctxt)
969 return new pass_ubsan (ctxt);
972 #include "gt-ubsan.h"