Index: ./ubsan_checks.inc =================================================================== --- ./ubsan_checks.inc +++ ./ubsan_checks.inc @@ -43,5 +43,6 @@ UBSAN_CHECK(InvalidNullReturn, "invalid-null-return", "returns-nonnull-attribute") UBSAN_CHECK(InvalidNullArgument, "invalid-null-argument", "nonnull-attribute") +UBSAN_CHECK(InvalidNoreturn, "invalid-noreturn", "noreturn") UBSAN_CHECK(DynamicTypeMismatch, "dynamic-type-mismatch", "vptr") UBSAN_CHECK(CFIBadType, "cfi-bad-type", "cfi") Index: ./ubsan_handlers.h =================================================================== --- ./ubsan_handlers.h +++ ./ubsan_handlers.h @@ -166,6 +166,14 @@ RECOVERABLE(nonnull_arg, NonNullArgData *Data) RECOVERABLE(nullability_arg, NonNullArgData *Data) +struct NoreturnData { + SourceLocation AttrLoc; +}; + +/// \brief Handle returning from function with the noreturn +/// attribute. +UNRECOVERABLE(noreturn, NoreturnData *Data, SourceLocation *Loc) + struct PointerOverflowData { SourceLocation Loc; }; Index: ./ubsan_handlers.cc =================================================================== --- ./ubsan_handlers.cc +++ ./ubsan_handlers.cc @@ -585,6 +585,32 @@ Die(); } +static void handleNoreturn(NoreturnData *Data, SourceLocation *LocPtr, + ReportOptions Opts) { + if (!LocPtr) + UNREACHABLE("source location pointer is null!"); + + SourceLocation Loc = LocPtr->acquire(); + ErrorType ET = ErrorType::InvalidNoreturn; + + if (ignoreReport(Loc, Opts, ET)) + return; + + ScopedReport R(Opts, Loc, ET); + + Diag(Loc, DL_Error, "return from function declared to never " + "return"); + if (!Data->AttrLoc.isInvalid()) + Diag(Data->AttrLoc, DL_Note, "noreturn attribute specified here"); +} + +void __ubsan::__ubsan_handle_noreturn(NoreturnData *Data, + SourceLocation *LocPtr) { + GET_REPORT_OPTIONS(true); + handleNoreturn(Data, LocPtr, Opts); + Die(); +} + static void handlePointerOverflowImpl(PointerOverflowData *Data, ValueHandle Base, ValueHandle Result,