Update gcc-50 to SVN version 221261
[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 (TREE_CODE (array) == COMPONENT_REF
307       && base && (TREE_CODE (base) == INDIRECT_REF
308                   || TREE_CODE (base) == MEM_REF))
309     {
310       tree next = NULL_TREE;
311       tree cref = array;
312
313       /* Walk all structs/unions.  */
314       while (TREE_CODE (cref) == COMPONENT_REF)
315         {
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))
320               ;
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);
328         }
329       if (!next)
330         /* Don't instrument this flexible array member-like array in non-strict
331            -fsanitize=bounds mode.  */
332         return NULL_TREE;
333     }
334
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;
347
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);
354 }
355
356 /* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS.  */
357
358 bool
359 ubsan_array_ref_instrumented_p (const_tree t)
360 {
361   if (TREE_CODE (t) != ARRAY_REF)
362     return false;
363
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;
369 }
370
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.  */
373
374 void
375 ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
376 {
377   if (!ubsan_array_ref_instrumented_p (*expr_p)
378       && do_ubsan_in_current_function ())
379     {
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)
385         {
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;
390         }
391     }
392 }
393
394 static tree
395 ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype,
396                                           enum ubsan_null_ckind ckind)
397 {
398   if (!do_ubsan_in_current_function ())
399     return NULL_TREE;
400
401   tree type = TREE_TYPE (ptype);
402   tree orig_op = op;
403   bool instrument = false;
404   unsigned int mina = 0;
405
406   if (flag_sanitize & SANITIZE_ALIGNMENT)
407     {
408       mina = min_align_of_type (type);
409       if (mina <= 1)
410         mina = 0;
411     }
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)
418     {
419       if (mina && mina > min_align_of_type (TREE_TYPE (TREE_TYPE (op))))
420         instrument = true;
421     }
422   else
423     {
424       if ((flag_sanitize & SANITIZE_NULL) && TREE_CODE (op) == ADDR_EXPR)
425         {
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;
439         }
440       else if (flag_sanitize & SANITIZE_NULL)
441         instrument = true;
442       if (mina && mina > 1)
443         {
444           if (!POINTER_TYPE_P (TREE_TYPE (op))
445               || mina > get_pointer_alignment (op) / BITS_PER_UNIT)
446             instrument = true;
447         }
448     }
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);
462 }
463
464 /* Instrument a NOP_EXPR to REFERENCE_TYPE if needed.  */
465
466 void
467 ubsan_maybe_instrument_reference (tree stmt)
468 {
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;
475 }
476
477 /* Instrument a CALL_EXPR to a method if needed.  */
478
479 void
480 ubsan_maybe_instrument_member_call (tree stmt, bool is_ctor)
481 {
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;
494 }