[UBSan] Always calculate ErrorType (kind of UB) before printing a report.

Currently, this is an NFC. However, knowing out the kind of error
report before we bring up all the reporting machinery (implemented in
ScopedReport class) is important once we teach UBSan runtime
suppressions.

llvm-svn: 255074
This commit is contained in:
Alexey Samsonov 2015-12-08 23:29:33 +00:00
parent 48945cdc15
commit 46442df8de
2 changed files with 65 additions and 42 deletions

View File

@ -238,9 +238,7 @@ class ScopedReport {
ErrorType Type; ErrorType Type;
public: public:
ScopedReport(ReportOptions Opts, Location SummaryLoc, ScopedReport(ReportOptions Opts, Location SummaryLoc, ErrorType Type);
ErrorType Type = ErrorType::GenericUB);
void setErrorType(ErrorType T) { Type = T; }
~ScopedReport(); ~ScopedReport();
}; };

View File

@ -51,24 +51,36 @@ static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,
Loc = FallbackLoc; Loc = FallbackLoc;
} }
ScopedReport R(Opts, Loc); ErrorType ET;
if (!Pointer)
ET = ErrorType::NullPointerUse;
else if (Data->Alignment && (Pointer & (Data->Alignment - 1)))
ET = ErrorType::MisalignedPointerUse;
else
ET = ErrorType::InsufficientObjectSize;
if (!Pointer) { ScopedReport R(Opts, Loc, ET);
R.setErrorType(ErrorType::NullPointerUse);
switch (ET) {
case ErrorType::NullPointerUse:
Diag(Loc, DL_Error, "%0 null pointer of type %1") Diag(Loc, DL_Error, "%0 null pointer of type %1")
<< TypeCheckKinds[Data->TypeCheckKind] << Data->Type; << TypeCheckKinds[Data->TypeCheckKind] << Data->Type;
} else if (Data->Alignment && (Pointer & (Data->Alignment - 1))) { break;
R.setErrorType(ErrorType::MisalignedPointerUse); case ErrorType::MisalignedPointerUse:
Diag(Loc, DL_Error, "%0 misaligned address %1 for type %3, " Diag(Loc, DL_Error, "%0 misaligned address %1 for type %3, "
"which requires %2 byte alignment") "which requires %2 byte alignment")
<< TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer
<< Data->Alignment << Data->Type; << Data->Alignment << Data->Type;
} else { break;
R.setErrorType(ErrorType::InsufficientObjectSize); case ErrorType::InsufficientObjectSize:
Diag(Loc, DL_Error, "%0 address %1 with insufficient space " Diag(Loc, DL_Error, "%0 address %1 with insufficient space "
"for an object of type %2") "for an object of type %2")
<< TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type; << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer << Data->Type;
break;
default:
UNREACHABLE("unexpected error type!");
} }
if (Pointer) if (Pointer)
Diag(Pointer, DL_Note, "pointer points here"); Diag(Pointer, DL_Note, "pointer points here");
} }
@ -157,19 +169,27 @@ static void handleDivremOverflowImpl(OverflowData *Data, ValueHandle LHS,
if (ignoreReport(Loc, Opts)) if (ignoreReport(Loc, Opts))
return; return;
ScopedReport R(Opts, Loc);
Value LHSVal(Data->Type, LHS); Value LHSVal(Data->Type, LHS);
Value RHSVal(Data->Type, RHS); Value RHSVal(Data->Type, RHS);
if (RHSVal.isMinusOne()) {
R.setErrorType(ErrorType::SignedIntegerOverflow); ErrorType ET;
Diag(Loc, DL_Error, if (RHSVal.isMinusOne())
"division of %0 by -1 cannot be represented in type %1") ET = ErrorType::SignedIntegerOverflow;
<< LHSVal << Data->Type; else if (Data->Type.isIntegerTy())
} else { ET = ErrorType::IntegerDivideByZero;
R.setErrorType(Data->Type.isIntegerTy() ? ErrorType::IntegerDivideByZero else
: ErrorType::FloatDivideByZero); ET = ErrorType::FloatDivideByZero;
ScopedReport R(Opts, Loc, ET);
switch (ET) {
case ErrorType::SignedIntegerOverflow:
Diag(Loc, DL_Error, "division of %0 by -1 cannot be represented in type %1")
<< LHSVal << Data->Type;
break;
default:
Diag(Loc, DL_Error, "division by zero"); Diag(Loc, DL_Error, "division by zero");
break;
} }
} }
@ -193,26 +213,31 @@ static void handleShiftOutOfBoundsImpl(ShiftOutOfBoundsData *Data,
if (ignoreReport(Loc, Opts)) if (ignoreReport(Loc, Opts))
return; return;
ScopedReport R(Opts, Loc);
Value LHSVal(Data->LHSType, LHS); Value LHSVal(Data->LHSType, LHS);
Value RHSVal(Data->RHSType, RHS); Value RHSVal(Data->RHSType, RHS);
if (RHSVal.isNegative()) {
R.setErrorType(ErrorType::InvalidShiftExponent); ErrorType ET;
Diag(Loc, DL_Error, "shift exponent %0 is negative") << RHSVal; if (RHSVal.isNegative() ||
} else if (RHSVal.getPositiveIntValue() >= RHSVal.getPositiveIntValue() >= Data->LHSType.getIntegerBitWidth())
Data->LHSType.getIntegerBitWidth()) { ET = ErrorType::InvalidShiftExponent;
R.setErrorType(ErrorType::InvalidShiftExponent); else
Diag(Loc, DL_Error, "shift exponent %0 is too large for %1-bit type %2") ET = ErrorType::InvalidShiftBase;
<< RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType;
} else if (LHSVal.isNegative()) { ScopedReport R(Opts, Loc, ET);
R.setErrorType(ErrorType::InvalidShiftBase);
Diag(Loc, DL_Error, "left shift of negative value %0") << LHSVal; if (ET == ErrorType::InvalidShiftExponent) {
if (RHSVal.isNegative())
Diag(Loc, DL_Error, "shift exponent %0 is negative") << RHSVal;
else
Diag(Loc, DL_Error, "shift exponent %0 is too large for %1-bit type %2")
<< RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType;
} else { } else {
R.setErrorType(ErrorType::InvalidShiftBase); if (LHSVal.isNegative())
Diag(Loc, DL_Error, Diag(Loc, DL_Error, "left shift of negative value %0") << LHSVal;
"left shift of %0 by %1 places cannot be represented in type %2") else
<< LHSVal << RHSVal << Data->LHSType; Diag(Loc, DL_Error,
"left shift of %0 by %1 places cannot be represented in type %2")
<< LHSVal << RHSVal << Data->LHSType;
} }
} }
@ -481,7 +506,7 @@ static void handleCFIBadIcall(CFIBadIcallData *Data, ValueHandle Function,
if (ignoreReport(Loc, Opts)) if (ignoreReport(Loc, Opts))
return; return;
ScopedReport R(Opts, Loc); ScopedReport R(Opts, Loc, ErrorType::CFIBadType);
Diag(Loc, DL_Error, "control flow integrity check for type %0 failed during " Diag(Loc, DL_Error, "control flow integrity check for type %0 failed during "
"indirect function call") "indirect function call")