gcc/
[official-gcc.git] / gcc / c-family / c-ubsan.c
blobc195c7ff763bed43beb26037d96c23cf390f7639
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 "tree.h"
25 #include "alloc-pool.h"
26 #include "hash-map.h"
27 #include "is-a.h"
28 #include "plugin-api.h"
29 #include "vec.h"
30 #include "hashtab.h"
31 #include "hash-set.h"
32 #include "machmode.h"
33 #include "tm.h"
34 #include "hard-reg-set.h"
35 #include "input.h"
36 #include "function.h"
37 #include "ipa-ref.h"
38 #include "cgraph.h"
39 #include "output.h"
40 #include "toplev.h"
41 #include "ubsan.h"
42 #include "c-family/c-common.h"
43 #include "c-family/c-ubsan.h"
44 #include "asan.h"
45 #include "internal-fn.h"
46 #include "stor-layout.h"
47 #include "builtins.h"
49 /* Instrument division by zero and INT_MIN / -1. If not instrumenting,
50 return NULL_TREE. */
52 tree
53 ubsan_instrument_division (location_t loc, tree op0, tree op1)
55 tree t, tt;
56 tree type = TREE_TYPE (op0);
58 /* At this point both operands should have the same type,
59 because they are already converted to RESULT_TYPE.
60 Use TYPE_MAIN_VARIANT since typedefs can confuse us. */
61 gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
62 == TYPE_MAIN_VARIANT (TREE_TYPE (op1)));
64 if (TREE_CODE (type) == INTEGER_TYPE
65 && (flag_sanitize & SANITIZE_DIVIDE))
66 t = fold_build2 (EQ_EXPR, boolean_type_node,
67 op1, build_int_cst (type, 0));
68 else if (TREE_CODE (type) == REAL_TYPE
69 && (flag_sanitize & SANITIZE_FLOAT_DIVIDE))
70 t = fold_build2 (EQ_EXPR, boolean_type_node,
71 op1, build_real (type, dconst0));
72 else
73 return NULL_TREE;
75 /* We check INT_MIN / -1 only for signed types. */
76 if (TREE_CODE (type) == INTEGER_TYPE
77 && (flag_sanitize & SANITIZE_DIVIDE)
78 && !TYPE_UNSIGNED (type))
80 tree x;
81 tt = fold_build2 (EQ_EXPR, boolean_type_node, op1,
82 build_int_cst (type, -1));
83 x = fold_build2 (EQ_EXPR, boolean_type_node, op0,
84 TYPE_MIN_VALUE (type));
85 x = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, x, tt);
86 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, x);
89 /* If the condition was folded to 0, no need to instrument
90 this expression. */
91 if (integer_zerop (t))
92 return NULL_TREE;
94 /* In case we have a SAVE_EXPR in a conditional context, we need to
95 make sure it gets evaluated before the condition. If the OP0 is
96 an instrumented array reference, mark it as having side effects so
97 it's not folded away. */
98 if (flag_sanitize & SANITIZE_BOUNDS)
100 tree xop0 = op0;
101 while (CONVERT_EXPR_P (xop0))
102 xop0 = TREE_OPERAND (xop0, 0);
103 if (TREE_CODE (xop0) == ARRAY_REF)
105 TREE_SIDE_EFFECTS (xop0) = 1;
106 TREE_SIDE_EFFECTS (op0) = 1;
109 t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
110 if (flag_sanitize_undefined_trap_on_error)
111 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
112 else
114 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
115 ubsan_type_descriptor (type), NULL_TREE,
116 NULL_TREE);
117 data = build_fold_addr_expr_loc (loc, data);
118 enum built_in_function bcode
119 = (flag_sanitize_recover & SANITIZE_DIVIDE)
120 ? BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW
121 : BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW_ABORT;
122 tt = builtin_decl_explicit (bcode);
123 tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
124 ubsan_encode_value (op1));
126 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
128 return t;
131 /* Instrument left and right shifts. */
133 tree
134 ubsan_instrument_shift (location_t loc, enum tree_code code,
135 tree op0, tree op1)
137 tree t, tt = NULL_TREE;
138 tree type0 = TREE_TYPE (op0);
139 tree type1 = TREE_TYPE (op1);
140 tree op1_utype = unsigned_type_for (type1);
141 HOST_WIDE_INT op0_prec = TYPE_PRECISION (type0);
142 tree uprecm1 = build_int_cst (op1_utype, op0_prec - 1);
144 t = fold_convert_loc (loc, op1_utype, op1);
145 t = fold_build2 (GT_EXPR, boolean_type_node, t, uprecm1);
147 /* For signed x << y, in C99/C11, the following:
148 (unsigned) x >> (uprecm1 - y)
149 if non-zero, is undefined. */
150 if (code == LSHIFT_EXPR
151 && !TYPE_UNSIGNED (type0)
152 && flag_isoc99)
154 tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
155 fold_convert (op1_utype, op1));
156 tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
157 tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
158 tt = fold_build2 (NE_EXPR, boolean_type_node, tt,
159 build_int_cst (TREE_TYPE (tt), 0));
162 /* For signed x << y, in C++11 and later, the following:
163 x < 0 || ((unsigned) x >> (uprecm1 - y))
164 if > 1, is undefined. */
165 if (code == LSHIFT_EXPR
166 && !TYPE_UNSIGNED (TREE_TYPE (op0))
167 && (cxx_dialect >= cxx11))
169 tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
170 fold_convert (op1_utype, op1));
171 tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
172 tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
173 tt = fold_build2 (GT_EXPR, boolean_type_node, tt,
174 build_int_cst (TREE_TYPE (tt), 1));
175 x = fold_build2 (LT_EXPR, boolean_type_node, op0,
176 build_int_cst (type0, 0));
177 tt = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, x, tt);
180 /* If the condition was folded to 0, no need to instrument
181 this expression. */
182 if (integer_zerop (t) && (tt == NULL_TREE || integer_zerop (tt)))
183 return NULL_TREE;
185 /* In case we have a SAVE_EXPR in a conditional context, we need to
186 make sure it gets evaluated before the condition. If the OP0 is
187 an instrumented array reference, mark it as having side effects so
188 it's not folded away. */
189 if (flag_sanitize & SANITIZE_BOUNDS)
191 tree xop0 = op0;
192 while (CONVERT_EXPR_P (xop0))
193 xop0 = TREE_OPERAND (xop0, 0);
194 if (TREE_CODE (xop0) == ARRAY_REF)
196 TREE_SIDE_EFFECTS (xop0) = 1;
197 TREE_SIDE_EFFECTS (op0) = 1;
200 t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
201 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t,
202 tt ? tt : integer_zero_node);
204 if (flag_sanitize_undefined_trap_on_error)
205 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
206 else
208 tree data = ubsan_create_data ("__ubsan_shift_data", 1, &loc,
209 ubsan_type_descriptor (type0),
210 ubsan_type_descriptor (type1), NULL_TREE,
211 NULL_TREE);
212 data = build_fold_addr_expr_loc (loc, data);
214 enum built_in_function bcode
215 = (flag_sanitize_recover & SANITIZE_SHIFT)
216 ? BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS
217 : BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS_ABORT;
218 tt = builtin_decl_explicit (bcode);
219 tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
220 ubsan_encode_value (op1));
222 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
224 return t;
227 /* Instrument variable length array bound. */
229 tree
230 ubsan_instrument_vla (location_t loc, tree size)
232 tree type = TREE_TYPE (size);
233 tree t, tt;
235 t = fold_build2 (LE_EXPR, boolean_type_node, size, build_int_cst (type, 0));
236 if (flag_sanitize_undefined_trap_on_error)
237 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
238 else
240 tree data = ubsan_create_data ("__ubsan_vla_data", 1, &loc,
241 ubsan_type_descriptor (type), NULL_TREE,
242 NULL_TREE);
243 data = build_fold_addr_expr_loc (loc, data);
244 enum built_in_function bcode
245 = (flag_sanitize_recover & SANITIZE_VLA)
246 ? BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE
247 : BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE_ABORT;
248 tt = builtin_decl_explicit (bcode);
249 tt = build_call_expr_loc (loc, tt, 2, data, ubsan_encode_value (size));
251 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
253 return t;
256 /* Instrument missing return in C++ functions returning non-void. */
258 tree
259 ubsan_instrument_return (location_t loc)
261 if (flag_sanitize_undefined_trap_on_error)
262 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
263 /* It is possible that PCH zapped table with definitions of sanitizer
264 builtins. Reinitialize them if needed. */
265 initialize_sanitizer_builtins ();
267 tree data = ubsan_create_data ("__ubsan_missing_return_data", 1, &loc,
268 NULL_TREE, NULL_TREE);
269 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_MISSING_RETURN);
270 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
273 /* Instrument array bounds for ARRAY_REFs. We create special builtin,
274 that gets expanded in the sanopt pass, and make an array dimension
275 of it. ARRAY is the array, *INDEX is an index to the array.
276 Return NULL_TREE if no instrumentation is emitted.
277 IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
279 tree
280 ubsan_instrument_bounds (location_t loc, tree array, tree *index,
281 bool ignore_off_by_one)
283 tree type = TREE_TYPE (array);
284 tree domain = TYPE_DOMAIN (type);
286 if (domain == NULL_TREE || TYPE_MAX_VALUE (domain) == NULL_TREE)
287 return NULL_TREE;
289 tree bound = TYPE_MAX_VALUE (domain);
290 if (ignore_off_by_one)
291 bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound,
292 build_int_cst (TREE_TYPE (bound), 1));
294 /* Detect flexible array members and suchlike. */
295 tree base = get_base_address (array);
296 if (base && (TREE_CODE (base) == INDIRECT_REF
297 || TREE_CODE (base) == MEM_REF))
299 tree next = NULL_TREE;
300 tree cref = array;
302 /* Walk all structs/unions. */
303 while (TREE_CODE (cref) == COMPONENT_REF)
305 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (cref, 0))) == RECORD_TYPE)
306 for (next = DECL_CHAIN (TREE_OPERAND (cref, 1));
307 next && TREE_CODE (next) != FIELD_DECL;
308 next = DECL_CHAIN (next))
310 if (next)
311 /* Not a last element. Instrument it. */
312 break;
313 /* Ok, this is the last field of the structure/union. But the
314 aggregate containing the field must be the last field too,
315 recursively. */
316 cref = TREE_OPERAND (cref, 0);
318 if (!next)
319 /* Don't instrument this flexible array member-like array in non-strict
320 -fsanitize=bounds mode. */
321 return NULL_TREE;
324 /* Don't emit instrumentation in the most common cases. */
325 tree idx = NULL_TREE;
326 if (TREE_CODE (*index) == INTEGER_CST)
327 idx = *index;
328 else if (TREE_CODE (*index) == BIT_AND_EXPR
329 && TREE_CODE (TREE_OPERAND (*index, 1)) == INTEGER_CST)
330 idx = TREE_OPERAND (*index, 1);
331 if (idx
332 && TREE_CODE (bound) == INTEGER_CST
333 && tree_int_cst_sgn (idx) >= 0
334 && tree_int_cst_le (idx, bound))
335 return NULL_TREE;
337 *index = save_expr (*index);
338 /* Create a "(T *) 0" tree node to describe the array type. */
339 tree zero_with_type = build_int_cst (build_pointer_type (type), 0);
340 return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
341 void_type_node, 3, zero_with_type,
342 *index, bound);
345 /* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS. */
347 bool
348 ubsan_array_ref_instrumented_p (const_tree t)
350 if (TREE_CODE (t) != ARRAY_REF)
351 return false;
353 tree op1 = TREE_OPERAND (t, 1);
354 return TREE_CODE (op1) == COMPOUND_EXPR
355 && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
356 && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
357 && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
360 /* Instrument an ARRAY_REF, if it hasn't already been instrumented.
361 IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
363 void
364 ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
366 if (!ubsan_array_ref_instrumented_p (*expr_p)
367 && do_ubsan_in_current_function ())
369 tree op0 = TREE_OPERAND (*expr_p, 0);
370 tree op1 = TREE_OPERAND (*expr_p, 1);
371 tree e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0, &op1,
372 ignore_off_by_one);
373 if (e != NULL_TREE)
375 tree t = copy_node (*expr_p);
376 TREE_OPERAND (t, 1) = build2 (COMPOUND_EXPR, TREE_TYPE (op1),
377 e, op1);
378 *expr_p = t;
383 static tree
384 ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype,
385 enum ubsan_null_ckind ckind)
387 if (!do_ubsan_in_current_function ())
388 return NULL_TREE;
390 tree type = TREE_TYPE (ptype);
391 tree orig_op = op;
392 bool instrument = false;
393 unsigned int mina = 0;
395 if (flag_sanitize & SANITIZE_ALIGNMENT)
397 mina = min_align_of_type (type);
398 if (mina <= 1)
399 mina = 0;
401 while ((TREE_CODE (op) == NOP_EXPR
402 || TREE_CODE (op) == NON_LVALUE_EXPR)
403 && TREE_CODE (TREE_TYPE (op)) == POINTER_TYPE)
404 op = TREE_OPERAND (op, 0);
405 if (TREE_CODE (op) == NOP_EXPR
406 && TREE_CODE (TREE_TYPE (op)) == REFERENCE_TYPE)
408 if (mina && mina > min_align_of_type (TREE_TYPE (TREE_TYPE (op))))
409 instrument = true;
411 else
413 if ((flag_sanitize & SANITIZE_NULL) && TREE_CODE (op) == ADDR_EXPR)
415 bool strict_overflow_p = false;
416 /* tree_single_nonzero_warnv_p will not return true for non-weak
417 non-automatic decls with -fno-delete-null-pointer-checks,
418 which is disabled during -fsanitize=null. We don't want to
419 instrument those, just weak vars though. */
420 int save_flag_delete_null_pointer_checks
421 = flag_delete_null_pointer_checks;
422 flag_delete_null_pointer_checks = 1;
423 if (!tree_single_nonzero_warnv_p (op, &strict_overflow_p)
424 || strict_overflow_p)
425 instrument = true;
426 flag_delete_null_pointer_checks
427 = save_flag_delete_null_pointer_checks;
429 else if (flag_sanitize & SANITIZE_NULL)
430 instrument = true;
431 if (mina && mina > 1)
433 if (!POINTER_TYPE_P (TREE_TYPE (op))
434 || mina > get_pointer_alignment (op) / BITS_PER_UNIT)
435 instrument = true;
438 if (!instrument)
439 return NULL_TREE;
440 op = save_expr (orig_op);
441 gcc_assert (POINTER_TYPE_P (ptype));
442 if (TREE_CODE (ptype) == REFERENCE_TYPE)
443 ptype = build_pointer_type (TREE_TYPE (ptype));
444 tree kind = build_int_cst (ptype, ckind);
445 tree align = build_int_cst (pointer_sized_int_node, mina);
446 tree call
447 = build_call_expr_internal_loc (loc, IFN_UBSAN_NULL, void_type_node,
448 3, op, kind, align);
449 TREE_SIDE_EFFECTS (call) = 1;
450 return fold_build2 (COMPOUND_EXPR, TREE_TYPE (op), call, op);
453 /* Instrument a NOP_EXPR to REFERENCE_TYPE if needed. */
455 void
456 ubsan_maybe_instrument_reference (tree stmt)
458 tree op = TREE_OPERAND (stmt, 0);
459 op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
460 TREE_TYPE (stmt),
461 UBSAN_REF_BINDING);
462 if (op)
463 TREE_OPERAND (stmt, 0) = op;
466 /* Instrument a CALL_EXPR to a method if needed. */
468 void
469 ubsan_maybe_instrument_member_call (tree stmt, bool is_ctor)
471 if (call_expr_nargs (stmt) == 0)
472 return;
473 tree op = CALL_EXPR_ARG (stmt, 0);
474 if (op == error_mark_node
475 || !POINTER_TYPE_P (TREE_TYPE (op)))
476 return;
477 op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
478 TREE_TYPE (op),
479 is_ctor ? UBSAN_CTOR_CALL
480 : UBSAN_MEMBER_CALL);
481 if (op)
482 CALL_EXPR_ARG (stmt, 0) = op;