summaryrefslogtreecommitdiff
path: root/lib/ubsan/ubsan_handlers.cc
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2015-08-24 23:18:49 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2015-08-24 23:18:49 +0000
commitaef60033031849c68092f304d04bf609b3c269ff (patch)
treeaff383ccd60e135ca8ef2b5879fc6cd315006395 /lib/ubsan/ubsan_handlers.cc
parentb1900f9b3f936a8f84cd42d1aabd899613f32137 (diff)
[UBSan] Add the ability to print more precise error kind in summary line.
Reviewers: rsmith, pcc Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D12215 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@245897 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ubsan/ubsan_handlers.cc')
-rw-r--r--lib/ubsan/ubsan_handlers.cc80
1 files changed, 50 insertions, 30 deletions
diff --git a/lib/ubsan/ubsan_handlers.cc b/lib/ubsan/ubsan_handlers.cc
index 1e8fee355..c175baa46 100644
--- a/lib/ubsan/ubsan_handlers.cc
+++ b/lib/ubsan/ubsan_handlers.cc
@@ -53,18 +53,22 @@ static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,
ScopedReport R(Opts, Loc);
- if (!Pointer)
+ if (!Pointer) {
+ R.setErrorType(ErrorType::NullPointerUse);
Diag(Loc, DL_Error, "%0 null pointer of type %1")
<< TypeCheckKinds[Data->TypeCheckKind] << Data->Type;
- else if (Data->Alignment && (Pointer & (Data->Alignment - 1)))
+ } else if (Data->Alignment && (Pointer & (Data->Alignment - 1))) {
+ R.setErrorType(ErrorType::MisalignedPointerUse);
Diag(Loc, DL_Error, "%0 misaligned address %1 for type %3, "
"which requires %2 byte alignment")
<< TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer
<< Data->Alignment << Data->Type;
- else
+ } else {
+ R.setErrorType(ErrorType::InsufficientObjectSize);
Diag(Loc, DL_Error, "%0 address %1 with insufficient space "
"for an object of type %2")
<< TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
+ }
if (Pointer)
Diag(Pointer, DL_Note, "pointer points here");
}
@@ -90,11 +94,13 @@ static void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts, Loc);
+ bool IsSigned = Data->Type.isSignedIntegerTy();
+ ScopedReport R(Opts, Loc, IsSigned ? ErrorType::SignedIntegerOverflow
+ : ErrorType::UnsignedIntegerOverflow);
Diag(Loc, DL_Error, "%0 integer overflow: "
"%1 %2 %3 cannot be represented in type %4")
- << (Data->Type.isSignedIntegerTy() ? "signed" : "unsigned")
+ << (IsSigned ? "signed" : "unsigned")
<< Value(Data->Type, LHS) << Operator << RHS << Data->Type;
}
@@ -119,17 +125,18 @@ static void handleNegateOverflowImpl(OverflowData *Data, ValueHandle OldVal,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts, Loc);
+ bool IsSigned = Data->Type.isSignedIntegerTy();
+ ScopedReport R(Opts, Loc, IsSigned ? ErrorType::SignedIntegerOverflow
+ : ErrorType::UnsignedIntegerOverflow);
- if (Data->Type.isSignedIntegerTy())
+ if (IsSigned)
Diag(Loc, DL_Error,
"negation of %0 cannot be represented in type %1; "
"cast to an unsigned type to negate this value to itself")
- << Value(Data->Type, OldVal) << Data->Type;
+ << Value(Data->Type, OldVal) << Data->Type;
else
- Diag(Loc, DL_Error,
- "negation of %0 cannot be represented in type %1")
- << Value(Data->Type, OldVal) << Data->Type;
+ Diag(Loc, DL_Error, "negation of %0 cannot be represented in type %1")
+ << Value(Data->Type, OldVal) << Data->Type;
}
void __ubsan::__ubsan_handle_negate_overflow(OverflowData *Data,
@@ -154,12 +161,16 @@ static void handleDivremOverflowImpl(OverflowData *Data, ValueHandle LHS,
Value LHSVal(Data->Type, LHS);
Value RHSVal(Data->Type, RHS);
- if (RHSVal.isMinusOne())
+ if (RHSVal.isMinusOne()) {
+ R.setErrorType(ErrorType::SignedIntegerOverflow);
Diag(Loc, DL_Error,
"division of %0 by -1 cannot be represented in type %1")
<< LHSVal << Data->Type;
- else
+ } else {
+ R.setErrorType(Data->Type.isIntegerTy() ? ErrorType::IntegerDivideByZero
+ : ErrorType::FloatDivideByZero);
Diag(Loc, DL_Error, "division by zero");
+ }
}
void __ubsan::__ubsan_handle_divrem_overflow(OverflowData *Data,
@@ -186,18 +197,23 @@ static void handleShiftOutOfBoundsImpl(ShiftOutOfBoundsData *Data,
Value LHSVal(Data->LHSType, LHS);
Value RHSVal(Data->RHSType, RHS);
- if (RHSVal.isNegative())
+ if (RHSVal.isNegative()) {
+ R.setErrorType(ErrorType::InvalidShiftExponent);
Diag(Loc, DL_Error, "shift exponent %0 is negative") << RHSVal;
- else if (RHSVal.getPositiveIntValue() >= Data->LHSType.getIntegerBitWidth())
- Diag(Loc, DL_Error,
- "shift exponent %0 is too large for %1-bit type %2")
- << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType;
- else if (LHSVal.isNegative())
+ } else if (RHSVal.getPositiveIntValue() >=
+ Data->LHSType.getIntegerBitWidth()) {
+ R.setErrorType(ErrorType::InvalidShiftExponent);
+ Diag(Loc, DL_Error, "shift exponent %0 is too large for %1-bit type %2")
+ << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType;
+ } else if (LHSVal.isNegative()) {
+ R.setErrorType(ErrorType::InvalidShiftBase);
Diag(Loc, DL_Error, "left shift of negative value %0") << LHSVal;
- else
+ } else {
+ R.setErrorType(ErrorType::InvalidShiftBase);
Diag(Loc, DL_Error,
"left shift of %0 by %1 places cannot be represented in type %2")
- << LHSVal << RHSVal << Data->LHSType;
+ << LHSVal << RHSVal << Data->LHSType;
+ }
}
void __ubsan::__ubsan_handle_shift_out_of_bounds(ShiftOutOfBoundsData *Data,
@@ -221,7 +237,7 @@ static void handleOutOfBoundsImpl(OutOfBoundsData *Data, ValueHandle Index,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts, Loc);
+ ScopedReport R(Opts, Loc, ErrorType::OutOfBoundsIndex);
Value IndexVal(Data->IndexType, Index);
Diag(Loc, DL_Error, "index %0 out of bounds for type %1")
@@ -242,7 +258,7 @@ void __ubsan::__ubsan_handle_out_of_bounds_abort(OutOfBoundsData *Data,
static void handleBuiltinUnreachableImpl(UnreachableData *Data,
ReportOptions Opts) {
- ScopedReport R(Opts, Data->Loc);
+ ScopedReport R(Opts, Data->Loc, ErrorType::UnreachableCall);
Diag(Data->Loc, DL_Error, "execution reached a __builtin_unreachable() call");
}
@@ -253,7 +269,7 @@ void __ubsan::__ubsan_handle_builtin_unreachable(UnreachableData *Data) {
}
static void handleMissingReturnImpl(UnreachableData *Data, ReportOptions Opts) {
- ScopedReport R(Opts, Data->Loc);
+ ScopedReport R(Opts, Data->Loc, ErrorType::MissingReturn);
Diag(Data->Loc, DL_Error,
"execution reached the end of a value-returning function "
"without returning a value");
@@ -271,7 +287,7 @@ static void handleVLABoundNotPositive(VLABoundData *Data, ValueHandle Bound,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts, Loc);
+ ScopedReport R(Opts, Loc, ErrorType::NonPositiveVLAIndex);
Diag(Loc, DL_Error, "variable length array bound evaluates to "
"non-positive value %0")
@@ -328,7 +344,7 @@ static void handleFloatCastOverflow(void *DataPtr, ValueHandle From,
ToType = &Data->ToType;
}
- ScopedReport R(Opts, Loc);
+ ScopedReport R(Opts, Loc, ErrorType::FloatCastOverflow);
Diag(Loc, DL_Error,
"value %0 is outside the range of representable values of type %2")
@@ -352,7 +368,11 @@ static void handleLoadInvalidValue(InvalidValueData *Data, ValueHandle Val,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts, Loc);
+ // This check could be more precise if we used different handlers for
+ // -fsanitize=bool and -fsanitize=enum.
+ bool IsBool = (0 == internal_strcmp(Data->Type.getTypeName(), "'bool'"));
+ ScopedReport R(Opts, Loc, IsBool ? ErrorType::InvalidBoolLoad
+ : ErrorType::InvalidEnumLoad);
Diag(Loc, DL_Error,
"load of value %0, which is not a valid value for type %1")
@@ -378,7 +398,7 @@ static void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
if (ignoreReport(CallLoc, Opts))
return;
- ScopedReport R(Opts, CallLoc);
+ ScopedReport R(Opts, CallLoc, ErrorType::FunctionTypeMismatch);
SymbolizedStackHolder FLoc(getSymbolizedLocation(Function));
const char *FName = FLoc.get()->info.function;
@@ -410,7 +430,7 @@ static void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts) {
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts, Loc);
+ ScopedReport R(Opts, Loc, ErrorType::InvalidNullReturn);
Diag(Loc, DL_Error, "null pointer returned from function declared to never "
"return null");
@@ -434,7 +454,7 @@ static void handleNonNullArg(NonNullArgData *Data, ReportOptions Opts) {
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts, Loc);
+ ScopedReport R(Opts, Loc, ErrorType::InvalidNullArgument);
Diag(Loc, DL_Error, "null pointer passed as argument %0, which is declared to "
"never be null") << Data->ArgIndex;