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 243d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarnamespace __ubsan { 253d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarbool ignoreReport(SourceLocation SLoc, ReportOptions Opts, ErrorType ET) { 263d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // We are not allowed to skip error report: if we are in unrecoverable 273d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // handler, we have to terminate the program right now, and therefore 283d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // have to print some diagnostic. 293d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // 303d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // Even if source location is disabled, it doesn't mean that we have 313d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // already report an error to the user: some concurrently running 323d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // thread could have acquired it, but not yet printed the report. 333d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (Opts.FromUnrecoverableHandler) 343d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar return false; 353d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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(); 473d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 483d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET; 493d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (!Pointer) 503d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ET = ErrorType::NullPointerUse; 513d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar else if (Data->Alignment && (Pointer & (Data->Alignment - 1))) 523d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ET = ErrorType::MisalignedPointerUse; 533d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar else 543d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ET = ErrorType::InsufficientObjectSize; 553d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 563d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // Use the SourceLocation from Data to track deduplication, even if it's 573d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // invalid. 583d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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 673d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 686d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 693d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar switch (ET) { 703d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar case ErrorType::NullPointerUse: 7125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Loc, DL_Error, "%0 null pointer of type %1") 723d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar << TypeCheckKinds[Data->TypeCheckKind] << Data->Type; 733d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar break; 743d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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") 773d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer 783d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar << Data->Alignment << Data->Type; 793d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar break; 803d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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") 833d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer << Data->Type; 843d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar break; 853d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar default: 863d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar UNREACHABLE("unexpected error type!"); 873d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar } 883d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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(); 1113d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar bool IsSigned = Data->Type.isSignedIntegerTy(); 1123d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET = IsSigned ? ErrorType::SignedIntegerOverflow 1133d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar : ErrorType::UnsignedIntegerOverflow; 1143d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 1153d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 1162af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 1172af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 1183d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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") 1223d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar << (IsSigned ? "signed" : "unsigned") 1236ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith << Value(Data->Type, LHS) << Operator << RHS << Data->Type; 1246ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 1256ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1263d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define UBSAN_OVERFLOW_HANDLER(handler_name, op, unrecoverable) \ 1276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines void __ubsan::handler_name(OverflowData *Data, ValueHandle LHS, \ 1286d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle RHS) { \ 1293d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar GET_REPORT_OPTIONS(unrecoverable); \ 1306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleIntegerOverflowImpl(Data, LHS, op, Value(Data->Type, RHS), Opts); \ 1313d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (unrecoverable) \ 1323d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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(); 1453d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar bool IsSigned = Data->Type.isSignedIntegerTy(); 1463d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET = IsSigned ? ErrorType::SignedIntegerOverflow 1473d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar : ErrorType::UnsignedIntegerOverflow; 1483d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 1493d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 1502af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 1512af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 1523d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 1536d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 1543d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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") 1583d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar << Value(Data->Type, OldVal) << Data->Type; 159f359dea95de4a17287d11052e9b552100c152287Will Dietz else 1603d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Diag(Loc, DL_Error, "negation of %0 cannot be represented in type %1") 1613d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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); 1813d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 1823d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET; 1836ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith if (RHSVal.isMinusOne()) 1843d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ET = ErrorType::SignedIntegerOverflow; 1853d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar else if (Data->Type.isIntegerTy()) 1863d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ET = ErrorType::IntegerDivideByZero; 1876ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else 1883d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ET = ErrorType::FloatDivideByZero; 1893d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 1903d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 1913d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar return; 1923d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 1933d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 1943d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 1953d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar switch (ET) { 1963d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar case ErrorType::SignedIntegerOverflow: 1973d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Diag(Loc, DL_Error, "division of %0 by -1 cannot be represented in type %1") 1983d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar << LHSVal << Data->Type; 1993d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar break; 2003d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar default: 2012af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, "division by zero"); 2023d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar break; 2033d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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); 2253d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 2263d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET; 2273d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (RHSVal.isNegative() || 2283d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar RHSVal.getPositiveIntValue() >= Data->LHSType.getIntegerBitWidth()) 2293d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ET = ErrorType::InvalidShiftExponent; 2306ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else 2313d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ET = ErrorType::InvalidShiftBase; 2323d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 2333d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 2343d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar return; 2353d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 2363d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 2373d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 2383d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ET == ErrorType::InvalidShiftExponent) { 2393d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (RHSVal.isNegative()) 2403d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Diag(Loc, DL_Error, "shift exponent %0 is negative") << RHSVal; 2413d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar else 2423d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Diag(Loc, DL_Error, "shift exponent %0 is too large for %1-bit type %2") 2433d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType; 2443d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar } else { 2453d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (LHSVal.isNegative()) 2463d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Diag(Loc, DL_Error, "left shift of negative value %0") << LHSVal; 2473d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar else 2483d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Diag(Loc, DL_Error, 2493d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar "left shift of %0 by %1 places cannot be represented in type %2") 2503d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar << LHSVal << RHSVal << Data->LHSType; 2513d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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(); 2723d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET = ErrorType::OutOfBoundsIndex; 2733d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 2743d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 275a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith return; 276a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith 2773d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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) { 2983d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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) { 3093d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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(); 3243d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET = ErrorType::NonPositiveVLAIndex; 3253d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 3263d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 3272af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 3282af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 3293d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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 3483d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarstatic bool looksLikeFloatCastOverflowDataV1(void *Data) { 3493d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // First field is either a pointer to filename or a pointer to a 3503d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // TypeDescriptor. 3513d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar u8 *FilenameOrTypeDescriptor; 3523d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar internal_memcpy(&FilenameOrTypeDescriptor, Data, 3533d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar sizeof(FilenameOrTypeDescriptor)); 3543d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 3553d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // Heuristic: For float_cast_overflow, the TypeKind will be either TK_Integer 3563d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // (0x0), TK_Float (0x1) or TK_Unknown (0xff). If both types are known, 3573d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // adding both bytes will be 0 or 1 (for BE or LE). If it were a filename, 3583d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // adding two printable characters will not yield such a value. Otherwise, 3593d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // if one of them is 0xff, this is most likely TK_Unknown type descriptor. 3603d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar u16 MaybeFromTypeKind = 3613d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar FilenameOrTypeDescriptor[0] + FilenameOrTypeDescriptor[1]; 3623d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar return MaybeFromTypeKind < 2 || FilenameOrTypeDescriptor[0] == 0xff || 3633d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar FilenameOrTypeDescriptor[1] == 0xff; 3643d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar} 3653d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 3663d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarstatic void handleFloatCastOverflow(void *DataPtr, ValueHandle From, 3673d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ReportOptions Opts) { 3683d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar SymbolizedStackHolder CallerLoc; 3693d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Location Loc; 3703d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar const TypeDescriptor *FromType, *ToType; 3713d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET = ErrorType::FloatCastOverflow; 3723d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 3733d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (looksLikeFloatCastOverflowDataV1(DataPtr)) { 3743d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar auto Data = reinterpret_cast<FloatCastOverflowData *>(DataPtr); 3753d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar CallerLoc.reset(getCallerLocation(Opts.pc)); 3763d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Loc = CallerLoc; 3773d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar FromType = &Data->FromType; 3783d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ToType = &Data->ToType; 3793d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar } else { 3803d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar auto Data = reinterpret_cast<FloatCastOverflowDataV2 *>(DataPtr); 3813d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar SourceLocation SLoc = Data->Loc.acquire(); 3823d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(SLoc, Opts, ET)) 3833d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar return; 3843d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Loc = SLoc; 3853d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar FromType = &Data->FromType; 3863d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ToType = &Data->ToType; 3873d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar } 3883d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 3893d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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") 3933d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar << Value(*FromType, From) << *FromType << *ToType; 3946d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 3955f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith 3963d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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} 4003d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarvoid __ubsan::__ubsan_handle_float_cast_overflow_abort(void *Data, 4013d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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(); 4103d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // This check could be more precise if we used different handlers for 4113d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar // -fsanitize=bool and -fsanitize=enum. 4123d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar bool IsBool = (0 == internal_strcmp(Data->Type.getTypeName(), "'bool'")); 4133d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET = 4143d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar IsBool ? ErrorType::InvalidBoolLoad : ErrorType::InvalidEnumLoad; 4153d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 4163d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 417d1bf52ecb1211af7fa3fe5f5b05d08033eb1a90cNick Lewycky return; 418d1bf52ecb1211af7fa3fe5f5b05d08033eb1a90cNick Lewycky 4193d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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(); 4423d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET = ErrorType::FunctionTypeMismatch; 4433d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 4443d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(CallLoc, Opts, ET)) 44586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return; 4469b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne 4473d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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(); 4763d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET = ErrorType::InvalidNullReturn; 4773d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 4783d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 4796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines return; 4806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4813d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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(); 5023d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET = ErrorType::InvalidNullArgument; 5033d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 5043d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 5056d1862363c88c183b0ed7740fca876342cf0474bStephen Hines return; 5066d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 5073d763c0d3700e73b3aead8e65e04ec28efc56138Pirama 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 5263d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarstatic void handleCFIBadIcall(CFIBadIcallData *Data, ValueHandle Function, 5273d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ReportOptions Opts) { 5283d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar SourceLocation Loc = Data->Loc.acquire(); 5293d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ErrorType ET = ErrorType::CFIBadType; 5303d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 5313d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (ignoreReport(Loc, Opts, ET)) 5323d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar return; 5333d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 5343d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ScopedReport R(Opts, Loc, ET); 5353d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 5363d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Diag(Loc, DL_Error, "control flow integrity check for type %0 failed during " 5373d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar "indirect function call") 5383d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar << Data->Type; 5393d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 5403d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar SymbolizedStackHolder FLoc(getSymbolizedLocation(Function)); 5413d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar const char *FName = FLoc.get()->info.function; 5423d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar if (!FName) 5433d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar FName = "(unknown)"; 5443d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Diag(FLoc, DL_Note, "%0 defined here") << FName; 5453d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar} 5463d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 5473d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarvoid __ubsan::__ubsan_handle_cfi_bad_icall(CFIBadIcallData *Data, 5483d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ValueHandle Function) { 5493d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar GET_REPORT_OPTIONS(false); 5503d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar handleCFIBadIcall(Data, Function, Opts); 5513d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar} 5523d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 5533d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarvoid __ubsan::__ubsan_handle_cfi_bad_icall_abort(CFIBadIcallData *Data, 5543d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar ValueHandle Function) { 5553d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar GET_REPORT_OPTIONS(true); 5563d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar handleCFIBadIcall(Data, Function, Opts); 5573d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar Die(); 5583d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar} 5593d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar 5607c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar#endif // CAN_SANITIZE_UB 561