gcc/
[official-gcc.git] / gcc / c-family / c-ubsan.c
blob6cf2a74d65433f072dbf473fbb8995e0111ef5ba
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 "alias.h"
25 #include "symtab.h"
26 #include "options.h"
27 #include "tree.h"
28 #include "alloc-pool.h"
29 #include "plugin-api.h"
30 #include "tm.h"
31 #include "hard-reg-set.h"
32 #include "function.h"
33 #include "ipa-ref.h"
34 #include "cgraph.h"
35 #include "output.h"
36 #include "toplev.h"
37 #include "ubsan.h"
38 #include "c-family/c-common.h"
39 #include "c-family/c-ubsan.h"
40 #include "asan.h"
41 #include "internal-fn.h"
42 #include "stor-layout.h"
43 #include "builtins.h"
45 /* Instrument division by zero and INT_MIN / -1. If not instrumenting,
46 return NULL_TREE. */
48 tree
49 ubsan_instrument_division (location_t loc, tree op0, tree op1)
51 tree t, tt;
52 tree type = TREE_TYPE (op0);
54 /* At this point both operands should have the same type,
55 because they are already converted to RESULT_TYPE.
56 Use TYPE_MAIN_VARIANT since typedefs can confuse us. */
57 gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
58 == TYPE_MAIN_VARIANT (TREE_TYPE (op1)));
60 if (TREE_CODE (type) == INTEGER_TYPE
61 && (flag_sanitize & SANITIZE_DIVIDE))
62 t = fold_build2 (EQ_EXPR, boolean_type_node,
63 op1, build_int_cst (type, 0));
64 else if (TREE_CODE (type) == REAL_TYPE
65 && (flag_sanitize & SANITIZE_FLOAT_DIVIDE))
66 t = fold_build2 (EQ_EXPR, boolean_type_node,
67 op1, build_real (type, dconst0));
68 else
69 return NULL_TREE;
71 /* We check INT_MIN / -1 only for signed types. */
72 if (TREE_CODE (type) == INTEGER_TYPE
73 && (flag_sanitize & SANITIZE_DIVIDE)
74 && !TYPE_UNSIGNED (type))
76 tree x;
77 tt = fold_build2 (EQ_EXPR, boolean_type_node, op1,
78 build_int_cst (type, -1));
79 x = fold_build2 (EQ_EXPR, boolean_type_node, op0,
80 TYPE_MIN_VALUE (type));
81 x = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, x, tt);
82 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, x);
85 /* If the condition was folded to 0, no need to instrument
86 this expression. */
87 if (integer_zerop (t))
88 return NULL_TREE;
90 /* In case we have a SAVE_EXPR in a conditional context, we need to
91 make sure it gets evaluated before the condition. If the OP0 is
92 an instrumented array reference, mark it as having side effects so
93 it's not folded away. */
94 if (flag_sanitize & SANITIZE_BOUNDS)
96 tree xop0 = op0;
97 while (CONVERT_EXPR_P (xop0))
98 xop0 = TREE_OPERAND (xop0, 0);
99 if (TREE_CODE (xop0) == ARRAY_REF)
101 TREE_SIDE_EFFECTS (xop0) = 1;
102 TREE_SIDE_EFFECTS (op0) = 1;
105 t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
106 if (flag_sanitize_undefined_trap_on_error)
107 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
108 else
110 tree data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
111 ubsan_type_descriptor (type), NULL_TREE,
112 NULL_TREE);
113 data = build_fold_addr_expr_loc (loc, data);
114 enum built_in_function bcode
115 = (flag_sanitize_recover & SANITIZE_DIVIDE)
116 ? BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW
117 : BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW_ABORT;
118 tt = builtin_decl_explicit (bcode);
119 tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
120 ubsan_encode_value (op1));
122 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
124 return t;
127 /* Instrument left and right shifts. */
129 tree
130 ubsan_instrument_shift (location_t loc, enum tree_code code,
131 tree op0, tree op1)
133 tree t, tt = NULL_TREE;
134 tree type0 = TREE_TYPE (op0);
135 tree type1 = TREE_TYPE (op1);
136 tree op1_utype = unsigned_type_for (type1);
137 HOST_WIDE_INT op0_prec = TYPE_PRECISION (type0);
138 tree uprecm1 = build_int_cst (op1_utype, op0_prec - 1);
140 t = fold_convert_loc (loc, op1_utype, op1);
141 t = fold_build2 (GT_EXPR, boolean_type_node, t, uprecm1);
143 /* For signed x << y, in C99/C11, the following:
144 (unsigned) x >> (uprecm1 - y)
145 if non-zero, is undefined. */
146 if (code == LSHIFT_EXPR
147 && !TYPE_UNSIGNED (type0)
148 && flag_isoc99)
150 tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
151 fold_convert (op1_utype, op1));
152 tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
153 tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
154 tt = fold_build2 (NE_EXPR, boolean_type_node, tt,
155 build_int_cst (TREE_TYPE (tt), 0));
158 /* For signed x << y, in C++11 and later, the following:
159 x < 0 || ((unsigned) x >> (uprecm1 - y))
160 if > 1, is undefined. */
161 if (code == LSHIFT_EXPR
162 && !TYPE_UNSIGNED (type0)
163 && (cxx_dialect >= cxx11))
165 tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
166 fold_convert (op1_utype, op1));
167 tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
168 tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
169 tt = fold_build2 (GT_EXPR, boolean_type_node, tt,
170 build_int_cst (TREE_TYPE (tt), 1));
171 x = fold_build2 (LT_EXPR, boolean_type_node, op0,
172 build_int_cst (type0, 0));
173 tt = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, x, tt);
176 /* If the condition was folded to 0, no need to instrument
177 this expression. */
178 if (integer_zerop (t) && (tt == NULL_TREE || integer_zerop (tt)))
179 return NULL_TREE;
181 /* In case we have a SAVE_EXPR in a conditional context, we need to
182 make sure it gets evaluated before the condition. If the OP0 is
183 an instrumented array reference, mark it as having side effects so
184 it's not folded away. */
185 if (flag_sanitize & SANITIZE_BOUNDS)
187 tree xop0 = op0;
188 while (CONVERT_EXPR_P (xop0))
189 xop0 = TREE_OPERAND (xop0, 0);
190 if (TREE_CODE (xop0) == ARRAY_REF)
192 TREE_SIDE_EFFECTS (xop0) = 1;
193 TREE_SIDE_EFFECTS (op0) = 1;
196 t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
197 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t,
198 tt ? tt : integer_zero_node);
200 if (flag_sanitize_undefined_trap_on_error)
201 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
202 else
204 tree data = ubsan_create_data ("__ubsan_shift_data", 1, &loc,
205 ubsan_type_descriptor (type0),
206 ubsan_type_descriptor (type1), NULL_TREE,
207 NULL_TREE);
208 data = build_fold_addr_expr_loc (loc, data);
210 enum built_in_function bcode
211 = (flag_sanitize_recover & SANITIZE_SHIFT)
212 ? BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS
213 : BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS_ABORT;
214 tt = builtin_decl_explicit (bcode);
215 tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
216 ubsan_encode_value (op1));
218 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
220 return t;
223 /* Instrument variable length array bound. */
225 tree
226 ubsan_instrument_vla (location_t loc, tree size)
228 tree type = TREE_TYPE (size);
229 tree t, tt;
231 t = fold_build2 (LE_EXPR, boolean_type_node, size, build_int_cst (type, 0));
232 if (flag_sanitize_undefined_trap_on_error)
233 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
234 else
236 tree data = ubsan_create_data ("__ubsan_vla_data", 1, &loc,
237 ubsan_type_descriptor (type), NULL_TREE,
238 NULL_TREE);
239 data = build_fold_addr_expr_loc (loc, data);
240 enum built_in_function bcode
241 = (flag_sanitize_recover & SANITIZE_VLA)
242 ? BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE
243 : BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE_ABORT;
244 tt = builtin_decl_explicit (bcode);
245 tt = build_call_expr_loc (loc, tt, 2, data, ubsan_encode_value (size));
247 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
249 return t;
252 /* Instrument missing return in C++ functions returning non-void. */
254 tree
255 ubsan_instrument_return (location_t loc)
257 if (flag_sanitize_undefined_trap_on_error)
258 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
259 /* It is possible that PCH zapped table with definitions of sanitizer
260 builtins. Reinitialize them if needed. */
261 initialize_sanitizer_builtins ();
263 tree data = ubsan_create_data ("__ubsan_missing_return_data", 1, &loc,
264 NULL_TREE, NULL_TREE);
265 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_MISSING_RETURN);
266 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
269 /* Instrument array bounds for ARRAY_REFs. We create special builtin,
270 that gets expanded in the sanopt pass, and make an array dimension
271 of it. ARRAY is the array, *INDEX is an index to the array.
272 Return NULL_TREE if no instrumentation is emitted.
273 IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
275 tree
276 ubsan_instrument_bounds (location_t loc, tree array, tree *index,
277 bool ignore_off_by_one)
279 tree type = TREE_TYPE (array);
280 tree domain = TYPE_DOMAIN (type);
282 if (domain == NULL_TREE || TYPE_MAX_VALUE (domain) == NULL_TREE)
283 return NULL_TREE;
285 tree bound = TYPE_MAX_VALUE (domain);
286 if (ignore_off_by_one)
287 bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound,
288 build_int_cst (TREE_TYPE (bound), 1));
290 /* Detect flexible array members and suchlike, unless
291 -fsanitize=bounds-strict. */
292 tree base = get_base_address (array);
293 if ((flag_sanitize & SANITIZE_BOUNDS_STRICT) == 0
294 && TREE_CODE (array) == COMPONENT_REF
295 && base && (TREE_CODE (base) == INDIRECT_REF
296 || TREE_CODE (base) == MEM_REF))
298 tree next = NULL_TREE;
299 tree cref = array;
301 /* Walk all structs/unions. */
302 while (TREE_CODE (cref) == COMPONENT_REF)
304 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (cref, 0))) == RECORD_TYPE)
305 for (next = DECL_CHAIN (TREE_OPERAND (cref, 1));
306 next && TREE_CODE (next) != FIELD_DECL;
307 next = DECL_CHAIN (next))
309 if (next)
310 /* Not a last element. Instrument it. */
311 break;
312 /* Ok, this is the last field of the structure/union. But the
313 aggregate containing the field must be the last field too,
314 recursively. */
315 cref = TREE_OPERAND (cref, 0);
317 if (!next)
318 /* Don't instrument this flexible array member-like array in non-strict
319 -fsanitize=bounds mode. */
320 return NULL_TREE;
323 /* Don't emit instrumentation in the most common cases. */
324 tree idx = NULL_TREE;
325 if (TREE_CODE (*index) == INTEGER_CST)
326 idx = *index;
327 else if (TREE_CODE (*index) == BIT_AND_EXPR
328 && TREE_CODE (TREE_OPERAND (*index, 1)) == INTEGER_CST)
329 idx = TREE_OPERAND (*index, 1);
330 if (idx
331 && TREE_CODE (bound) == INTEGER_CST
332 && tree_int_cst_sgn (idx) >= 0
333 && tree_int_cst_le (idx, bound))
334 return NULL_TREE;
336 *index = save_expr (*index);
337 /* Create a "(T *) 0" tree node to describe the array type. */
338 tree zero_with_type = build_int_cst (build_pointer_type (type), 0);
339 return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
340 void_type_node, 3, zero_with_type,
341 *index, bound);
344 /* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS. */
346 bool
347 ubsan_array_ref_instrumented_p (const_tree t)
349 if (TREE_CODE (t) != ARRAY_REF)
350 return false;
352 tree op1 = TREE_OPERAND (t, 1);
353 return TREE_CODE (op1) == COMPOUND_EXPR
354 && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
355 && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
356 && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
359 /* Instrument an ARRAY_REF, if it hasn't already been instrumented.
360 IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
362 void
363 ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
365 if (!ubsan_array_ref_instrumented_p (*expr_p)
366 && do_ubsan_in_current_function ())
368 tree op0 = TREE_OPERAND (*expr_p, 0);
369 tree op1 = TREE_OPERAND (*expr_p, 1);
370 tree e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0, &op1,
371 ignore_off_by_one);
372 if (e != NULL_TREE)
374 tree t = copy_node (*expr_p);
375 TREE_OPERAND (t, 1) = build2 (COMPOUND_EXPR, TREE_TYPE (op1),
376 e, op1);
377 *expr_p = t;
382 static tree
383 ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype,
384 enum ubsan_null_ckind ckind)
386 if (!do_ubsan_in_current_function ())
387 return NULL_TREE;
389 tree type = TREE_TYPE (ptype);
390 tree orig_op = op;
391 bool instrument = false;
392 unsigned int mina = 0;
394 if (flag_sanitize & SANITIZE_ALIGNMENT)
396 mina = min_align_of_type (type);
397 if (mina <= 1)
398 mina = 0;
400 while ((TREE_CODE (op) == NOP_EXPR
401 || TREE_CODE (op) == NON_LVALUE_EXPR)
402 && TREE_CODE (TREE_TYPE (op)) == POINTER_TYPE)
403 op = TREE_OPERAND (op, 0);
404 if (TREE_CODE (op) == NOP_EXPR
405 && TREE_CODE (TREE_TYPE (op)) == REFERENCE_TYPE)
407 if (mina && mina > min_align_of_type (TREE_TYPE (TREE_TYPE (op))))
408 instrument = true;
410 else
412 if ((flag_sanitize & SANITIZE_NULL) && TREE_CODE (op) == ADDR_EXPR)
414 bool strict_overflow_p = false;
415 /* tree_single_nonzero_warnv_p will not return true for non-weak
416 non-automatic decls with -fno-delete-null-pointer-checks,
417 which is disabled during -fsanitize=null. We don't want to
418 instrument those, just weak vars though. */
419 int save_flag_delete_null_pointer_checks
420 = flag_delete_null_pointer_checks;
421 flag_delete_null_pointer_checks = 1;
422 if (!tree_single_nonzero_warnv_p (op, &strict_overflow_p)
423 || strict_overflow_p)
424 instrument = true;
425 flag_delete_null_pointer_checks
426 = save_flag_delete_null_pointer_checks;
428 else if (flag_sanitize & SANITIZE_NULL)
429 instrument = true;
430 if (mina && mina > 1)
432 if (!POINTER_TYPE_P (TREE_TYPE (op))
433 || mina > get_pointer_alignment (op) / BITS_PER_UNIT)
434 instrument = true;
437 if (!instrument)
438 return NULL_TREE;
439 op = save_expr (orig_op);
440 gcc_assert (POINTER_TYPE_P (ptype));
441 if (TREE_CODE (ptype) == REFERENCE_TYPE)
442 ptype = build_pointer_type (TREE_TYPE (ptype));
443 tree kind = build_int_cst (ptype, ckind);
444 tree align = build_int_cst (pointer_sized_int_node, mina);
445 tree call
446 = build_call_expr_internal_loc (loc, IFN_UBSAN_NULL, void_type_node,
447 3, op, kind, align);
448 TREE_SIDE_EFFECTS (call) = 1;
449 return fold_build2 (COMPOUND_EXPR, TREE_TYPE (op), call, op);
452 /* Instrument a NOP_EXPR to REFERENCE_TYPE if needed. */
454 void
455 ubsan_maybe_instrument_reference (tree stmt)
457 tree op = TREE_OPERAND (stmt, 0);
458 op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
459 TREE_TYPE (stmt),
460 UBSAN_REF_BINDING);
461 if (op)
462 TREE_OPERAND (stmt, 0) = op;
465 /* Instrument a CALL_EXPR to a method if needed. */
467 void
468 ubsan_maybe_instrument_member_call (tree stmt, bool is_ctor)
470 if (call_expr_nargs (stmt) == 0)
471 return;
472 tree op = CALL_EXPR_ARG (stmt, 0);
473 if (op == error_mark_node
474 || !POINTER_TYPE_P (TREE_TYPE (op)))
475 return;
476 op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
477 TREE_TYPE (op),
478 is_ctor ? UBSAN_CTOR_CALL
479 : UBSAN_MEMBER_CALL);
480 if (op)
481 CALL_EXPR_ARG (stmt, 0) = op;