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