ubsan_handlers.cc revision eda8bd0fc07df35c9ad7de5b698bb717b063e7af
1//===-- ubsan_handlers.cc -------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Error logging entry points for the UBSan runtime. 11// 12//===----------------------------------------------------------------------===// 13 14#include "ubsan_handlers.h" 15#include "ubsan_diag.h" 16 17#include "sanitizer_common/sanitizer_common.h" 18 19using namespace __sanitizer; 20using namespace __ubsan; 21 22NORETURN void __sanitizer::Die() { 23 __builtin_trap(); 24} 25 26NORETURN void __sanitizer::CheckFailed(const char *File, int Line, 27 const char *Cond, u64 V1, u64 V2) { 28 Diag(SourceLocation(File, Line, 0), 29 "CHECK failed: %0 (with values %1 and %2)") 30 << Cond << V1 << V2; 31 Die(); 32} 33 34namespace __ubsan { 35 const char *TypeCheckKinds[] = { 36 "load of", "store to", "reference binding to", "member access within", 37 "member call on", "constructor call on" 38 }; 39} 40 41void __ubsan::__ubsan_handle_type_mismatch(TypeMismatchData *Data, 42 ValueHandle Pointer) { 43 if (!Pointer) 44 Diag(Data->Loc, "%0 null pointer of type %1") 45 << TypeCheckKinds[Data->TypeCheckKind] << Data->Type; 46 else if (Data->Alignment && (Pointer & (Data->Alignment - 1))) 47 Diag(Data->Loc, "%0 misaligned address %1 for type %3, " 48 "which requires %2 byte alignment") 49 << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer 50 << Data->Alignment << Data->Type; 51 else 52 Diag(Data->Loc, "%0 address %1 with insufficient space " 53 "for an object of type %2") 54 << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type; 55 Die(); 56} 57 58/// \brief Common diagnostic emission for various forms of signed overflow. 59template<typename T> static void HandleSignedOverflow(OverflowData *Data, 60 ValueHandle LHS, 61 const char *Operator, 62 T RHS) { 63 Diag(Data->Loc, "signed integer overflow: " 64 "%0 %1 %2 cannot be represented in type %3") 65 << Value(Data->Type, LHS) << Operator << RHS << Data->Type; 66 Die(); 67} 68 69void __ubsan::__ubsan_handle_add_overflow(OverflowData *Data, 70 ValueHandle LHS, ValueHandle RHS) { 71 HandleSignedOverflow(Data, LHS, "+", Value(Data->Type, RHS)); 72} 73 74void __ubsan::__ubsan_handle_sub_overflow(OverflowData *Data, 75 ValueHandle LHS, ValueHandle RHS) { 76 HandleSignedOverflow(Data, LHS, "-", Value(Data->Type, RHS)); 77} 78 79void __ubsan::__ubsan_handle_mul_overflow(OverflowData *Data, 80 ValueHandle LHS, ValueHandle RHS) { 81 HandleSignedOverflow(Data, LHS, "*", Value(Data->Type, RHS)); 82} 83 84void __ubsan::__ubsan_handle_negate_overflow(OverflowData *Data, 85 ValueHandle OldVal) { 86 Diag(Data->Loc, "negation of %0 cannot be represented in type %1; " 87 "cast to an unsigned type to negate this value to itself") 88 << Value(Data->Type, OldVal) << Data->Type; 89 Die(); 90} 91 92void __ubsan::__ubsan_handle_divrem_overflow(OverflowData *Data, 93 ValueHandle LHS, ValueHandle RHS) { 94 Value LHSVal(Data->Type, LHS); 95 Value RHSVal(Data->Type, RHS); 96 if (RHSVal.isMinusOne()) 97 Diag(Data->Loc, "division of %0 by -1 cannot be represented in type %1") 98 << LHSVal << Data->Type; 99 else 100 Diag(Data->Loc, "division by zero"); 101 Die(); 102} 103 104void __ubsan::__ubsan_handle_shift_out_of_bounds(ShiftOutOfBoundsData *Data, 105 ValueHandle LHS, 106 ValueHandle RHS) { 107 Value LHSVal(Data->LHSType, LHS); 108 Value RHSVal(Data->RHSType, RHS); 109 if (RHSVal.isNegative()) 110 Diag(Data->Loc, "shift exponent %0 is negative") << RHSVal; 111 else if (RHSVal.getPositiveIntValue() >= Data->LHSType.getIntegerBitWidth()) 112 Diag(Data->Loc, "shift exponent %0 is too large for %1-bit type %2") 113 << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType; 114 else if (LHSVal.isNegative()) 115 Diag(Data->Loc, "left shift of negative value %0") << LHSVal; 116 else 117 Diag(Data->Loc, "left shift of %0 by %1 places cannot be represented " 118 "in type %2") << LHSVal << RHSVal << Data->LHSType; 119 Die(); 120} 121 122void __ubsan::__ubsan_handle_builtin_unreachable(UnreachableData *Data) { 123 Diag(Data->Loc, "execution reached a __builtin_unreachable() call"); 124 Die(); 125} 126 127void __ubsan::__ubsan_handle_missing_return(UnreachableData *Data) { 128 Diag(Data->Loc, "execution reached the end of a value-returning function " 129 "without returning a value"); 130 Die(); 131} 132 133void __ubsan::__ubsan_handle_vla_bound_not_positive(VLABoundData *Data, 134 ValueHandle Bound) { 135 Diag(Data->Loc, "variable length array bound evaluates to " 136 "non-positive value %0") 137 << Value(Data->Type, Bound); 138 Die(); 139} 140 141void __ubsan::__ubsan_handle_float_cast_overflow(FloatCastOverflowData *Data, 142 ValueHandle From) { 143 Diag(SourceLocation(), "value %0 is outside the range of representable " 144 "values of type %2") 145 << Value(Data->FromType, From) << Data->FromType << Data->ToType; 146 Die(); 147} 148