ubsan_handlers.cc revision 86277eb844c4983c81de62d7c050e92fe7155788
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 146ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#include "ubsan_handlers.h" 156ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#include "ubsan_diag.h" 166ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 176ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#include "sanitizer_common/sanitizer_common.h" 186ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 196ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithusing namespace __sanitizer; 206ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithusing namespace __ubsan; 216ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 226d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic bool ignoreReport(SourceLocation SLoc, ReportOptions Opts) { 236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // If source location is already acquired, we don't need to print an error 246d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // report for the second time. However, if we're in an unrecoverable handler, 256d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // it's possible that location was required by concurrently running thread. 266d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // In this case, we should continue the execution to ensure that any of 276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // threads will grab the report mutex and print the report before 286d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // crashing the program. 296d1862363c88c183b0ed7740fca876342cf0474bStephen Hines return SLoc.isDisabled() && !Opts.DieAfterReport; 306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 316d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 32eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smithnamespace __ubsan { 336d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesconst char *TypeCheckKinds[] = { 346ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith "load of", "store to", "reference binding to", "member access within", 356d1862363c88c183b0ed7740fca876342cf0474bStephen Hines "member call on", "constructor call on", "downcast of", "downcast of", 366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines "upcast of", "cast to virtual base of"}; 37eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith} 38eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith 395f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smithstatic void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer, 4086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ReportOptions Opts) { 412af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Location Loc = Data->Loc.acquire(); 422af552f98f980178db37eed28a609b6bf55f6df8Will Dietz // Use the SourceLocation from Data to track deduplication, even if 'invalid' 436d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (ignoreReport(Loc.getSourceLocation(), Opts)) 442af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SymbolizedStackHolder FallbackLoc; 4786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Data->Loc.isInvalid()) { 4886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines FallbackLoc.reset(getCallerLocation(Opts.pc)); 495f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith Loc = FallbackLoc; 5086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 515f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith 526d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Loc); 536d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 546ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith if (!Pointer) 5525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Loc, DL_Error, "%0 null pointer of type %1") 566ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith << TypeCheckKinds[Data->TypeCheckKind] << Data->Type; 576ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else if (Data->Alignment && (Pointer & (Data->Alignment - 1))) 5825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Loc, DL_Error, "%0 misaligned address %1 for type %3, " 5925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "which requires %2 byte alignment") 606ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer 616ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith << Data->Alignment << Data->Type; 626ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else 6325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Loc, DL_Error, "%0 address %1 with insufficient space " 6425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "for an object of type %2") 656ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type; 6625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (Pointer) 6725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Pointer, DL_Note, "pointer points here"); 68a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 705f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smithvoid __ubsan::__ubsan_handle_type_mismatch(TypeMismatchData *Data, 715f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith ValueHandle Pointer) { 726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 7386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines handleTypeMismatchImpl(Data, Pointer, Opts); 745f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith} 75a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_type_mismatch_abort(TypeMismatchData *Data, 765f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith ValueHandle Pointer) { 776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 7886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines handleTypeMismatchImpl(Data, Pointer, Opts); 796ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 806ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 816ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 8280af605afd0e92a2a128c81898f647207f384e08Will Dietz/// \brief Common diagnostic emission for various forms of integer overflow. 836d1862363c88c183b0ed7740fca876342cf0474bStephen Hinestemplate <typename T> 846d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS, 856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines const char *Operator, T RHS, 866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 872af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation Loc = Data->Loc.acquire(); 886d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (ignoreReport(Loc, Opts)) 892af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 902af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 916d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Loc); 926d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 932af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, "%0 integer overflow: " 942af552f98f980178db37eed28a609b6bf55f6df8Will Dietz "%1 %2 %3 cannot be represented in type %4") 9580af605afd0e92a2a128c81898f647207f384e08Will Dietz << (Data->Type.isSignedIntegerTy() ? "signed" : "unsigned") 966ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith << Value(Data->Type, LHS) << Operator << RHS << Data->Type; 976ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 986ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 996d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#define UBSAN_OVERFLOW_HANDLER(handler_name, op, abort) \ 1006d1862363c88c183b0ed7740fca876342cf0474bStephen Hines void __ubsan::handler_name(OverflowData *Data, ValueHandle LHS, \ 1016d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle RHS) { \ 1026d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(abort); \ 1036d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleIntegerOverflowImpl(Data, LHS, op, Value(Data->Type, RHS), Opts); \ 1046d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (abort) Die(); \ 1056d1862363c88c183b0ed7740fca876342cf0474bStephen Hines } 1066d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 1076d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_add_overflow, "+", false) 1086d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_add_overflow_abort, "+", true) 1096d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_sub_overflow, "-", false) 1106d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_sub_overflow_abort, "-", true) 1116d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_mul_overflow, "*", false) 1126d1862363c88c183b0ed7740fca876342cf0474bStephen HinesUBSAN_OVERFLOW_HANDLER(__ubsan_handle_mul_overflow_abort, "*", true) 1136d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 1146d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleNegateOverflowImpl(OverflowData *Data, ValueHandle OldVal, 1156d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 1162af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation Loc = Data->Loc.acquire(); 1176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (ignoreReport(Loc, Opts)) 1182af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 1192af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 1206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Loc); 1216d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 122f359dea95de4a17287d11052e9b552100c152287Will Dietz if (Data->Type.isSignedIntegerTy()) 1232af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, 124f359dea95de4a17287d11052e9b552100c152287Will Dietz "negation of %0 cannot be represented in type %1; " 125f359dea95de4a17287d11052e9b552100c152287Will Dietz "cast to an unsigned type to negate this value to itself") 126f359dea95de4a17287d11052e9b552100c152287Will Dietz << Value(Data->Type, OldVal) << Data->Type; 127f359dea95de4a17287d11052e9b552100c152287Will Dietz else 1282af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, 129f359dea95de4a17287d11052e9b552100c152287Will Dietz "negation of %0 cannot be represented in type %1") 130f359dea95de4a17287d11052e9b552100c152287Will Dietz << Value(Data->Type, OldVal) << Data->Type; 131a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 1326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 1336d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_negate_overflow(OverflowData *Data, 1346d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle OldVal) { 1356d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 1366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNegateOverflowImpl(Data, OldVal, Opts); 1376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 138a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_negate_overflow_abort(OverflowData *Data, 139a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ValueHandle OldVal) { 1406d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 1416d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNegateOverflowImpl(Data, OldVal, Opts); 1426ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 1436ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 1446ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1456d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleDivremOverflowImpl(OverflowData *Data, ValueHandle LHS, 1466d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle RHS, ReportOptions Opts) { 1472af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation Loc = Data->Loc.acquire(); 1486d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (ignoreReport(Loc, Opts)) 1492af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 1502af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 1516d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Loc); 1526d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 1536ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Value LHSVal(Data->Type, LHS); 1546ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Value RHSVal(Data->Type, RHS); 1556ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith if (RHSVal.isMinusOne()) 1562af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, 15725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "division of %0 by -1 cannot be represented in type %1") 1586ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith << LHSVal << Data->Type; 1596ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else 1602af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, "division by zero"); 161a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 1626d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 1636d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_divrem_overflow(OverflowData *Data, 1646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle LHS, ValueHandle RHS) { 1656d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 1666d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleDivremOverflowImpl(Data, LHS, RHS, Opts); 1676d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 168a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_divrem_overflow_abort(OverflowData *Data, 169a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ValueHandle LHS, 170a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ValueHandle RHS) { 1716d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 1726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleDivremOverflowImpl(Data, LHS, RHS, Opts); 1736ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 1746ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 1756ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1766d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleShiftOutOfBoundsImpl(ShiftOutOfBoundsData *Data, 1776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle LHS, ValueHandle RHS, 1786d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 1792af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation Loc = Data->Loc.acquire(); 1806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (ignoreReport(Loc, Opts)) 1812af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 1822af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 1836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Loc); 1846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 1856ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Value LHSVal(Data->LHSType, LHS); 1866ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Value RHSVal(Data->RHSType, RHS); 1876ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith if (RHSVal.isNegative()) 1882af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, "shift exponent %0 is negative") << RHSVal; 1896ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else if (RHSVal.getPositiveIntValue() >= Data->LHSType.getIntegerBitWidth()) 1902af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, 19125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "shift exponent %0 is too large for %1-bit type %2") 1926ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType; 1936ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else if (LHSVal.isNegative()) 1942af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, "left shift of negative value %0") << LHSVal; 1956ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else 1962af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, 19725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "left shift of %0 by %1 places cannot be represented in type %2") 19825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith << LHSVal << RHSVal << Data->LHSType; 199a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 2006d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 2016d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_shift_out_of_bounds(ShiftOutOfBoundsData *Data, 2026d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle LHS, 2036d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle RHS) { 2046d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 2056d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleShiftOutOfBoundsImpl(Data, LHS, RHS, Opts); 2066d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 207a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_shift_out_of_bounds_abort( 208a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ShiftOutOfBoundsData *Data, 209a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ValueHandle LHS, 210a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz ValueHandle RHS) { 2116d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 2126d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleShiftOutOfBoundsImpl(Data, LHS, RHS, Opts); 2136ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 2146ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 2156ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 2166d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleOutOfBoundsImpl(OutOfBoundsData *Data, ValueHandle Index, 2176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 218a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith SourceLocation Loc = Data->Loc.acquire(); 2196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (ignoreReport(Loc, Opts)) 220a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith return; 221a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith 2226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Loc); 2236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 224a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith Value IndexVal(Data->IndexType, Index); 225a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith Diag(Loc, DL_Error, "index %0 out of bounds for type %1") 226a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith << IndexVal << Data->ArrayType; 227a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith} 2286d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 2296d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_out_of_bounds(OutOfBoundsData *Data, 2306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Index) { 2316d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 2326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleOutOfBoundsImpl(Data, Index, Opts); 2336d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 234a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smithvoid __ubsan::__ubsan_handle_out_of_bounds_abort(OutOfBoundsData *Data, 235a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith ValueHandle Index) { 2366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 2376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleOutOfBoundsImpl(Data, Index, Opts); 238a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith Die(); 239a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith} 240a0b1e21d72429c3672115b3ddc85240e3b7ac88bRichard Smith 2416d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleBuiltinUnreachableImpl(UnreachableData *Data, 2426d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 2436d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Data->Loc); 24425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Data->Loc, DL_Error, "execution reached a __builtin_unreachable() call"); 2456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 2466d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 2476d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_builtin_unreachable(UnreachableData *Data) { 2486d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 2496d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleBuiltinUnreachableImpl(Data, Opts); 2506ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 2516ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 2526ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 2536d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleMissingReturnImpl(UnreachableData *Data, ReportOptions Opts) { 2546d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Data->Loc); 25525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Diag(Data->Loc, DL_Error, 25625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "execution reached the end of a value-returning function " 25725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "without returning a value"); 2586d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 2596d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 2606d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_missing_return(UnreachableData *Data) { 2616d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 2626d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleMissingReturnImpl(Data, Opts); 2636ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Die(); 2646ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 265b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith 2666d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleVLABoundNotPositive(VLABoundData *Data, ValueHandle Bound, 2676d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 2682af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation Loc = Data->Loc.acquire(); 2696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (ignoreReport(Loc, Opts)) 2702af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return; 2712af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 2726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Loc); 2736d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 2742af552f98f980178db37eed28a609b6bf55f6df8Will Dietz Diag(Loc, DL_Error, "variable length array bound evaluates to " 2752af552f98f980178db37eed28a609b6bf55f6df8Will Dietz "non-positive value %0") 276b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith << Value(Data->Type, Bound); 277a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 2786d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 2796d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_vla_bound_not_positive(VLABoundData *Data, 2806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Bound) { 2816d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 2826d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleVLABoundNotPositive(Data, Bound, Opts); 2836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 284a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_vla_bound_not_positive_abort(VLABoundData *Data, 2856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Bound) { 2866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 2876d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleVLABoundNotPositive(Data, Bound, Opts); 288b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith Die(); 289b04caf1385a4279a7b95d41c3ccefc61842c3633Richard Smith} 29058561700a4abad310911a24a867da49a14fae91eRichard Smith 2916d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleFloatCastOverflow(FloatCastOverflowData *Data, 2926d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle From, ReportOptions Opts) { 2936d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // TODO: Add deduplication once a SourceLocation is generated for this check. 29486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SymbolizedStackHolder CallerLoc(getCallerLocation(Opts.pc)); 29586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Location Loc = CallerLoc; 2966d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Loc); 2976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 2986d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Diag(Loc, DL_Error, 2996d1862363c88c183b0ed7740fca876342cf0474bStephen Hines "value %0 is outside the range of representable values of type %2") 3006d1862363c88c183b0ed7740fca876342cf0474bStephen Hines << Value(Data->FromType, From) << Data->FromType << Data->ToType; 3016d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 3025f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith 30358561700a4abad310911a24a867da49a14fae91eRichard Smithvoid __ubsan::__ubsan_handle_float_cast_overflow(FloatCastOverflowData *Data, 30458561700a4abad310911a24a867da49a14fae91eRichard Smith ValueHandle From) { 3056d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 3066d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleFloatCastOverflow(Data, From, Opts); 307a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz} 3086d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid 3096d1862363c88c183b0ed7740fca876342cf0474bStephen Hines__ubsan::__ubsan_handle_float_cast_overflow_abort(FloatCastOverflowData *Data, 3106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle From) { 3116d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 3126d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleFloatCastOverflow(Data, From, Opts); 31358561700a4abad310911a24a867da49a14fae91eRichard Smith Die(); 31458561700a4abad310911a24a867da49a14fae91eRichard Smith} 315f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith 3166d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleLoadInvalidValue(InvalidValueData *Data, ValueHandle Val, 3176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 318d1bf52ecb1211af7fa3fe5f5b05d08033eb1a90cNick Lewycky SourceLocation Loc = Data->Loc.acquire(); 3196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (ignoreReport(Loc, Opts)) 320d1bf52ecb1211af7fa3fe5f5b05d08033eb1a90cNick Lewycky return; 321d1bf52ecb1211af7fa3fe5f5b05d08033eb1a90cNick Lewycky 3226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Loc); 3236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 324d1bf52ecb1211af7fa3fe5f5b05d08033eb1a90cNick Lewycky Diag(Loc, DL_Error, 32525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith "load of value %0, which is not a valid value for type %1") 326f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith << Value(Data->Type, Val) << Data->Type; 327f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith} 3286d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3296d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_load_invalid_value(InvalidValueData *Data, 3306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Val) { 3316d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 3326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleLoadInvalidValue(Data, Val, Opts); 3336d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 334f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smithvoid __ubsan::__ubsan_handle_load_invalid_value_abort(InvalidValueData *Data, 335f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith ValueHandle Val) { 3366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 3376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleLoadInvalidValue(Data, Val, Opts); 338f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith Die(); 339f2d77d03b75733139c9f0896162bbc7a6fc38385Richard Smith} 3409b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne 3416d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data, 3426d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Function, 3436d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ReportOptions Opts) { 34486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SourceLocation CallLoc = Data->Loc.acquire(); 34586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (ignoreReport(CallLoc, Opts)) 34686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return; 3479b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne 34886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ScopedReport R(Opts, CallLoc); 3499b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne 35086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SymbolizedStackHolder FLoc(getSymbolizedLocation(Function)); 35186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *FName = FLoc.get()->info.function; 35286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!FName) 35386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines FName = "(unknown)"; 3546d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 35586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Diag(CallLoc, DL_Error, 3569b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne "call to function %0 through pointer to incorrect function type %1") 35786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines << FName << Data->Type; 35886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Diag(FLoc, DL_Note, "%0 defined here") << FName; 3599b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne} 3609b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne 3616d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid 3626d1862363c88c183b0ed7740fca876342cf0474bStephen Hines__ubsan::__ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data, 3636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ValueHandle Function) { 3646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 3656d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleFunctionTypeMismatch(Data, Function, Opts); 3666d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 3676d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3689b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbournevoid __ubsan::__ubsan_handle_function_type_mismatch_abort( 3696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines FunctionTypeMismatchData *Data, ValueHandle Function) { 3706d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 3716d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleFunctionTypeMismatch(Data, Function, Opts); 3726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Die(); 3736d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 3746d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3756d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts) { 3766d1862363c88c183b0ed7740fca876342cf0474bStephen Hines SourceLocation Loc = Data->Loc.acquire(); 3776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (ignoreReport(Loc, Opts)) 3786d1862363c88c183b0ed7740fca876342cf0474bStephen Hines return; 3796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Loc); 3816d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3826d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Diag(Loc, DL_Error, "null pointer returned from function declared to never " 3836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines "return null"); 3846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (!Data->AttrLoc.isInvalid()) 3856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Diag(Data->AttrLoc, DL_Note, "returns_nonnull attribute specified here"); 3866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 3876d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3886d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_nonnull_return(NonNullReturnData *Data) { 3896d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 3906d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNonNullReturn(Data, Opts); 3916d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 3926d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3936d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_nonnull_return_abort(NonNullReturnData *Data) { 3946d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 3956d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNonNullReturn(Data, Opts); 3966d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Die(); 3976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 3986d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 3996d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesstatic void handleNonNullArg(NonNullArgData *Data, ReportOptions Opts) { 4006d1862363c88c183b0ed7740fca876342cf0474bStephen Hines SourceLocation Loc = Data->Loc.acquire(); 4016d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (ignoreReport(Loc, Opts)) 4026d1862363c88c183b0ed7740fca876342cf0474bStephen Hines return; 4036d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4046d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedReport R(Opts, Loc); 4056d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4066d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Diag(Loc, DL_Error, "null pointer passed as argument %0, which is declared to " 4076d1862363c88c183b0ed7740fca876342cf0474bStephen Hines "never be null") << Data->ArgIndex; 4086d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (!Data->AttrLoc.isInvalid()) 4096d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Diag(Data->AttrLoc, DL_Note, "nonnull attribute specified here"); 4106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 4116d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4126d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_nonnull_arg(NonNullArgData *Data) { 4136d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(false); 4146d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNonNullArg(Data, Opts); 4156d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 4166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 4176d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __ubsan::__ubsan_handle_nonnull_arg_abort(NonNullArgData *Data) { 4186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines GET_REPORT_OPTIONS(true); 4196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines handleNonNullArg(Data, Opts); 4209b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne Die(); 4219b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535Peter Collingbourne} 422