1eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith//===-- ubsan_handlers.cc -------------------------------------------------===// 26ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 36ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// The LLVM Compiler Infrastructure 46ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 56ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// This file is distributed under the University of Illinois Open Source 66ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// License. See LICENSE.TXT for details. 76ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 86ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith//===----------------------------------------------------------------------===// 96ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 106ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// Error logging entry points for the UBSan runtime. 116ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 126ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith//===----------------------------------------------------------------------===// 136ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 147c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar#include "ubsan_platform.h" 157c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar#if CAN_SANITIZE_UB 166ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#include "ubsan_handlers.h" 176ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#include "ubsan_diag.h" 186ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 196ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#include "sanitizer_common/sanitizer_common.h" 206ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 216ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithusing namespace __sanitizer; 226ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithusing namespace __ubsan; 236ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 24799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarnamespace __ubsan { 25799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarbool ignoreReport(SourceLocation SLoc, ReportOptions Opts, ErrorType ET) { 26799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // We are not allowed to skip error report: if we are in unrecoverable 27799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // handler, we have to terminate the program right now, and therefore 28799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // have to print some diagnostic. 29799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // 30799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // Even if source location is disabled, it doesn't mean that we have 31799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // already report an error to the user: some concurrently running 32799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // thread could have acquired it, but not yet printed the report. 33799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (Opts.FromUnrecoverableHandler) 34799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return false; 35799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return SLoc.isDisabled() || IsPCSuppressed(ET, Opts.pc, SLoc.getFilename()); 366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 386d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesconst char *TypeCheckKinds[] = { 396ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith "load of", "store to", "reference binding to", "member access within", 406d1862363c88c183b0ed7740fca876342cf0474bStephen Hines "member call on", "constructor call on", "downcast of", "downcast of", 416d1862363c88c183b0ed7740fca876342cf0474bStephen Hines "upcast of", "cast to virtual base of"}; 42eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith} 43eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith 445f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smithstatic void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer, 4586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ReportOptions Opts) { 462af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Location Loc = Data->Loc.acquire(); 47799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 48799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET; 49799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (!Pointer) 50799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ET = ErrorType::NullPointerUse; 51799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar else if (Data->Alignment && (Pointer & (Data->Alignment - 1))) 52799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ET = ErrorType::MisalignedPointerUse; 53799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar else 54799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ET = ErrorType::InsufficientObjectSize; 55799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 56799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // Use the SourceLocation from Data to track deduplication, even if it's 57799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // invalid. 58799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(Loc.getSourceLocation(), Opts, ET)) 592af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 606d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 6186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SymbolizedStackHolder FallbackLoc; 6286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Data->Loc.isInvalid()) { 6386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines FallbackLoc.reset(getCallerLocation(Opts.pc)); 645f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith Loc = FallbackLoc; 6586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 665f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith 67799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 686d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 69799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar switch (ET) { 70799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar case ErrorType::NullPointerUse: 7125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Loc, DL_Error, "%0 null pointer of type %1") 72799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << TypeCheckKinds[Data->TypeCheckKind] << Data->Type; 73799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar break; 74799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar case ErrorType::MisalignedPointerUse: 7525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Loc, DL_Error, "%0 misaligned address %1 for type %3, " 7625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "which requires %2 byte alignment") 77799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer 78799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << Data->Alignment << Data->Type; 79799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar break; 80799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar case ErrorType::InsufficientObjectSize: 8125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Loc, DL_Error, "%0 address %1 with insufficient space " 8225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "for an object of type %2") 83799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer << Data->Type; 84799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar break; 85799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar default: 86799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar UNREACHABLE("unexpected error type!"); 87799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar } 88799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 8925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (Pointer) 9025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Pointer, DL_Note, "pointer points here"); 91a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 926d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 935f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smithvoid __ubsan::__ubsan_handle_type_mismatch(TypeMismatchData *Data, 945f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith ValueHandle Pointer) { 956d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 9686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines handleTypeMismatchImpl(Data, Pointer, Opts); 975f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith} 98a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_type_mismatch_abort(TypeMismatchData *Data, 995f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith ValueHandle Pointer) { 1006d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 10186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines handleTypeMismatchImpl(Data, Pointer, Opts); 1026ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 1036ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 1046ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 10580af605afd0e92a2a128c81898f647207f384e08Will Dietz/// \brief Common diagnostic emission for various forms of integer overflow. 1066d1862363c88c183b0ed7740fca876342cf0474bStephen Hinestemplate <typename T> 1076d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS, 1086d1862363c88c183b0ed7740fca876342cf0474bStephen Hines const char *Operator, T RHS, 1096d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 1102af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation Loc = Data->Loc.acquire(); 111799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar bool IsSigned = Data->Type.isSignedIntegerTy(); 112799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET = IsSigned ? ErrorType::SignedIntegerOverflow 113799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar : ErrorType::UnsignedIntegerOverflow; 114799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 115799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 1162af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 1172af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 118799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 1196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 1202af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, "%0 integer overflow: " 1212af552f98f980178db37eed28a609b6bf55f6df8Will Dietz "%1 %2 %3 cannot be represented in type %4") 122799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << (IsSigned ? "signed" : "unsigned") 1236ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith << Value(Data->Type, LHS) << Operator << RHS << Data->Type; 1246ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 1256ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 126799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#define UBSAN_OVERFLOW_HANDLER(handler_name, op, unrecoverable) \ 1276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines void __ubsan::handler_name(OverflowData *Data, ValueHandle LHS, \ 1286d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle RHS) { \ 129799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar GET_REPORT_OPTIONS(unrecoverable); \ 1306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleIntegerOverflowImpl(Data, LHS, op, Value(Data->Type, RHS), Opts); \ 131799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (unrecoverable) \ 132799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Die(); \ 1336d1862363c88c183b0ed7740fca876342cf0474bStephen Hines } 1346d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 1356d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_add_overflow, "+", false) 1366d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_add_overflow_abort, "+", true) 1376d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_sub_overflow, "-", false) 1386d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_sub_overflow_abort, "-", true) 1396d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_mul_overflow, "*", false) 1406d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_mul_overflow_abort, "*", true) 1416d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 1426d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleNegateOverflowImpl(OverflowData *Data, ValueHandle OldVal, 1436d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 1442af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation Loc = Data->Loc.acquire(); 145799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar bool IsSigned = Data->Type.isSignedIntegerTy(); 146799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET = IsSigned ? ErrorType::SignedIntegerOverflow 147799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar : ErrorType::UnsignedIntegerOverflow; 148799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 149799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 1502af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 1512af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 152799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 1536d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 154799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (IsSigned) 1552af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, 156f359dea95de4a17287d11052e9b552100c152287Will Dietz "negation of %0 cannot be represented in type %1; " 157f359dea95de4a17287d11052e9b552100c152287Will Dietz "cast to an unsigned type to negate this value to itself") 158799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << Value(Data->Type, OldVal) << Data->Type; 159f359dea95de4a17287d11052e9b552100c152287Will Dietz else 160799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Diag(Loc, DL_Error, "negation of %0 cannot be represented in type %1") 161799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << Value(Data->Type, OldVal) << Data->Type; 162a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 1636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 1646d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_negate_overflow(OverflowData *Data, 1656d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle OldVal) { 1666d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 1676d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNegateOverflowImpl(Data, OldVal, Opts); 1686d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 169a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_negate_overflow_abort(OverflowData *Data, 170a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ValueHandle OldVal) { 1716d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 1726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNegateOverflowImpl(Data, OldVal, Opts); 1736ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 1746ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 1756ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1766d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleDivremOverflowImpl(OverflowData *Data, ValueHandle LHS, 1776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle RHS, ReportOptions Opts) { 1782af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation Loc = Data->Loc.acquire(); 1796ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Value LHSVal(Data->Type, LHS); 1806ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Value RHSVal(Data->Type, RHS); 181799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 182799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET; 1836ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith if (RHSVal.isMinusOne()) 184799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ET = ErrorType::SignedIntegerOverflow; 185799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar else if (Data->Type.isIntegerTy()) 186799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ET = ErrorType::IntegerDivideByZero; 1876ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else 188799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ET = ErrorType::FloatDivideByZero; 189799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 190799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 191799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return; 192799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 193799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 194799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 195799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar switch (ET) { 196799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar case ErrorType::SignedIntegerOverflow: 197799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Diag(Loc, DL_Error, "division of %0 by -1 cannot be represented in type %1") 198799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << LHSVal << Data->Type; 199799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar break; 200799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar default: 2012af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, "division by zero"); 202799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar break; 203799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar } 204a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 2056d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 2066d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_divrem_overflow(OverflowData *Data, 2076d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle LHS, ValueHandle RHS) { 2086d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 2096d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleDivremOverflowImpl(Data, LHS, RHS, Opts); 2106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 211a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_divrem_overflow_abort(OverflowData *Data, 212a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ValueHandle LHS, 213a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ValueHandle RHS) { 2146d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 2156d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleDivremOverflowImpl(Data, LHS, RHS, Opts); 2166ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 2176ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 2186ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 2196d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleShiftOutOfBoundsImpl(ShiftOutOfBoundsData *Data, 2206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle LHS, ValueHandle RHS, 2216d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 2222af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation Loc = Data->Loc.acquire(); 2236ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Value LHSVal(Data->LHSType, LHS); 2246ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Value RHSVal(Data->RHSType, RHS); 225799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 226799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET; 227799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (RHSVal.isNegative() || 228799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar RHSVal.getPositiveIntValue() >= Data->LHSType.getIntegerBitWidth()) 229799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ET = ErrorType::InvalidShiftExponent; 2306ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else 231799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ET = ErrorType::InvalidShiftBase; 232799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 233799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 234799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return; 235799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 236799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 237799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 238799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ET == ErrorType::InvalidShiftExponent) { 239799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (RHSVal.isNegative()) 240799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Diag(Loc, DL_Error, "shift exponent %0 is negative") << RHSVal; 241799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar else 242799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Diag(Loc, DL_Error, "shift exponent %0 is too large for %1-bit type %2") 243799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType; 244799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar } else { 245799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (LHSVal.isNegative()) 246799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Diag(Loc, DL_Error, "left shift of negative value %0") << LHSVal; 247799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar else 248799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Diag(Loc, DL_Error, 249799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar "left shift of %0 by %1 places cannot be represented in type %2") 250799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << LHSVal << RHSVal << Data->LHSType; 251799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar } 252a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 2536d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 2546d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_shift_out_of_bounds(ShiftOutOfBoundsData *Data, 2556d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle LHS, 2566d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle RHS) { 2576d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 2586d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleShiftOutOfBoundsImpl(Data, LHS, RHS, Opts); 2596d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 260a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_shift_out_of_bounds_abort( 261a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ShiftOutOfBoundsData *Data, 262a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ValueHandle LHS, 263a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ValueHandle RHS) { 2646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 2656d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleShiftOutOfBoundsImpl(Data, LHS, RHS, Opts); 2666ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 2676ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 2686ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 2696d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleOutOfBoundsImpl(OutOfBoundsData *Data, ValueHandle Index, 2706d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 271a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith SourceLocation Loc = Data->Loc.acquire(); 272799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET = ErrorType::OutOfBoundsIndex; 273799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 274799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 275a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith return; 276a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith 277799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 2786d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 279a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith Value IndexVal(Data->IndexType, Index); 280a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith Diag(Loc, DL_Error, "index %0 out of bounds for type %1") 281a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith << IndexVal << Data->ArrayType; 282a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith} 2836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 2846d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_out_of_bounds(OutOfBoundsData *Data, 2856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Index) { 2866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 2876d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleOutOfBoundsImpl(Data, Index, Opts); 2886d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 289a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smithvoid __ubsan::__ubsan_handle_out_of_bounds_abort(OutOfBoundsData *Data, 290a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith ValueHandle Index) { 2916d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 2926d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleOutOfBoundsImpl(Data, Index, Opts); 293a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith Die(); 294a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith} 295a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith 2966d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleBuiltinUnreachableImpl(UnreachableData *Data, 2976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 298799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Data->Loc, ErrorType::UnreachableCall); 29925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Data->Loc, DL_Error, "execution reached a __builtin_unreachable() call"); 3006d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 3016d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3026d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_builtin_unreachable(UnreachableData *Data) { 3036d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 3046d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleBuiltinUnreachableImpl(Data, Opts); 3056ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 3066ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 3076ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 3086d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleMissingReturnImpl(UnreachableData *Data, ReportOptions Opts) { 309799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Data->Loc, ErrorType::MissingReturn); 31025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Data->Loc, DL_Error, 31125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "execution reached the end of a value-returning function " 31225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "without returning a value"); 3136d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 3146d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3156d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_missing_return(UnreachableData *Data) { 3166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 3176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleMissingReturnImpl(Data, Opts); 3186ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 3196ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 320b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith 3216d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleVLABoundNotPositive(VLABoundData *Data, ValueHandle Bound, 3226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 3232af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation Loc = Data->Loc.acquire(); 324799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET = ErrorType::NonPositiveVLAIndex; 325799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 326799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 3272af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 3282af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 329799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 3306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3312af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, "variable length array bound evaluates to " 3322af552f98f980178db37eed28a609b6bf55f6df8Will Dietz "non-positive value %0") 333b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith << Value(Data->Type, Bound); 334a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 3356d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3366d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_vla_bound_not_positive(VLABoundData *Data, 3376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Bound) { 3386d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 3396d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleVLABoundNotPositive(Data, Bound, Opts); 3406d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 341a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_vla_bound_not_positive_abort(VLABoundData *Data, 3426d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Bound) { 3436d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 3446d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleVLABoundNotPositive(Data, Bound, Opts); 345b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith Die(); 346b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith} 34758561700a4abad310911a24a867da49a14fae91eRichard Smith 348799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarstatic bool looksLikeFloatCastOverflowDataV1(void *Data) { 349799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // First field is either a pointer to filename or a pointer to a 350799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // TypeDescriptor. 351799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar u8 *FilenameOrTypeDescriptor; 352799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar internal_memcpy(&FilenameOrTypeDescriptor, Data, 353799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar sizeof(FilenameOrTypeDescriptor)); 354799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 355799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // Heuristic: For float_cast_overflow, the TypeKind will be either TK_Integer 356799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // (0x0), TK_Float (0x1) or TK_Unknown (0xff). If both types are known, 357799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // adding both bytes will be 0 or 1 (for BE or LE). If it were a filename, 358799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // adding two printable characters will not yield such a value. Otherwise, 359799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // if one of them is 0xff, this is most likely TK_Unknown type descriptor. 360799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar u16 MaybeFromTypeKind = 361799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar FilenameOrTypeDescriptor[0] + FilenameOrTypeDescriptor[1]; 362799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return MaybeFromTypeKind < 2 || FilenameOrTypeDescriptor[0] == 0xff || 363799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar FilenameOrTypeDescriptor[1] == 0xff; 364799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar} 365799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 366799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarstatic void handleFloatCastOverflow(void *DataPtr, ValueHandle From, 367799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ReportOptions Opts) { 368799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar SymbolizedStackHolder CallerLoc; 369799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Location Loc; 370799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar const TypeDescriptor *FromType, *ToType; 371799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET = ErrorType::FloatCastOverflow; 372799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 373799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (looksLikeFloatCastOverflowDataV1(DataPtr)) { 374799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar auto Data = reinterpret_cast<FloatCastOverflowData *>(DataPtr); 375799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar CallerLoc.reset(getCallerLocation(Opts.pc)); 376799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Loc = CallerLoc; 377799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar FromType = &Data->FromType; 378799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ToType = &Data->ToType; 379799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar } else { 380799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar auto Data = reinterpret_cast<FloatCastOverflowDataV2 *>(DataPtr); 381799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar SourceLocation SLoc = Data->Loc.acquire(); 382799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(SLoc, Opts, ET)) 383799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return; 384799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Loc = SLoc; 385799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar FromType = &Data->FromType; 386799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ToType = &Data->ToType; 387799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar } 388799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 389799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 3906d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3916d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Diag(Loc, DL_Error, 3926d1862363c88c183b0ed7740fca876342cf0474bStephen Hines "value %0 is outside the range of representable values of type %2") 393799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << Value(*FromType, From) << *FromType << *ToType; 3946d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 3955f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith 396799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarvoid __ubsan::__ubsan_handle_float_cast_overflow(void *Data, ValueHandle From) { 3976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 3986d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleFloatCastOverflow(Data, From, Opts); 399a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 400799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarvoid __ubsan::__ubsan_handle_float_cast_overflow_abort(void *Data, 401799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ValueHandle From) { 4026d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 4036d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleFloatCastOverflow(Data, From, Opts); 40458561700a4abad310911a24a867da49a14fae91eRichard Smith Die(); 40558561700a4abad310911a24a867da49a14fae91eRichard Smith} 406f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith 4076d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleLoadInvalidValue(InvalidValueData *Data, ValueHandle Val, 4086d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 409d1bf52ecb1211af7fa3fe5f5b05d08033eb1a90cNick Lewycky SourceLocation Loc = Data->Loc.acquire(); 410799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // This check could be more precise if we used different handlers for 411799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // -fsanitize=bool and -fsanitize=enum. 412799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar bool IsBool = (0 == internal_strcmp(Data->Type.getTypeName(), "'bool'")); 413799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET = 414799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar IsBool ? ErrorType::InvalidBoolLoad : ErrorType::InvalidEnumLoad; 415799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 416799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 417d1bf52ecb1211af7fa3fe5f5b05d08033eb1a90cNick Lewycky return; 418d1bf52ecb1211af7fa3fe5f5b05d08033eb1a90cNick Lewycky 419799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 4206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 421d1bf52ecb1211af7fa3fe5f5b05d08033eb1a90cNick Lewycky Diag(Loc, DL_Error, 42225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "load of value %0, which is not a valid value for type %1") 423f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith << Value(Data->Type, Val) << Data->Type; 424f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith} 4256d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4266d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_load_invalid_value(InvalidValueData *Data, 4276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Val) { 4286d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 4296d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleLoadInvalidValue(Data, Val, Opts); 4306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 431f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smithvoid __ubsan::__ubsan_handle_load_invalid_value_abort(InvalidValueData *Data, 432f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith ValueHandle Val) { 4336d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 4346d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleLoadInvalidValue(Data, Val, Opts); 435f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith Die(); 436f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith} 4379b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne 4386d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data, 4396d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Function, 4406d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 44186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SourceLocation CallLoc = Data->Loc.acquire(); 442799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET = ErrorType::FunctionTypeMismatch; 443799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 444799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(CallLoc, Opts, ET)) 44586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return; 4469b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne 447799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, CallLoc, ET); 4489b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne 44986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SymbolizedStackHolder FLoc(getSymbolizedLocation(Function)); 45086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *FName = FLoc.get()->info.function; 45186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!FName) 45286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines FName = "(unknown)"; 4536d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 45486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Diag(CallLoc, DL_Error, 4559b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne "call to function %0 through pointer to incorrect function type %1") 45686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines << FName << Data->Type; 45786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Diag(FLoc, DL_Note, "%0 defined here") << FName; 4589b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne} 4599b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne 4606d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid 4616d1862363c88c183b0ed7740fca876342cf0474bStephen Hines__ubsan::__ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data, 4626d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Function) { 4636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 4646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleFunctionTypeMismatch(Data, Function, Opts); 4656d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 4666d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4679b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbournevoid __ubsan::__ubsan_handle_function_type_mismatch_abort( 4686d1862363c88c183b0ed7740fca876342cf0474bStephen Hines FunctionTypeMismatchData *Data, ValueHandle Function) { 4696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 4706d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleFunctionTypeMismatch(Data, Function, Opts); 4716d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Die(); 4726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 4736d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4746d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts) { 4756d1862363c88c183b0ed7740fca876342cf0474bStephen Hines SourceLocation Loc = Data->Loc.acquire(); 476799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET = ErrorType::InvalidNullReturn; 477799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 478799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 4796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines return; 4806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 481799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 4826d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Diag(Loc, DL_Error, "null pointer returned from function declared to never " 4846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines "return null"); 4856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (!Data->AttrLoc.isInvalid()) 4866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Diag(Data->AttrLoc, DL_Note, "returns_nonnull attribute specified here"); 4876d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 4886d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4896d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_nonnull_return(NonNullReturnData *Data) { 4906d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 4916d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNonNullReturn(Data, Opts); 4926d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 4936d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4946d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_nonnull_return_abort(NonNullReturnData *Data) { 4956d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 4966d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNonNullReturn(Data, Opts); 4976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Die(); 4986d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 4996d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 5006d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleNonNullArg(NonNullArgData *Data, ReportOptions Opts) { 5016d1862363c88c183b0ed7740fca876342cf0474bStephen Hines SourceLocation Loc = Data->Loc.acquire(); 502799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET = ErrorType::InvalidNullArgument; 503799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 504799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 5056d1862363c88c183b0ed7740fca876342cf0474bStephen Hines return; 5066d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 507799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 5086d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 5096d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Diag(Loc, DL_Error, "null pointer passed as argument %0, which is declared to " 5106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines "never be null") << Data->ArgIndex; 5116d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (!Data->AttrLoc.isInvalid()) 5126d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Diag(Data->AttrLoc, DL_Note, "nonnull attribute specified here"); 5136d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5146d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 5156d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_nonnull_arg(NonNullArgData *Data) { 5166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 5176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNonNullArg(Data, Opts); 5186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 5206d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_nonnull_arg_abort(NonNullArgData *Data) { 5216d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 5226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNonNullArg(Data, Opts); 5239b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne Die(); 5249b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne} 5257c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar 526c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic void handleCFIBadIcall(CFICheckFailData *Data, ValueHandle Function, 527799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ReportOptions Opts) { 528c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (Data->CheckKind != CFITCK_ICall) 529c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Die(); 530c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 531799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar SourceLocation Loc = Data->Loc.acquire(); 532799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ErrorType ET = ErrorType::CFIBadType; 533799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 534799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 535799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return; 536799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 537799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 538799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 539799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Diag(Loc, DL_Error, "control flow integrity check for type %0 failed during " 540799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar "indirect function call") 541799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar << Data->Type; 542799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 543799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar SymbolizedStackHolder FLoc(getSymbolizedLocation(Function)); 544799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar const char *FName = FLoc.get()->info.function; 545799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar if (!FName) 546799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar FName = "(unknown)"; 547799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Diag(FLoc, DL_Note, "%0 defined here") << FName; 548799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar} 549799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 550c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarnamespace __ubsan { 551c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef UBSAN_CAN_USE_CXXABI 552c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarSANITIZER_WEAK_ATTRIBUTE 553c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarvoid HandleCFIBadType(CFICheckFailData *Data, ValueHandle Vtable, 554c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar bool ValidVtable, ReportOptions Opts); 555c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else 556c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic void HandleCFIBadType(CFICheckFailData *Data, ValueHandle Vtable, 557c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar bool ValidVtable, ReportOptions Opts) { 558c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Die(); 559c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 560c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif 561c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} // namespace __ubsan 562c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 563c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarvoid __ubsan::__ubsan_handle_cfi_check_fail(CFICheckFailData *Data, 564c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar ValueHandle Value, 565c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar uptr ValidVtable) { 566799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar GET_REPORT_OPTIONS(false); 567c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (Data->CheckKind == CFITCK_ICall) 568c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar handleCFIBadIcall(Data, Value, Opts); 569c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar else 570c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar HandleCFIBadType(Data, Value, ValidVtable, Opts); 571799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar} 572799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 573c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarvoid __ubsan::__ubsan_handle_cfi_check_fail_abort(CFICheckFailData *Data, 574c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar ValueHandle Value, 575c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar uptr ValidVtable) { 576799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar GET_REPORT_OPTIONS(true); 577c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (Data->CheckKind == CFITCK_ICall) 578c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar handleCFIBadIcall(Data, Value, Opts); 579c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar else 580c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar HandleCFIBadType(Data, Value, ValidVtable, Opts); 581799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar Die(); 582799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar} 583799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 5847c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar#endif // CAN_SANITIZE_UB 585