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