* config/abi/post/alpha-linux-gnu/baseline_symbols.txt: Update.
[official-gcc.git] / libsanitizer / ubsan / ubsan_handlers.cc
blobdd2e7bbf3e5b86a7b9788eb8a1b82ef45a076585
1 //===-- ubsan_handlers.cc -------------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // Error logging entry points for the UBSan runtime.
9 //
10 //===----------------------------------------------------------------------===//
12 #include "ubsan_handlers.h"
13 #include "ubsan_diag.h"
15 #include "sanitizer_common/sanitizer_common.h"
17 using namespace __sanitizer;
18 using namespace __ubsan;
20 namespace __ubsan {
21 const char *TypeCheckKinds[] = {
22 "load of", "store to", "reference binding to", "member access within",
23 "member call on", "constructor call on", "downcast of", "downcast of"
27 static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,
28 Location FallbackLoc) {
29 Location Loc = Data->Loc.acquire();
31 // Use the SourceLocation from Data to track deduplication, even if 'invalid'
32 if (Loc.getSourceLocation().isDisabled())
33 return;
34 if (Data->Loc.isInvalid())
35 Loc = FallbackLoc;
37 if (!Pointer)
38 Diag(Loc, DL_Error, "%0 null pointer of type %1")
39 << TypeCheckKinds[Data->TypeCheckKind] << Data->Type;
40 else if (Data->Alignment && (Pointer & (Data->Alignment - 1)))
41 Diag(Loc, DL_Error, "%0 misaligned address %1 for type %3, "
42 "which requires %2 byte alignment")
43 << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer
44 << Data->Alignment << Data->Type;
45 else
46 Diag(Loc, DL_Error, "%0 address %1 with insufficient space "
47 "for an object of type %2")
48 << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
49 if (Pointer)
50 Diag(Pointer, DL_Note, "pointer points here");
52 void __ubsan::__ubsan_handle_type_mismatch(TypeMismatchData *Data,
53 ValueHandle Pointer) {
54 handleTypeMismatchImpl(Data, Pointer, getCallerLocation());
56 void __ubsan::__ubsan_handle_type_mismatch_abort(TypeMismatchData *Data,
57 ValueHandle Pointer) {
58 handleTypeMismatchImpl(Data, Pointer, getCallerLocation());
59 Die();
62 /// \brief Common diagnostic emission for various forms of integer overflow.
63 template<typename T> static void HandleIntegerOverflow(OverflowData *Data,
64 ValueHandle LHS,
65 const char *Operator,
66 T RHS) {
67 SourceLocation Loc = Data->Loc.acquire();
68 if (Loc.isDisabled())
69 return;
71 Diag(Loc, DL_Error, "%0 integer overflow: "
72 "%1 %2 %3 cannot be represented in type %4")
73 << (Data->Type.isSignedIntegerTy() ? "signed" : "unsigned")
74 << Value(Data->Type, LHS) << Operator << RHS << Data->Type;
77 void __ubsan::__ubsan_handle_add_overflow(OverflowData *Data,
78 ValueHandle LHS, ValueHandle RHS) {
79 HandleIntegerOverflow(Data, LHS, "+", Value(Data->Type, RHS));
81 void __ubsan::__ubsan_handle_add_overflow_abort(OverflowData *Data,
82 ValueHandle LHS,
83 ValueHandle RHS) {
84 __ubsan_handle_add_overflow(Data, LHS, RHS);
85 Die();
88 void __ubsan::__ubsan_handle_sub_overflow(OverflowData *Data,
89 ValueHandle LHS, ValueHandle RHS) {
90 HandleIntegerOverflow(Data, LHS, "-", Value(Data->Type, RHS));
92 void __ubsan::__ubsan_handle_sub_overflow_abort(OverflowData *Data,
93 ValueHandle LHS,
94 ValueHandle RHS) {
95 __ubsan_handle_sub_overflow(Data, LHS, RHS);
96 Die();
99 void __ubsan::__ubsan_handle_mul_overflow(OverflowData *Data,
100 ValueHandle LHS, ValueHandle RHS) {
101 HandleIntegerOverflow(Data, LHS, "*", Value(Data->Type, RHS));
103 void __ubsan::__ubsan_handle_mul_overflow_abort(OverflowData *Data,
104 ValueHandle LHS,
105 ValueHandle RHS) {
106 __ubsan_handle_mul_overflow(Data, LHS, RHS);
107 Die();
110 void __ubsan::__ubsan_handle_negate_overflow(OverflowData *Data,
111 ValueHandle OldVal) {
112 SourceLocation Loc = Data->Loc.acquire();
113 if (Loc.isDisabled())
114 return;
116 if (Data->Type.isSignedIntegerTy())
117 Diag(Loc, DL_Error,
118 "negation of %0 cannot be represented in type %1; "
119 "cast to an unsigned type to negate this value to itself")
120 << Value(Data->Type, OldVal) << Data->Type;
121 else
122 Diag(Loc, DL_Error,
123 "negation of %0 cannot be represented in type %1")
124 << Value(Data->Type, OldVal) << Data->Type;
126 void __ubsan::__ubsan_handle_negate_overflow_abort(OverflowData *Data,
127 ValueHandle OldVal) {
128 __ubsan_handle_negate_overflow(Data, OldVal);
129 Die();
132 void __ubsan::__ubsan_handle_divrem_overflow(OverflowData *Data,
133 ValueHandle LHS, ValueHandle RHS) {
134 SourceLocation Loc = Data->Loc.acquire();
135 if (Loc.isDisabled())
136 return;
138 Value LHSVal(Data->Type, LHS);
139 Value RHSVal(Data->Type, RHS);
140 if (RHSVal.isMinusOne())
141 Diag(Loc, DL_Error,
142 "division of %0 by -1 cannot be represented in type %1")
143 << LHSVal << Data->Type;
144 else
145 Diag(Loc, DL_Error, "division by zero");
147 void __ubsan::__ubsan_handle_divrem_overflow_abort(OverflowData *Data,
148 ValueHandle LHS,
149 ValueHandle RHS) {
150 __ubsan_handle_divrem_overflow(Data, LHS, RHS);
151 Die();
154 void __ubsan::__ubsan_handle_shift_out_of_bounds(ShiftOutOfBoundsData *Data,
155 ValueHandle LHS,
156 ValueHandle RHS) {
157 SourceLocation Loc = Data->Loc.acquire();
158 if (Loc.isDisabled())
159 return;
161 Value LHSVal(Data->LHSType, LHS);
162 Value RHSVal(Data->RHSType, RHS);
163 if (RHSVal.isNegative())
164 Diag(Loc, DL_Error, "shift exponent %0 is negative") << RHSVal;
165 else if (RHSVal.getPositiveIntValue() >= Data->LHSType.getIntegerBitWidth())
166 Diag(Loc, DL_Error,
167 "shift exponent %0 is too large for %1-bit type %2")
168 << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType;
169 else if (LHSVal.isNegative())
170 Diag(Loc, DL_Error, "left shift of negative value %0") << LHSVal;
171 else
172 Diag(Loc, DL_Error,
173 "left shift of %0 by %1 places cannot be represented in type %2")
174 << LHSVal << RHSVal << Data->LHSType;
176 void __ubsan::__ubsan_handle_shift_out_of_bounds_abort(
177 ShiftOutOfBoundsData *Data,
178 ValueHandle LHS,
179 ValueHandle RHS) {
180 __ubsan_handle_shift_out_of_bounds(Data, LHS, RHS);
181 Die();
184 void __ubsan::__ubsan_handle_out_of_bounds(OutOfBoundsData *Data,
185 ValueHandle Index) {
186 SourceLocation Loc = Data->Loc.acquire();
187 if (Loc.isDisabled())
188 return;
190 Value IndexVal(Data->IndexType, Index);
191 Diag(Loc, DL_Error, "index %0 out of bounds for type %1")
192 << IndexVal << Data->ArrayType;
194 void __ubsan::__ubsan_handle_out_of_bounds_abort(OutOfBoundsData *Data,
195 ValueHandle Index) {
196 __ubsan_handle_out_of_bounds(Data, Index);
197 Die();
200 void __ubsan::__ubsan_handle_builtin_unreachable(UnreachableData *Data) {
201 Diag(Data->Loc, DL_Error, "execution reached a __builtin_unreachable() call");
202 Die();
205 void __ubsan::__ubsan_handle_missing_return(UnreachableData *Data) {
206 Diag(Data->Loc, DL_Error,
207 "execution reached the end of a value-returning function "
208 "without returning a value");
209 Die();
212 void __ubsan::__ubsan_handle_vla_bound_not_positive(VLABoundData *Data,
213 ValueHandle Bound) {
214 SourceLocation Loc = Data->Loc.acquire();
215 if (Loc.isDisabled())
216 return;
218 Diag(Loc, DL_Error, "variable length array bound evaluates to "
219 "non-positive value %0")
220 << Value(Data->Type, Bound);
222 void __ubsan::__ubsan_handle_vla_bound_not_positive_abort(VLABoundData *Data,
223 ValueHandle Bound) {
224 __ubsan_handle_vla_bound_not_positive(Data, Bound);
225 Die();
229 void __ubsan::__ubsan_handle_float_cast_overflow(FloatCastOverflowData *Data,
230 ValueHandle From) {
231 // TODO: Add deduplication once a SourceLocation is generated for this check.
232 Diag(getCallerLocation(), DL_Error,
233 "value %0 is outside the range of representable values of type %2")
234 << Value(Data->FromType, From) << Data->FromType << Data->ToType;
236 void __ubsan::__ubsan_handle_float_cast_overflow_abort(
237 FloatCastOverflowData *Data,
238 ValueHandle From) {
239 Diag(getCallerLocation(), DL_Error,
240 "value %0 is outside the range of representable values of type %2")
241 << Value(Data->FromType, From) << Data->FromType << Data->ToType;
242 Die();
245 void __ubsan::__ubsan_handle_load_invalid_value(InvalidValueData *Data,
246 ValueHandle Val) {
247 SourceLocation Loc = Data->Loc.acquire();
248 if (Loc.isDisabled())
249 return;
251 Diag(Loc, DL_Error,
252 "load of value %0, which is not a valid value for type %1")
253 << Value(Data->Type, Val) << Data->Type;
255 void __ubsan::__ubsan_handle_load_invalid_value_abort(InvalidValueData *Data,
256 ValueHandle Val) {
257 __ubsan_handle_load_invalid_value(Data, Val);
258 Die();
261 void __ubsan::__ubsan_handle_function_type_mismatch(
262 FunctionTypeMismatchData *Data,
263 ValueHandle Function) {
264 const char *FName = "(unknown)";
266 Location Loc = getFunctionLocation(Function, &FName);
268 Diag(Data->Loc, DL_Error,
269 "call to function %0 through pointer to incorrect function type %1")
270 << FName << Data->Type;
271 Diag(Loc, DL_Note, "%0 defined here") << FName;
274 void __ubsan::__ubsan_handle_function_type_mismatch_abort(
275 FunctionTypeMismatchData *Data,
276 ValueHandle Function) {
277 __ubsan_handle_function_type_mismatch(Data, Function);
278 Die();