Merge from trunk:
[official-gcc.git] / main / gcc / c-family / c-ubsan.c
blobe048c53ac3ee4e3051091cff841d712cb366d089
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013-2014 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 "cgraph.h"
27 #include "output.h"
28 #include "toplev.h"
29 #include "ubsan.h"
30 #include "c-family/c-common.h"
31 #include "c-family/c-ubsan.h"
32 #include "asan.h"
33 #include "internal-fn.h"
34 #include "stor-layout.h"
35 #include "builtins.h"
37 /* Instrument division by zero and INT_MIN / -1. If not instrumenting,
38 return NULL_TREE. */
40 tree
41 ubsan_instrument_division (location_t loc, tree op0, tree op1)
43 tree t, tt;
44 tree type = TREE_TYPE (op0);
46 /* At this point both operands should have the same type,
47 because they are already converted to RESULT_TYPE.
48 Use TYPE_MAIN_VARIANT since typedefs can confuse us. */
49 gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
50 == TYPE_MAIN_VARIANT (TREE_TYPE (op1)));
52 if (TREE_CODE (type) == INTEGER_TYPE
53 && (flag_sanitize & SANITIZE_DIVIDE))
54 t = fold_build2 (EQ_EXPR, boolean_type_node,
55 op1, build_int_cst (type, 0));
56 else if (TREE_CODE (type) == REAL_TYPE
57 && (flag_sanitize & SANITIZE_FLOAT_DIVIDE))
58 t = fold_build2 (EQ_EXPR, boolean_type_node,
59 op1, build_real (type, dconst0));
60 else
61 return NULL_TREE;
63 /* We check INT_MIN / -1 only for signed types. */
64 if (TREE_CODE (type) == INTEGER_TYPE
65 && (flag_sanitize & SANITIZE_DIVIDE)
66 && !TYPE_UNSIGNED (type))
68 tree x;
69 tt = fold_build2 (EQ_EXPR, boolean_type_node, op1,
70 build_int_cst (type, -1));
71 x = fold_build2 (EQ_EXPR, boolean_type_node, op0,
72 TYPE_MIN_VALUE (type));
73 x = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, x, tt);
74 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, x);
77 /* If the condition was folded to 0, no need to instrument
78 this expression. */
79 if (integer_zerop (t))
80 return NULL_TREE;
82 /* In case we have a SAVE_EXPR in a conditional context, we need to
83 make sure it gets evaluated before the condition. If the OP0 is
84 an instrumented array reference, mark it as having side effects so
85 it's not folded away. */
86 if (flag_sanitize & SANITIZE_BOUNDS)
88 tree xop0 = op0;
89 while (CONVERT_EXPR_P (xop0))
90 xop0 = TREE_OPERAND (xop0, 0);
91 if (TREE_CODE (xop0) == ARRAY_REF)
93 TREE_SIDE_EFFECTS (xop0) = 1;
94 TREE_SIDE_EFFECTS (op0) = 1;
97 t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
98 if (flag_sanitize_undefined_trap_on_error)
99 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
100 else
102 tree data = ubsan_create_data ("__ubsan_overflow_data", &loc, NULL,
103 ubsan_type_descriptor (type), NULL_TREE);
104 data = build_fold_addr_expr_loc (loc, data);
105 enum built_in_function bcode
106 = flag_sanitize_recover
107 ? BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW
108 : BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW_ABORT;
109 tt = builtin_decl_explicit (bcode);
110 tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
111 ubsan_encode_value (op1));
113 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
115 return t;
118 /* Instrument left and right shifts. */
120 tree
121 ubsan_instrument_shift (location_t loc, enum tree_code code,
122 tree op0, tree op1)
124 tree t, tt = NULL_TREE;
125 tree type0 = TREE_TYPE (op0);
126 tree type1 = TREE_TYPE (op1);
127 tree op1_utype = unsigned_type_for (type1);
128 HOST_WIDE_INT op0_prec = TYPE_PRECISION (type0);
129 tree uprecm1 = build_int_cst (op1_utype, op0_prec - 1);
130 tree precm1 = build_int_cst (type1, op0_prec - 1);
132 t = fold_convert_loc (loc, op1_utype, op1);
133 t = fold_build2 (GT_EXPR, boolean_type_node, t, uprecm1);
135 /* For signed x << y, in C99/C11, the following:
136 (unsigned) x >> (precm1 - y)
137 if non-zero, is undefined. */
138 if (code == LSHIFT_EXPR
139 && !TYPE_UNSIGNED (type0)
140 && flag_isoc99)
142 tree x = fold_build2 (MINUS_EXPR, integer_type_node, precm1, op1);
143 tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
144 tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
145 tt = fold_build2 (NE_EXPR, boolean_type_node, tt,
146 build_int_cst (TREE_TYPE (tt), 0));
149 /* For signed x << y, in C++11/C++14, the following:
150 x < 0 || ((unsigned) x >> (precm1 - y))
151 if > 1, is undefined. */
152 if (code == LSHIFT_EXPR
153 && !TYPE_UNSIGNED (TREE_TYPE (op0))
154 && (cxx_dialect == cxx11 || cxx_dialect == cxx1y))
156 tree x = fold_build2 (MINUS_EXPR, integer_type_node, precm1, op1);
157 tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
158 tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
159 tt = fold_build2 (GT_EXPR, boolean_type_node, tt,
160 build_int_cst (TREE_TYPE (tt), 1));
161 x = fold_build2 (LT_EXPR, boolean_type_node, op0,
162 build_int_cst (type0, 0));
163 tt = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, x, tt);
166 /* If the condition was folded to 0, no need to instrument
167 this expression. */
168 if (integer_zerop (t) && (tt == NULL_TREE || integer_zerop (tt)))
169 return NULL_TREE;
171 /* In case we have a SAVE_EXPR in a conditional context, we need to
172 make sure it gets evaluated before the condition. If the OP0 is
173 an instrumented array reference, mark it as having side effects so
174 it's not folded away. */
175 if (flag_sanitize & SANITIZE_BOUNDS)
177 tree xop0 = op0;
178 while (CONVERT_EXPR_P (xop0))
179 xop0 = TREE_OPERAND (xop0, 0);
180 if (TREE_CODE (xop0) == ARRAY_REF)
182 TREE_SIDE_EFFECTS (xop0) = 1;
183 TREE_SIDE_EFFECTS (op0) = 1;
186 t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
187 t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t,
188 tt ? tt : integer_zero_node);
190 if (flag_sanitize_undefined_trap_on_error)
191 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
192 else
194 tree data = ubsan_create_data ("__ubsan_shift_data", &loc, NULL,
195 ubsan_type_descriptor (type0),
196 ubsan_type_descriptor (type1), NULL_TREE);
197 data = build_fold_addr_expr_loc (loc, data);
199 enum built_in_function bcode
200 = flag_sanitize_recover
201 ? BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS
202 : BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS_ABORT;
203 tt = builtin_decl_explicit (bcode);
204 tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
205 ubsan_encode_value (op1));
207 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
209 return t;
212 /* Instrument variable length array bound. */
214 tree
215 ubsan_instrument_vla (location_t loc, tree size)
217 tree type = TREE_TYPE (size);
218 tree t, tt;
220 t = fold_build2 (LE_EXPR, boolean_type_node, size, build_int_cst (type, 0));
221 if (flag_sanitize_undefined_trap_on_error)
222 tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
223 else
225 tree data = ubsan_create_data ("__ubsan_vla_data", &loc, NULL,
226 ubsan_type_descriptor (type), NULL_TREE);
227 data = build_fold_addr_expr_loc (loc, data);
228 enum built_in_function bcode
229 = flag_sanitize_recover
230 ? BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE
231 : BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE_ABORT;
232 tt = builtin_decl_explicit (bcode);
233 tt = build_call_expr_loc (loc, tt, 2, data, ubsan_encode_value (size));
235 t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
237 return t;
240 /* Instrument missing return in C++ functions returning non-void. */
242 tree
243 ubsan_instrument_return (location_t loc)
245 if (flag_sanitize_undefined_trap_on_error)
246 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
247 /* It is possible that PCH zapped table with definitions of sanitizer
248 builtins. Reinitialize them if needed. */
249 initialize_sanitizer_builtins ();
251 tree data = ubsan_create_data ("__ubsan_missing_return_data", &loc,
252 NULL, NULL_TREE);
253 tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_MISSING_RETURN);
254 return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
257 /* Instrument array bounds for ARRAY_REFs. We create special builtin,
258 that gets expanded in the sanopt pass, and make an array dimension
259 of it. ARRAY is the array, *INDEX is an index to the array.
260 Return NULL_TREE if no instrumentation is emitted.
261 IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
263 tree
264 ubsan_instrument_bounds (location_t loc, tree array, tree *index,
265 bool ignore_off_by_one)
267 tree type = TREE_TYPE (array);
268 tree domain = TYPE_DOMAIN (type);
270 if (domain == NULL_TREE || TYPE_MAX_VALUE (domain) == NULL_TREE)
271 return NULL_TREE;
273 tree bound = TYPE_MAX_VALUE (domain);
274 if (ignore_off_by_one)
275 bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound,
276 build_int_cst (TREE_TYPE (bound), 1));
278 /* Detect flexible array members and suchlike. */
279 tree base = get_base_address (array);
280 if (base && (TREE_CODE (base) == INDIRECT_REF
281 || TREE_CODE (base) == MEM_REF))
283 tree next = NULL_TREE;
284 tree cref = array;
286 /* Walk all structs/unions. */
287 while (TREE_CODE (cref) == COMPONENT_REF)
289 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (cref, 0))) == RECORD_TYPE)
290 for (next = DECL_CHAIN (TREE_OPERAND (cref, 1));
291 next && TREE_CODE (next) != FIELD_DECL;
292 next = DECL_CHAIN (next))
294 if (next)
295 /* Not a last element. Instrument it. */
296 break;
297 /* Ok, this is the last field of the structure/union. But the
298 aggregate containing the field must be the last field too,
299 recursively. */
300 cref = TREE_OPERAND (cref, 0);
302 if (!next)
303 /* Don't instrument this flexible array member-like array in non-strict
304 -fsanitize=bounds mode. */
305 return NULL_TREE;
308 *index = save_expr (*index);
309 /* Create a "(T *) 0" tree node to describe the array type. */
310 tree zero_with_type = build_int_cst (build_pointer_type (type), 0);
311 return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
312 void_type_node, 3, zero_with_type,
313 *index, bound);
316 /* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS. */
318 bool
319 ubsan_array_ref_instrumented_p (const_tree t)
321 if (TREE_CODE (t) != ARRAY_REF)
322 return false;
324 tree op1 = TREE_OPERAND (t, 1);
325 return TREE_CODE (op1) == COMPOUND_EXPR
326 && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
327 && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
328 && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
331 /* Instrument an ARRAY_REF, if it hasn't already been instrumented.
332 IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
334 void
335 ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
337 if (!ubsan_array_ref_instrumented_p (*expr_p)
338 && current_function_decl != NULL_TREE
339 && !lookup_attribute ("no_sanitize_undefined",
340 DECL_ATTRIBUTES (current_function_decl)))
342 tree op0 = TREE_OPERAND (*expr_p, 0);
343 tree op1 = TREE_OPERAND (*expr_p, 1);
344 tree e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0, &op1,
345 ignore_off_by_one);
346 if (e != NULL_TREE)
348 tree t = copy_node (*expr_p);
349 TREE_OPERAND (t, 1) = build2 (COMPOUND_EXPR, TREE_TYPE (op1),
350 e, op1);
351 *expr_p = t;
356 static tree
357 ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree type,
358 enum ubsan_null_ckind ckind)
360 tree orig_op = op;
361 bool instrument = false;
362 unsigned int mina = 0;
364 if (current_function_decl == NULL_TREE
365 || lookup_attribute ("no_sanitize_undefined",
366 DECL_ATTRIBUTES (current_function_decl)))
367 return NULL_TREE;
369 if (flag_sanitize & SANITIZE_ALIGNMENT)
371 mina = min_align_of_type (type);
372 if (mina <= 1)
373 mina = 0;
375 while ((TREE_CODE (op) == NOP_EXPR
376 || TREE_CODE (op) == NON_LVALUE_EXPR)
377 && TREE_CODE (TREE_TYPE (op)) == POINTER_TYPE)
378 op = TREE_OPERAND (op, 0);
379 if (TREE_CODE (op) == NOP_EXPR
380 && TREE_CODE (TREE_TYPE (op)) == REFERENCE_TYPE)
382 if (mina && mina > min_align_of_type (TREE_TYPE (TREE_TYPE (op))))
383 instrument = true;
385 else
387 if ((flag_sanitize & SANITIZE_NULL) && TREE_CODE (op) == ADDR_EXPR)
389 bool strict_overflow_p = false;
390 /* tree_single_nonzero_warnv_p will not return true for non-weak
391 non-automatic decls with -fno-delete-null-pointer-checks,
392 which is disabled during -fsanitize=null. We don't want to
393 instrument those, just weak vars though. */
394 int save_flag_delete_null_pointer_checks
395 = flag_delete_null_pointer_checks;
396 flag_delete_null_pointer_checks = 1;
397 if (!tree_single_nonzero_warnv_p (op, &strict_overflow_p)
398 || strict_overflow_p)
399 instrument = true;
400 flag_delete_null_pointer_checks
401 = save_flag_delete_null_pointer_checks;
403 else if (flag_sanitize & SANITIZE_NULL)
404 instrument = true;
405 if (mina && mina > get_pointer_alignment (op) / BITS_PER_UNIT)
406 instrument = true;
408 if (!instrument)
409 return NULL_TREE;
410 op = save_expr (orig_op);
411 tree kind = build_int_cst (TREE_TYPE (op), ckind);
412 tree align = build_int_cst (pointer_sized_int_node, mina);
413 tree call
414 = build_call_expr_internal_loc (loc, IFN_UBSAN_NULL, void_type_node,
415 3, op, kind, align);
416 TREE_SIDE_EFFECTS (call) = 1;
417 return fold_build2 (COMPOUND_EXPR, TREE_TYPE (op), call, op);
420 /* Instrument a NOP_EXPR to REFERENCE_TYPE if needed. */
422 void
423 ubsan_maybe_instrument_reference (tree stmt)
425 tree op = TREE_OPERAND (stmt, 0);
426 op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
427 TREE_TYPE (TREE_TYPE (stmt)),
428 UBSAN_REF_BINDING);
429 if (op)
430 TREE_OPERAND (stmt, 0) = op;
433 /* Instrument a CALL_EXPR to a method if needed. */
435 void
436 ubsan_maybe_instrument_member_call (tree stmt, bool is_ctor)
438 if (call_expr_nargs (stmt) == 0)
439 return;
440 tree op = CALL_EXPR_ARG (stmt, 0);
441 if (op == error_mark_node
442 || !POINTER_TYPE_P (TREE_TYPE (op)))
443 return;
444 op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
445 TREE_TYPE (TREE_TYPE (op)),
446 is_ctor ? UBSAN_CTOR_CALL
447 : UBSAN_MEMBER_CALL);
448 if (op)
449 CALL_EXPR_ARG (stmt, 0) = op;