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