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