diff options
author | Vedant Kumar <vsk@apple.com> | 2017-03-14 16:32:27 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2017-03-14 16:32:27 +0000 |
commit | eac3043502e263e5140f12e7b2ed655aa51e9f9d (patch) | |
tree | 1c4bbb7a9f3523ceac0974a55a541b665673d493 /lib/ubsan/ubsan_handlers.cc | |
parent | 1b3f1014cef7e8fe3b532dae88d91a1bf3a6a73f (diff) |
[ubsan] Add diagnostic handlers for nullability errors
Add 'nullability_arg' and 'nullability_return' diagnostic handlers, and
also add a TypeCheckKind for null assignments to _Nonnull. With this in
place, we can update clang to use the nicer handlers for nullability
diagnostics.
The alternative to this approach is to update the existing 'nonnull_arg'
and 'nonnull_return' handlers to accept a boolean parameter. However,
versioning the existing handlers would cause code size bloat, and the
complexity cost of introducing new handlers into the runtime is low.
I will add tests for this, and all of -fsanitize=nullability, into
check-ubsan once the clang side of the changes is in.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@297748 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ubsan/ubsan_handlers.cc')
-rw-r--r-- | lib/ubsan/ubsan_handlers.cc | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/lib/ubsan/ubsan_handlers.cc b/lib/ubsan/ubsan_handlers.cc index 6ffffae7b..4e025a8dd 100644 --- a/lib/ubsan/ubsan_handlers.cc +++ b/lib/ubsan/ubsan_handlers.cc @@ -38,7 +38,7 @@ bool ignoreReport(SourceLocation SLoc, ReportOptions Opts, ErrorType ET) { const char *TypeCheckKinds[] = { "load of", "store to", "reference binding to", "member access within", "member call on", "constructor call on", "downcast of", "downcast of", - "upcast of", "cast to virtual base of"}; + "upcast of", "cast to virtual base of", "_Nonnull binding to"}; } static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer, @@ -472,7 +472,8 @@ void __ubsan::__ubsan_handle_function_type_mismatch_abort( Die(); } -static void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts) { +static void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts, + bool IsAttr) { SourceLocation Loc = Data->Loc.acquire(); ErrorType ET = ErrorType::InvalidNullReturn; @@ -484,21 +485,35 @@ static void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts) { Diag(Loc, DL_Error, "null pointer returned from function declared to never " "return null"); if (!Data->AttrLoc.isInvalid()) - Diag(Data->AttrLoc, DL_Note, "returns_nonnull attribute specified here"); + Diag(Data->AttrLoc, DL_Note, "%0 specified here") + << (IsAttr ? "returns_nonnull attribute" + : "_Nonnull return type annotation"); } void __ubsan::__ubsan_handle_nonnull_return(NonNullReturnData *Data) { GET_REPORT_OPTIONS(false); - handleNonNullReturn(Data, Opts); + handleNonNullReturn(Data, Opts, true); } void __ubsan::__ubsan_handle_nonnull_return_abort(NonNullReturnData *Data) { GET_REPORT_OPTIONS(true); - handleNonNullReturn(Data, Opts); + handleNonNullReturn(Data, Opts, true); Die(); } -static void handleNonNullArg(NonNullArgData *Data, ReportOptions Opts) { +void __ubsan::__ubsan_handle_nullability_return(NonNullReturnData *Data) { + GET_REPORT_OPTIONS(false); + handleNonNullReturn(Data, Opts, false); +} + +void __ubsan::__ubsan_handle_nullability_return_abort(NonNullReturnData *Data) { + GET_REPORT_OPTIONS(true); + handleNonNullReturn(Data, Opts, false); + Die(); +} + +static void handleNonNullArg(NonNullArgData *Data, ReportOptions Opts, + bool IsAttr) { SourceLocation Loc = Data->Loc.acquire(); ErrorType ET = ErrorType::InvalidNullArgument; @@ -507,20 +522,34 @@ static void handleNonNullArg(NonNullArgData *Data, ReportOptions Opts) { ScopedReport R(Opts, Loc, ET); - Diag(Loc, DL_Error, "null pointer passed as argument %0, which is declared to " - "never be null") << Data->ArgIndex; + Diag(Loc, DL_Error, + "null pointer passed as argument %0, which is declared to " + "never be null") + << Data->ArgIndex; if (!Data->AttrLoc.isInvalid()) - Diag(Data->AttrLoc, DL_Note, "nonnull attribute specified here"); + Diag(Data->AttrLoc, DL_Note, "%0 specified here") + << (IsAttr ? "nonnull attribute" : "_Nonnull type annotation"); } void __ubsan::__ubsan_handle_nonnull_arg(NonNullArgData *Data) { GET_REPORT_OPTIONS(false); - handleNonNullArg(Data, Opts); + handleNonNullArg(Data, Opts, true); } void __ubsan::__ubsan_handle_nonnull_arg_abort(NonNullArgData *Data) { GET_REPORT_OPTIONS(true); - handleNonNullArg(Data, Opts); + handleNonNullArg(Data, Opts, true); + Die(); +} + +void __ubsan::__ubsan_handle_nullability_arg(NonNullArgData *Data) { + GET_REPORT_OPTIONS(false); + handleNonNullArg(Data, Opts, false); +} + +void __ubsan::__ubsan_handle_nullability_arg_abort(NonNullArgData *Data) { + GET_REPORT_OPTIONS(true); + handleNonNullArg(Data, Opts, false); Die(); } |