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"
31 #include "c-family/c-common.h"
32 #include "c-family/c-ubsan.h"
34 /* Instrument division by zero and INT_MIN / -1. If not instrumenting,
38 ubsan_instrument_division (location_t loc
, tree op0
, tree op1
)
41 tree type
= TREE_TYPE (op0
);
43 /* At this point both operands should have the same type,
44 because they are already converted to RESULT_TYPE.
45 Use TYPE_MAIN_VARIANT since typedefs can confuse us. */
46 gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0
))
47 == TYPE_MAIN_VARIANT (TREE_TYPE (op1
)));
49 /* TODO: REAL_TYPE is not supported yet. */
50 if (TREE_CODE (type
) != INTEGER_TYPE
)
53 t
= fold_build2 (EQ_EXPR
, boolean_type_node
,
54 op1
, build_int_cst (type
, 0));
56 /* We check INT_MIN / -1 only for signed types. */
57 if (!TYPE_UNSIGNED (type
))
60 tt
= fold_build2 (EQ_EXPR
, boolean_type_node
, op1
,
61 build_int_cst (type
, -1));
62 x
= fold_build2 (EQ_EXPR
, boolean_type_node
, op0
,
63 TYPE_MIN_VALUE (type
));
64 x
= fold_build2 (TRUTH_AND_EXPR
, boolean_type_node
, x
, tt
);
65 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
, x
);
68 /* If the condition was folded to 0, no need to instrument
70 if (integer_zerop (t
))
73 /* In case we have a SAVE_EXPR in a conditional context, we need to
74 make sure it gets evaluated before the condition. */
75 t
= fold_build2 (COMPOUND_EXPR
, TREE_TYPE (t
), op0
, t
);
76 tree data
= ubsan_create_data ("__ubsan_overflow_data",
77 loc
, ubsan_type_descriptor (type
),
79 data
= build_fold_addr_expr_loc (loc
, data
);
80 tt
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW
);
81 tt
= build_call_expr_loc (loc
, tt
, 3, data
, ubsan_encode_value (op0
),
82 ubsan_encode_value (op1
));
83 t
= fold_build3 (COND_EXPR
, void_type_node
, t
, tt
, void_zero_node
);
88 /* Instrument left and right shifts. */
91 ubsan_instrument_shift (location_t loc
, enum tree_code code
,
94 tree t
, tt
= NULL_TREE
;
95 tree type0
= TREE_TYPE (op0
);
96 tree type1
= TREE_TYPE (op1
);
97 tree op1_utype
= unsigned_type_for (type1
);
98 HOST_WIDE_INT op0_prec
= TYPE_PRECISION (type0
);
99 tree uprecm1
= build_int_cst (op1_utype
, op0_prec
- 1);
100 tree precm1
= build_int_cst (type1
, op0_prec
- 1);
102 t
= fold_convert_loc (loc
, op1_utype
, op1
);
103 t
= fold_build2 (GT_EXPR
, boolean_type_node
, t
, uprecm1
);
105 /* For signed x << y, in C99/C11, the following:
106 (unsigned) x >> (precm1 - y)
107 if non-zero, is undefined. */
108 if (code
== LSHIFT_EXPR
109 && !TYPE_UNSIGNED (type0
)
112 tree x
= fold_build2 (MINUS_EXPR
, integer_type_node
, precm1
, op1
);
113 tt
= fold_convert_loc (loc
, unsigned_type_for (type0
), op0
);
114 tt
= fold_build2 (RSHIFT_EXPR
, TREE_TYPE (tt
), tt
, x
);
115 tt
= fold_build2 (NE_EXPR
, boolean_type_node
, tt
,
116 build_int_cst (TREE_TYPE (tt
), 0));
119 /* For signed x << y, in C++11/C++14, the following:
120 x < 0 || ((unsigned) x >> (precm1 - y))
121 if > 1, is undefined. */
122 if (code
== LSHIFT_EXPR
123 && !TYPE_UNSIGNED (TREE_TYPE (op0
))
124 && (cxx_dialect
== cxx11
|| cxx_dialect
== cxx1y
))
126 tree x
= fold_build2 (MINUS_EXPR
, integer_type_node
, precm1
, op1
);
127 tt
= fold_convert_loc (loc
, unsigned_type_for (type0
), op0
);
128 tt
= fold_build2 (RSHIFT_EXPR
, TREE_TYPE (tt
), tt
, x
);
129 tt
= fold_build2 (GT_EXPR
, boolean_type_node
, tt
,
130 build_int_cst (TREE_TYPE (tt
), 1));
131 x
= fold_build2 (LT_EXPR
, boolean_type_node
, op0
,
132 build_int_cst (type0
, 0));
133 tt
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, x
, tt
);
136 /* If the condition was folded to 0, no need to instrument
138 if (integer_zerop (t
) && (tt
== NULL_TREE
|| integer_zerop (tt
)))
141 /* In case we have a SAVE_EXPR in a conditional context, we need to
142 make sure it gets evaluated before the condition. */
143 t
= fold_build2 (COMPOUND_EXPR
, TREE_TYPE (t
), op0
, t
);
144 tree data
= ubsan_create_data ("__ubsan_shift_data",
145 loc
, ubsan_type_descriptor (type0
),
146 ubsan_type_descriptor (type1
), NULL_TREE
);
148 data
= build_fold_addr_expr_loc (loc
, data
);
150 t
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, t
,
151 tt
? tt
: integer_zero_node
);
152 tt
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS
);
153 tt
= build_call_expr_loc (loc
, tt
, 3, data
, ubsan_encode_value (op0
),
154 ubsan_encode_value (op1
));
155 t
= fold_build3 (COND_EXPR
, void_type_node
, t
, tt
, void_zero_node
);
160 /* Instrument variable length array bound. */
163 ubsan_instrument_vla (location_t loc
, tree size
)
165 tree type
= TREE_TYPE (size
);
168 t
= fold_build2 (LE_EXPR
, boolean_type_node
, size
, build_int_cst (type
, 0));
169 tree data
= ubsan_create_data ("__ubsan_vla_data",
170 loc
, ubsan_type_descriptor (type
), NULL_TREE
);
171 data
= build_fold_addr_expr_loc (loc
, data
);
172 tt
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE
);
173 tt
= build_call_expr_loc (loc
, tt
, 2, data
, ubsan_encode_value (size
));
174 t
= fold_build3 (COND_EXPR
, void_type_node
, t
, tt
, void_zero_node
);