PR sanitizer/65280
[official-gcc.git] / gcc / c-family / c-ubsan.c
bloba14426f962467aa5148be765cfe89383cfbe8ef5
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 (TREE_CODE (array) == COMPONENT_REF
307 && base && (TREE_CODE (base) == INDIRECT_REF
308 || TREE_CODE (base) == MEM_REF))
310 tree next = NULL_TREE;
311 tree cref = array;
313 /* Walk all structs/unions. */
314 while (TREE_CODE (cref) == COMPONENT_REF)
316 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (cref, 0))) == RECORD_TYPE)
317 for (next = DECL_CHAIN (TREE_OPERAND (cref, 1));
318 next && TREE_CODE (next) != FIELD_DECL;
319 next = DECL_CHAIN (next))
321 if (next)
322 /* Not a last element. Instrument it. */
323 break;
324 /* Ok, this is the last field of the structure/union. But the
325 aggregate containing the field must be the last field too,
326 recursively. */
327 cref = TREE_OPERAND (cref, 0);
329 if (!next)
330 /* Don't instrument this flexible array member-like array in non-strict
331 -fsanitize=bounds mode. */
332 return NULL_TREE;
335 /* Don't emit instrumentation in the most common cases. */
336 tree idx = NULL_TREE;
337 if (TREE_CODE (*index) == INTEGER_CST)
338 idx = *index;
339 else if (TREE_CODE (*index) == BIT_AND_EXPR
340 && TREE_CODE (TREE_OPERAND (*index, 1)) == INTEGER_CST)
341 idx = TREE_OPERAND (*index, 1);
342 if (idx
343 && TREE_CODE (bound) == INTEGER_CST
344 && tree_int_cst_sgn (idx) >= 0
345 && tree_int_cst_le (idx, bound))
346 return NULL_TREE;
348 *index = save_expr (*index);
349 /* Create a "(T *) 0" tree node to describe the array type. */
350 tree zero_with_type = build_int_cst (build_pointer_type (type), 0);
351 return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
352 void_type_node, 3, zero_with_type,
353 *index, bound);
356 /* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS. */
358 bool
359 ubsan_array_ref_instrumented_p (const_tree t)
361 if (TREE_CODE (t) != ARRAY_REF)
362 return false;
364 tree op1 = TREE_OPERAND (t, 1);
365 return TREE_CODE (op1) == COMPOUND_EXPR
366 && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
367 && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
368 && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
371 /* Instrument an ARRAY_REF, if it hasn't already been instrumented.
372 IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
374 void
375 ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
377 if (!ubsan_array_ref_instrumented_p (*expr_p)
378 && do_ubsan_in_current_function ())
380 tree op0 = TREE_OPERAND (*expr_p, 0);
381 tree op1 = TREE_OPERAND (*expr_p, 1);
382 tree e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0, &op1,
383 ignore_off_by_one);
384 if (e != NULL_TREE)
386 tree t = copy_node (*expr_p);
387 TREE_OPERAND (t, 1) = build2 (COMPOUND_EXPR, TREE_TYPE (op1),
388 e, op1);
389 *expr_p = t;
394 static tree
395 ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype,
396 enum ubsan_null_ckind ckind)
398 if (!do_ubsan_in_current_function ())
399 return NULL_TREE;
401 tree type = TREE_TYPE (ptype);
402 tree orig_op = op;
403 bool instrument = false;
404 unsigned int mina = 0;
406 if (flag_sanitize & SANITIZE_ALIGNMENT)
408 mina = min_align_of_type (type);
409 if (mina <= 1)
410 mina = 0;
412 while ((TREE_CODE (op) == NOP_EXPR
413 || TREE_CODE (op) == NON_LVALUE_EXPR)
414 && TREE_CODE (TREE_TYPE (op)) == POINTER_TYPE)
415 op = TREE_OPERAND (op, 0);
416 if (TREE_CODE (op) == NOP_EXPR
417 && TREE_CODE (TREE_TYPE (op)) == REFERENCE_TYPE)
419 if (mina && mina > min_align_of_type (TREE_TYPE (TREE_TYPE (op))))
420 instrument = true;
422 else
424 if ((flag_sanitize & SANITIZE_NULL) && TREE_CODE (op) == ADDR_EXPR)
426 bool strict_overflow_p = false;
427 /* tree_single_nonzero_warnv_p will not return true for non-weak
428 non-automatic decls with -fno-delete-null-pointer-checks,
429 which is disabled during -fsanitize=null. We don't want to
430 instrument those, just weak vars though. */
431 int save_flag_delete_null_pointer_checks
432 = flag_delete_null_pointer_checks;
433 flag_delete_null_pointer_checks = 1;
434 if (!tree_single_nonzero_warnv_p (op, &strict_overflow_p)
435 || strict_overflow_p)
436 instrument = true;
437 flag_delete_null_pointer_checks
438 = save_flag_delete_null_pointer_checks;
440 else if (flag_sanitize & SANITIZE_NULL)
441 instrument = true;
442 if (mina && mina > 1)
444 if (!POINTER_TYPE_P (TREE_TYPE (op))
445 || mina > get_pointer_alignment (op) / BITS_PER_UNIT)
446 instrument = true;
449 if (!instrument)
450 return NULL_TREE;
451 op = save_expr (orig_op);
452 gcc_assert (POINTER_TYPE_P (ptype));
453 if (TREE_CODE (ptype) == REFERENCE_TYPE)
454 ptype = build_pointer_type (TREE_TYPE (ptype));
455 tree kind = build_int_cst (ptype, ckind);
456 tree align = build_int_cst (pointer_sized_int_node, mina);
457 tree call
458 = build_call_expr_internal_loc (loc, IFN_UBSAN_NULL, void_type_node,
459 3, op, kind, align);
460 TREE_SIDE_EFFECTS (call) = 1;
461 return fold_build2 (COMPOUND_EXPR, TREE_TYPE (op), call, op);
464 /* Instrument a NOP_EXPR to REFERENCE_TYPE if needed. */
466 void
467 ubsan_maybe_instrument_reference (tree stmt)
469 tree op = TREE_OPERAND (stmt, 0);
470 op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
471 TREE_TYPE (stmt),
472 UBSAN_REF_BINDING);
473 if (op)
474 TREE_OPERAND (stmt, 0) = op;
477 /* Instrument a CALL_EXPR to a method if needed. */
479 void
480 ubsan_maybe_instrument_member_call (tree stmt, bool is_ctor)
482 if (call_expr_nargs (stmt) == 0)
483 return;
484 tree op = CALL_EXPR_ARG (stmt, 0);
485 if (op == error_mark_node
486 || !POINTER_TYPE_P (TREE_TYPE (op)))
487 return;
488 op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
489 TREE_TYPE (op),
490 is_ctor ? UBSAN_CTOR_CALL
491 : UBSAN_MEMBER_CALL);
492 if (op)
493 CALL_EXPR_ARG (stmt, 0) = op;