2015-02-28 Martin Liska <mliska@suse.cz>
[official-gcc.git] / gcc / c-family / c-ubsan.c
blob90d59c03a1609be63f601003153ccd63db61f612
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2015 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 "hash-set.h"
25 #include "machmode.h"
26 #include "vec.h"
27 #include "double-int.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "options.h"
32 #include "wide-int.h"
33 #include "inchash.h"
34 #include "tree.h"
35 #include "alloc-pool.h"
36 #include "hash-map.h"
37 #include "is-a.h"
38 #include "plugin-api.h"
39 #include "vec.h"
40 #include "hashtab.h"
41 #include "hash-set.h"
42 #include "machmode.h"
43 #include "tm.h"
44 #include "hard-reg-set.h"
45 #include "input.h"
46 #include "function.h"
47 #include "ipa-ref.h"
48 #include "cgraph.h"
49 #include "output.h"
50 #include "toplev.h"
51 #include "ubsan.h"
52 #include "c-family/c-common.h"
53 #include "c-family/c-ubsan.h"
54 #include "asan.h"
55 #include "internal-fn.h"
56 #include "stor-layout.h"
57 #include "builtins.h"
59 /* Instrument division by zero and INT_MIN / -1. If not instrumenting,
60 return NULL_TREE. */
62 tree
63 ubsan_instrument_division (location_t loc, tree op0, tree op1)
65 tree t, tt;
66 tree type = TREE_TYPE (op0);
68 /* At this point both operands should have the same type,
69 because they are already converted to RESULT_TYPE.
70 Use TYPE_MAIN_VARIANT since typedefs can confuse us. */
71 gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
72 == TYPE_MAIN_VARIANT (TREE_TYPE (op1)));
74 if (TREE_CODE (type) == INTEGER_TYPE
75 && (flag_sanitize & SANITIZE_DIVIDE))
76 t = fold_build2 (EQ_EXPR, boolean_type_node,
77 op1, build_int_cst (type, 0));
78 else if (TREE_CODE (type) == REAL_TYPE
79 && (flag_sanitize & SANITIZE_FLOAT_DIVIDE))
80 t = fold_build2 (EQ_EXPR, boolean_type_node,
81 op1, build_real (type, dconst0));
82 else
83 return NULL_TREE;
85 /* We check INT_MIN / -1 only for signed types. */
86 if (TREE_CODE (type) == INTEGER_TYPE
87 && (flag_sanitize & SANITIZE_DIVIDE)
88 && !TYPE_UNSIGNED (type))
90 tree x;
91 tt = fold_build2 (EQ_EXPR, boolean_type_node, op1,
92 build_int_cst (type, -1));
93 x = fold_build2 (EQ_EXPR, boolean_type_node, op0,
94 TYPE_MIN_VALUE (type));
95 x = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, x, tt);
96 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, x);
99 /* If the condition was folded to 0, no need to instrument
100 this expression. */
101 if (integer_zerop (t))
102 return NULL_TREE;
104 /* In case we have a SAVE_EXPR in a conditional context, we need to
105 make sure it gets evaluated before the condition. If the OP0 is
106 an instrumented array reference, mark it as having side effects so
107 it's not folded away. */
108 if (flag_sanitize & SANITIZE_BOUNDS)
110 tree xop0 = op0;
111 while (CONVERT_EXPR_P (xop0))
112 xop0 = TREE_OPERAND (xop0, 0);
113 if (TREE_CODE (xop0) == ARRAY_REF)
115 TREE_SIDE_EFFECTS (xop0) = 1;
116 TREE_SIDE_EFFECTS (op0) = 1;
119 t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
120 if (flag_sanitize_undefined_trap_on_error)
121 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
122 else
124 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
125 ubsan_type_descriptor (type), NULL_TREE,
126 NULL_TREE);
127 data = build_fold_addr_expr_loc (loc, data);
128 enum built_in_function bcode
129 = (flag_sanitize_recover & SANITIZE_DIVIDE)
130 ? BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW
131 : BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW_ABORT;
132 tt = builtin_decl_explicit (bcode);
133 tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
134 ubsan_encode_value (op1));
136 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
138 return t;
141 /* Instrument left and right shifts. */
143 tree
144 ubsan_instrument_shift (location_t loc, enum tree_code code,
145 tree op0, tree op1)
147 tree t, tt = NULL_TREE;
148 tree type0 = TREE_TYPE (op0);
149 tree type1 = TREE_TYPE (op1);
150 tree op1_utype = unsigned_type_for (type1);
151 HOST_WIDE_INT op0_prec = TYPE_PRECISION (type0);
152 tree uprecm1 = build_int_cst (op1_utype, op0_prec - 1);
154 t = fold_convert_loc (loc, op1_utype, op1);
155 t = fold_build2 (GT_EXPR, boolean_type_node, t, uprecm1);
157 /* For signed x << y, in C99/C11, the following:
158 (unsigned) x >> (uprecm1 - y)
159 if non-zero, is undefined. */
160 if (code == LSHIFT_EXPR
161 && !TYPE_UNSIGNED (type0)
162 && flag_isoc99)
164 tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
165 fold_convert (op1_utype, op1));
166 tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
167 tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
168 tt = fold_build2 (NE_EXPR, boolean_type_node, tt,
169 build_int_cst (TREE_TYPE (tt), 0));
172 /* For signed x << y, in C++11 and later, the following:
173 x < 0 || ((unsigned) x >> (uprecm1 - y))
174 if > 1, is undefined. */
175 if (code == LSHIFT_EXPR
176 && !TYPE_UNSIGNED (TREE_TYPE (op0))
177 && (cxx_dialect >= cxx11))
179 tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
180 fold_convert (op1_utype, op1));
181 tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
182 tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
183 tt = fold_build2 (GT_EXPR, boolean_type_node, tt,
184 build_int_cst (TREE_TYPE (tt), 1));
185 x = fold_build2 (LT_EXPR, boolean_type_node, op0,
186 build_int_cst (type0, 0));
187 tt = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, x, tt);
190 /* If the condition was folded to 0, no need to instrument
191 this expression. */
192 if (integer_zerop (t) && (tt == NULL_TREE || integer_zerop (tt)))
193 return NULL_TREE;
195 /* In case we have a SAVE_EXPR in a conditional context, we need to
196 make sure it gets evaluated before the condition. If the OP0 is
197 an instrumented array reference, mark it as having side effects so
198 it's not folded away. */
199 if (flag_sanitize & SANITIZE_BOUNDS)
201 tree xop0 = op0;
202 while (CONVERT_EXPR_P (xop0))
203 xop0 = TREE_OPERAND (xop0, 0);
204 if (TREE_CODE (xop0) == ARRAY_REF)
206 TREE_SIDE_EFFECTS (xop0) = 1;
207 TREE_SIDE_EFFECTS (op0) = 1;
210 t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
211 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t,
212 tt ? tt : integer_zero_node);
214 if (flag_sanitize_undefined_trap_on_error)
215 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
216 else
218 tree data = ubsan_create_data ("__ubsan_shift_data", 1, &loc,
219 ubsan_type_descriptor (type0),
220 ubsan_type_descriptor (type1), NULL_TREE,
221 NULL_TREE);
222 data = build_fold_addr_expr_loc (loc, data);
224 enum built_in_function bcode
225 = (flag_sanitize_recover & SANITIZE_SHIFT)
226 ? BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS
227 : BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS_ABORT;
228 tt = builtin_decl_explicit (bcode);
229 tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
230 ubsan_encode_value (op1));
232 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
234 return t;
237 /* Instrument variable length array bound. */
239 tree
240 ubsan_instrument_vla (location_t loc, tree size)
242 tree type = TREE_TYPE (size);
243 tree t, tt;
245 t = fold_build2 (LE_EXPR, boolean_type_node, size, build_int_cst (type, 0));
246 if (flag_sanitize_undefined_trap_on_error)
247 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
248 else
250 tree data = ubsan_create_data ("__ubsan_vla_data", 1, &loc,
251 ubsan_type_descriptor (type), NULL_TREE,
252 NULL_TREE);
253 data = build_fold_addr_expr_loc (loc, data);
254 enum built_in_function bcode
255 = (flag_sanitize_recover & SANITIZE_VLA)
256 ? BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE
257 : BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE_ABORT;
258 tt = builtin_decl_explicit (bcode);
259 tt = build_call_expr_loc (loc, tt, 2, data, ubsan_encode_value (size));
261 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
263 return t;
266 /* Instrument missing return in C++ functions returning non-void. */
268 tree
269 ubsan_instrument_return (location_t loc)
271 if (flag_sanitize_undefined_trap_on_error)
272 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
273 /* It is possible that PCH zapped table with definitions of sanitizer
274 builtins. Reinitialize them if needed. */
275 initialize_sanitizer_builtins ();
277 tree data = ubsan_create_data ("__ubsan_missing_return_data", 1, &loc,
278 NULL_TREE, NULL_TREE);
279 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_MISSING_RETURN);
280 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
283 /* Instrument array bounds for ARRAY_REFs. We create special builtin,
284 that gets expanded in the sanopt pass, and make an array dimension
285 of it. ARRAY is the array, *INDEX is an index to the array.
286 Return NULL_TREE if no instrumentation is emitted.
287 IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
289 tree
290 ubsan_instrument_bounds (location_t loc, tree array, tree *index,
291 bool ignore_off_by_one)
293 tree type = TREE_TYPE (array);
294 tree domain = TYPE_DOMAIN (type);
296 if (domain == NULL_TREE || TYPE_MAX_VALUE (domain) == NULL_TREE)
297 return NULL_TREE;
299 tree bound = TYPE_MAX_VALUE (domain);
300 if (ignore_off_by_one)
301 bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound,
302 build_int_cst (TREE_TYPE (bound), 1));
304 /* Detect flexible array members and suchlike. */
305 tree base = get_base_address (array);
306 if (base && (TREE_CODE (base) == INDIRECT_REF
307 || TREE_CODE (base) == MEM_REF))
309 tree next = NULL_TREE;
310 tree cref = array;
312 /* Walk all structs/unions. */
313 while (TREE_CODE (cref) == COMPONENT_REF)
315 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (cref, 0))) == RECORD_TYPE)
316 for (next = DECL_CHAIN (TREE_OPERAND (cref, 1));
317 next && TREE_CODE (next) != FIELD_DECL;
318 next = DECL_CHAIN (next))
320 if (next)
321 /* Not a last element. Instrument it. */
322 break;
323 /* Ok, this is the last field of the structure/union. But the
324 aggregate containing the field must be the last field too,
325 recursively. */
326 cref = TREE_OPERAND (cref, 0);
328 if (!next)
329 /* Don't instrument this flexible array member-like array in non-strict
330 -fsanitize=bounds mode. */
331 return NULL_TREE;
334 /* Don't emit instrumentation in the most common cases. */
335 tree idx = NULL_TREE;
336 if (TREE_CODE (*index) == INTEGER_CST)
337 idx = *index;
338 else if (TREE_CODE (*index) == BIT_AND_EXPR
339 && TREE_CODE (TREE_OPERAND (*index, 1)) == INTEGER_CST)
340 idx = TREE_OPERAND (*index, 1);
341 if (idx
342 && TREE_CODE (bound) == INTEGER_CST
343 && tree_int_cst_sgn (idx) >= 0
344 && tree_int_cst_le (idx, bound))
345 return NULL_TREE;
347 *index = save_expr (*index);
348 /* Create a "(T *) 0" tree node to describe the array type. */
349 tree zero_with_type = build_int_cst (build_pointer_type (type), 0);
350 return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
351 void_type_node, 3, zero_with_type,
352 *index, bound);
355 /* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS. */
357 bool
358 ubsan_array_ref_instrumented_p (const_tree t)
360 if (TREE_CODE (t) != ARRAY_REF)
361 return false;
363 tree op1 = TREE_OPERAND (t, 1);
364 return TREE_CODE (op1) == COMPOUND_EXPR
365 && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
366 && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
367 && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
370 /* Instrument an ARRAY_REF, if it hasn't already been instrumented.
371 IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
373 void
374 ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
376 if (!ubsan_array_ref_instrumented_p (*expr_p)
377 && do_ubsan_in_current_function ())
379 tree op0 = TREE_OPERAND (*expr_p, 0);
380 tree op1 = TREE_OPERAND (*expr_p, 1);
381 tree e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0, &op1,
382 ignore_off_by_one);
383 if (e != NULL_TREE)
385 tree t = copy_node (*expr_p);
386 TREE_OPERAND (t, 1) = build2 (COMPOUND_EXPR, TREE_TYPE (op1),
387 e, op1);
388 *expr_p = t;
393 static tree
394 ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype,
395 enum ubsan_null_ckind ckind)
397 if (!do_ubsan_in_current_function ())
398 return NULL_TREE;
400 tree type = TREE_TYPE (ptype);
401 tree orig_op = op;
402 bool instrument = false;
403 unsigned int mina = 0;
405 if (flag_sanitize & SANITIZE_ALIGNMENT)
407 mina = min_align_of_type (type);
408 if (mina <= 1)
409 mina = 0;
411 while ((TREE_CODE (op) == NOP_EXPR
412 || TREE_CODE (op) == NON_LVALUE_EXPR)
413 && TREE_CODE (TREE_TYPE (op)) == POINTER_TYPE)
414 op = TREE_OPERAND (op, 0);
415 if (TREE_CODE (op) == NOP_EXPR
416 && TREE_CODE (TREE_TYPE (op)) == REFERENCE_TYPE)
418 if (mina && mina > min_align_of_type (TREE_TYPE (TREE_TYPE (op))))
419 instrument = true;
421 else
423 if ((flag_sanitize & SANITIZE_NULL) && TREE_CODE (op) == ADDR_EXPR)
425 bool strict_overflow_p = false;
426 /* tree_single_nonzero_warnv_p will not return true for non-weak
427 non-automatic decls with -fno-delete-null-pointer-checks,
428 which is disabled during -fsanitize=null. We don't want to
429 instrument those, just weak vars though. */
430 int save_flag_delete_null_pointer_checks
431 = flag_delete_null_pointer_checks;
432 flag_delete_null_pointer_checks = 1;
433 if (!tree_single_nonzero_warnv_p (op, &strict_overflow_p)
434 || strict_overflow_p)
435 instrument = true;
436 flag_delete_null_pointer_checks
437 = save_flag_delete_null_pointer_checks;
439 else if (flag_sanitize & SANITIZE_NULL)
440 instrument = true;
441 if (mina && mina > 1)
443 if (!POINTER_TYPE_P (TREE_TYPE (op))
444 || mina > get_pointer_alignment (op) / BITS_PER_UNIT)
445 instrument = true;
448 if (!instrument)
449 return NULL_TREE;
450 op = save_expr (orig_op);
451 gcc_assert (POINTER_TYPE_P (ptype));
452 if (TREE_CODE (ptype) == REFERENCE_TYPE)
453 ptype = build_pointer_type (TREE_TYPE (ptype));
454 tree kind = build_int_cst (ptype, ckind);
455 tree align = build_int_cst (pointer_sized_int_node, mina);
456 tree call
457 = build_call_expr_internal_loc (loc, IFN_UBSAN_NULL, void_type_node,
458 3, op, kind, align);
459 TREE_SIDE_EFFECTS (call) = 1;
460 return fold_build2 (COMPOUND_EXPR, TREE_TYPE (op), call, op);
463 /* Instrument a NOP_EXPR to REFERENCE_TYPE if needed. */
465 void
466 ubsan_maybe_instrument_reference (tree stmt)
468 tree op = TREE_OPERAND (stmt, 0);
469 op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
470 TREE_TYPE (stmt),
471 UBSAN_REF_BINDING);
472 if (op)
473 TREE_OPERAND (stmt, 0) = op;
476 /* Instrument a CALL_EXPR to a method if needed. */
478 void
479 ubsan_maybe_instrument_member_call (tree stmt, bool is_ctor)
481 if (call_expr_nargs (stmt) == 0)
482 return;
483 tree op = CALL_EXPR_ARG (stmt, 0);
484 if (op == error_mark_node
485 || !POINTER_TYPE_P (TREE_TYPE (op)))
486 return;
487 op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
488 TREE_TYPE (op),
489 is_ctor ? UBSAN_CTOR_CALL
490 : UBSAN_MEMBER_CALL);
491 if (op)
492 CALL_EXPR_ARG (stmt, 0) = op;