1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013 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
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
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/>. */
23 #include "coretypes.h"
25 #include "alloc-pool.h"
30 #include "c-family/c-common.h"
31 #include "c-family/c-ubsan.h"
33 /* Instrument division by zero and INT_MIN / -1. If not instrumenting,
37 ubsan_instrument_division (location_t loc
, tree op0
, tree op1
)
40 tree type
= TREE_TYPE (op0
);
42 /* At this point both operands should have the same type,
43 because they are already converted to RESULT_TYPE.
44 Use TYPE_MAIN_VARIANT since typedefs can confuse us. */
45 gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0
))
46 == TYPE_MAIN_VARIANT (TREE_TYPE (op1
)));
48 /* TODO: REAL_TYPE is not supported yet. */
49 if (TREE_CODE (type
) != INTEGER_TYPE
)
52 t
= fold_build2 (EQ_EXPR
, boolean_type_node
,
53 op1
, build_int_cst (type
, 0));
55 /* We check INT_MIN / -1 only for signed types. */
56 if (!TYPE_UNSIGNED (type
))
59 tt
= fold_build2 (EQ_EXPR
, boolean_type_node
, op1
,
60 build_int_cst (type
, -1));
61 x
= fold_build2 (EQ_EXPR
, boolean_type_node
, op0
,
62 TYPE_MIN_VALUE (type
));
63 x
= fold_build2 (TRUTH_AND_EXPR
, boolean_type_node
, x
, tt
);
64 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, x
);
67 /* If the condition was folded to 0, no need to instrument
69 if (integer_zerop (t
))
72 /* In case we have a SAVE_EXPR in a conditional context, we need to
73 make sure it gets evaluated before the condition. */
74 t
= fold_build2 (COMPOUND_EXPR
, TREE_TYPE (t
), op0
, t
);
75 tree data
= ubsan_create_data ("__ubsan_overflow_data",
76 loc
, ubsan_type_descriptor (type
),
78 data
= build_fold_addr_expr_loc (loc
, data
);
79 tt
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW
);
80 tt
= build_call_expr_loc (loc
, tt
, 3, data
, ubsan_encode_value (op0
),
81 ubsan_encode_value (op1
));
82 t
= fold_build3 (COND_EXPR
, void_type_node
, t
, tt
, void_zero_node
);
87 /* Instrument left and right shifts. */
90 ubsan_instrument_shift (location_t loc
, enum tree_code code
,
93 tree t
, tt
= NULL_TREE
;
94 tree type0
= TREE_TYPE (op0
);
95 tree type1
= TREE_TYPE (op1
);
96 tree op1_utype
= unsigned_type_for (type1
);
97 HOST_WIDE_INT op0_prec
= TYPE_PRECISION (type0
);
98 tree uprecm1
= build_int_cst (op1_utype
, op0_prec
- 1);
99 tree precm1
= build_int_cst (type1
, op0_prec
- 1);
101 t
= fold_convert_loc (loc
, op1_utype
, op1
);
102 t
= fold_build2 (GT_EXPR
, boolean_type_node
, t
, uprecm1
);
104 /* For signed x << y, in C99/C11, the following:
105 (unsigned) x >> (precm1 - y)
106 if non-zero, is undefined. */
107 if (code
== LSHIFT_EXPR
108 && !TYPE_UNSIGNED (type0
)
111 tree x
= fold_build2 (MINUS_EXPR
, integer_type_node
, precm1
, op1
);
112 tt
= fold_convert_loc (loc
, unsigned_type_for (type0
), op0
);
113 tt
= fold_build2 (RSHIFT_EXPR
, TREE_TYPE (tt
), tt
, x
);
114 tt
= fold_build2 (NE_EXPR
, boolean_type_node
, tt
,
115 build_int_cst (TREE_TYPE (tt
), 0));
118 /* For signed x << y, in C++11/C++14, the following:
119 x < 0 || ((unsigned) x >> (precm1 - y))
120 if > 1, is undefined. */
121 if (code
== LSHIFT_EXPR
122 && !TYPE_UNSIGNED (TREE_TYPE (op0
))
123 && (cxx_dialect
== cxx11
|| cxx_dialect
== cxx1y
))
125 tree x
= fold_build2 (MINUS_EXPR
, integer_type_node
, precm1
, op1
);
126 tt
= fold_convert_loc (loc
, unsigned_type_for (type0
), op0
);
127 tt
= fold_build2 (RSHIFT_EXPR
, TREE_TYPE (tt
), tt
, x
);
128 tt
= fold_build2 (GT_EXPR
, boolean_type_node
, tt
,
129 build_int_cst (TREE_TYPE (tt
), 1));
130 x
= fold_build2 (LT_EXPR
, boolean_type_node
, op0
,
131 build_int_cst (type0
, 0));
132 tt
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, x
, tt
);
135 /* If the condition was folded to 0, no need to instrument
137 if (integer_zerop (t
) && (tt
== NULL_TREE
|| integer_zerop (tt
)))
140 /* In case we have a SAVE_EXPR in a conditional context, we need to
141 make sure it gets evaluated before the condition. */
142 t
= fold_build2 (COMPOUND_EXPR
, TREE_TYPE (t
), op0
, t
);
143 tree data
= ubsan_create_data ("__ubsan_shift_data",
144 loc
, ubsan_type_descriptor (type0
),
145 ubsan_type_descriptor (type1
), NULL_TREE
);
147 data
= build_fold_addr_expr_loc (loc
, data
);
149 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
,
150 tt
? tt
: integer_zero_node
);
151 tt
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS
);
152 tt
= build_call_expr_loc (loc
, tt
, 3, data
, ubsan_encode_value (op0
),
153 ubsan_encode_value (op1
));
154 t
= fold_build3 (COND_EXPR
, void_type_node
, t
, tt
, void_zero_node
);
159 /* Instrument variable length array bound. */
162 ubsan_instrument_vla (location_t loc
, tree size
)
164 tree type
= TREE_TYPE (size
);
167 t
= fold_build2 (LE_EXPR
, boolean_type_node
, size
, build_int_cst (type
, 0));
168 tree data
= ubsan_create_data ("__ubsan_vla_data",
169 loc
, ubsan_type_descriptor (type
), NULL_TREE
);
170 data
= build_fold_addr_expr_loc (loc
, data
);
171 tt
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE
);
172 tt
= build_call_expr_loc (loc
, tt
, 2, data
, ubsan_encode_value (size
));
173 t
= fold_build3 (COND_EXPR
, void_type_node
, t
, tt
, void_zero_node
);