Merge branch 'vendor/GCC50' - gcc 5.0 snapshot 1 FEB 2015
[dragonfly.git] / contrib / gcc-5.0 / gcc / c-family / c-ubsan.c
1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2    Copyright (C) 2013-2015 Free Software Foundation, Inc.
3    Contributed by Marek Polacek <polacek@redhat.com>
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>.  */
20
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"
58
59 /* Instrument division by zero and INT_MIN / -1.  If not instrumenting,
60    return NULL_TREE.  */
61
62 tree
63 ubsan_instrument_division (location_t loc, tree op0, tree op1)
64 {
65   tree t, tt;
66   tree type = TREE_TYPE (op0);
67
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)));
73
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;
84
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))
89     {
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);
97     }
98
99   /* If the condition was folded to 0, no need to instrument
100      this expression.  */
101   if (integer_zerop (t))
102     return NULL_TREE;
103
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)
109     {
110       tree xop0 = op0;
111       while (CONVERT_EXPR_P (xop0))
112         xop0 = TREE_OPERAND (xop0, 0);
113       if (TREE_CODE (xop0) == ARRAY_REF)
114         {
115           TREE_SIDE_EFFECTS (xop0) = 1;
116           TREE_SIDE_EFFECTS (op0) = 1;
117         }
118     }
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
123     {
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));
135     }
136   t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
137
138   return t;
139 }
140
141 /* Instrument left and right shifts.  */
142
143 tree
144 ubsan_instrument_shift (location_t loc, enum tree_code code,
145                         tree op0, tree op1)
146 {
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);
153
154   t = fold_convert_loc (loc, op1_utype, op1);
155   t = fold_build2 (GT_EXPR, boolean_type_node, t, uprecm1);
156
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)
163     {
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));
170     }
171
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))
178     {
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);
188     }
189
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;
194
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)
200     {
201       tree xop0 = op0;
202       while (CONVERT_EXPR_P (xop0))
203         xop0 = TREE_OPERAND (xop0, 0);
204       if (TREE_CODE (xop0) == ARRAY_REF)
205         {
206           TREE_SIDE_EFFECTS (xop0) = 1;
207           TREE_SIDE_EFFECTS (op0) = 1;
208         }
209     }
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);
213
214   if (flag_sanitize_undefined_trap_on_error)
215     tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
216   else
217     {
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);
223
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));
231     }
232   t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
233
234   return t;
235 }
236
237 /* Instrument variable length array bound.  */
238
239 tree
240 ubsan_instrument_vla (location_t loc, tree size)
241 {
242   tree type = TREE_TYPE (size);
243   tree t, tt;
244
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
249     {
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));
260     }
261   t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
262
263   return t;
264 }
265
266 /* Instrument missing return in C++ functions returning non-void.  */
267
268 tree
269 ubsan_instrument_return (location_t loc)
270 {
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 ();
276
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));
281 }
282
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.  */
288
289 tree
290 ubsan_instrument_bounds (location_t loc, tree array, tree *index,
291                          bool ignore_off_by_one)
292 {
293   tree type = TREE_TYPE (array);
294   tree domain = TYPE_DOMAIN (type);
295
296   if (domain == NULL_TREE || TYPE_MAX_VALUE (domain) == NULL_TREE)
297     return NULL_TREE;
298
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));
303
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))
308     {
309       tree next = NULL_TREE;
310       tree cref = array;
311
312       /* Walk all structs/unions.  */
313       while (TREE_CODE (cref) == COMPONENT_REF)
314         {
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))
319               ;
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);
327         }
328       if (!next)
329         /* Don't instrument this flexible array member-like array in non-strict
330            -fsanitize=bounds mode.  */
331         return NULL_TREE;
332     }
333
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;
346
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);
353 }
354
355 /* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS.  */
356
357 bool
358 ubsan_array_ref_instrumented_p (const_tree t)
359 {
360   if (TREE_CODE (t) != ARRAY_REF)
361     return false;
362
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;
368 }
369
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.  */
372
373 void
374 ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
375 {
376   if (!ubsan_array_ref_instrumented_p (*expr_p)
377       && do_ubsan_in_current_function ())
378     {
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)
384         {
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;
389         }
390     }
391 }
392
393 static tree
394 ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype,
395                                           enum ubsan_null_ckind ckind)
396 {
397   if (!do_ubsan_in_current_function ())
398     return NULL_TREE;
399
400   tree type = TREE_TYPE (ptype);
401   tree orig_op = op;
402   bool instrument = false;
403   unsigned int mina = 0;
404
405   if (flag_sanitize & SANITIZE_ALIGNMENT)
406     {
407       mina = min_align_of_type (type);
408       if (mina <= 1)
409         mina = 0;
410     }
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)
417     {
418       if (mina && mina > min_align_of_type (TREE_TYPE (TREE_TYPE (op))))
419         instrument = true;
420     }
421   else
422     {
423       if ((flag_sanitize & SANITIZE_NULL) && TREE_CODE (op) == ADDR_EXPR)
424         {
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;
438         }
439       else if (flag_sanitize & SANITIZE_NULL)
440         instrument = true;
441       if (mina && mina > 1)
442         {
443           if (!POINTER_TYPE_P (TREE_TYPE (op))
444               || mina > get_pointer_alignment (op) / BITS_PER_UNIT)
445             instrument = true;
446         }
447     }
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);
461 }
462
463 /* Instrument a NOP_EXPR to REFERENCE_TYPE if needed.  */
464
465 void
466 ubsan_maybe_instrument_reference (tree stmt)
467 {
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;
474 }
475
476 /* Instrument a CALL_EXPR to a method if needed.  */
477
478 void
479 ubsan_maybe_instrument_member_call (tree stmt, bool is_ctor)
480 {
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;
493 }