diff options
| author | Alexey Samsonov <vonosmas@gmail.com> | 2014-08-13 00:26:40 +0000 |
|---|---|---|
| committer | Alexey Samsonov <vonosmas@gmail.com> | 2014-08-13 00:26:40 +0000 |
| commit | de443c500203d262c87a27e3f9272b520ff15d9f (patch) | |
| tree | 82f296d2aa3af79c5ce4f8f6059b00312ac63e4d /compiler-rt | |
| parent | cfe8fc3e2840845bd159b1eb9ec1f8f2a6a31446 (diff) | |
| download | bcm5719-llvm-de443c500203d262c87a27e3f9272b520ff15d9f.tar.gz bcm5719-llvm-de443c500203d262c87a27e3f9272b520ff15d9f.zip | |
[UBSan] Add returns-nonnull sanitizer.
Summary:
This patch adds a runtime check verifying that functions
annotated with "returns_nonnull" attribute do in fact return nonnull pointers.
It is based on suggestion by Jakub Jelinek:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140623/223693.html.
Test Plan: regression test suite
Reviewers: rsmith
Reviewed By: rsmith
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D4849
llvm-svn: 215485
Diffstat (limited to 'compiler-rt')
| -rw-r--r-- | compiler-rt/lib/ubsan/ubsan_handlers.cc | 19 | ||||
| -rw-r--r-- | compiler-rt/lib/ubsan/ubsan_handlers.h | 7 | ||||
| -rw-r--r-- | compiler-rt/test/ubsan/TestCases/Misc/nonnull.cpp | 13 |
3 files changed, 39 insertions, 0 deletions
diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.cc b/compiler-rt/lib/ubsan/ubsan_handlers.cc index afda39332f2..14b12b6a97f 100644 --- a/compiler-rt/lib/ubsan/ubsan_handlers.cc +++ b/compiler-rt/lib/ubsan/ubsan_handlers.cc @@ -308,3 +308,22 @@ void __ubsan::__ubsan_handle_function_type_mismatch_abort( FunctionTypeMismatchData *Data, ValueHandle Function) { handleFunctionTypeMismatch(Data, Function, true); } + +static void handleNonnullReturn(NonNullReturnData *Data, bool Abort) { + SourceLocation Loc = Data->Loc.acquire(); + if (Loc.isDisabled()) + return; + + ScopedReport R(Abort); + + Diag(Loc, DL_Error, "null pointer returned from function declared to never " + "return null"); +} + +void __ubsan::__ubsan_handle_nonnull_return(NonNullReturnData *Data) { + handleNonnullReturn(Data, false); +} + +void __ubsan::__ubsan_handle_nonnull_return_abort(NonNullReturnData *Data) { + handleNonnullReturn(Data, true); +} diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.h b/compiler-rt/lib/ubsan/ubsan_handlers.h index 14e6f04c2a1..910198c51a4 100644 --- a/compiler-rt/lib/ubsan/ubsan_handlers.h +++ b/compiler-rt/lib/ubsan/ubsan_handlers.h @@ -121,6 +121,13 @@ RECOVERABLE(function_type_mismatch, FunctionTypeMismatchData *Data, ValueHandle Val) +struct NonNullReturnData { + SourceLocation Loc; +}; + +/// \brief Handle returning null from function with returns_nonnull attribute. +RECOVERABLE(nonnull_return, NonNullReturnData *Data) + } #endif // UBSAN_HANDLERS_H diff --git a/compiler-rt/test/ubsan/TestCases/Misc/nonnull.cpp b/compiler-rt/test/ubsan/TestCases/Misc/nonnull.cpp new file mode 100644 index 00000000000..8b5fcaf43bf --- /dev/null +++ b/compiler-rt/test/ubsan/TestCases/Misc/nonnull.cpp @@ -0,0 +1,13 @@ +// RUN: %clangxx -fsanitize=returns-nonnull-attribute %s -O3 -o %t +// RUN: %run %t foo +// RUN: %run %t 2>&1 | FileCheck %s + +__attribute__((returns_nonnull)) +char *foo(char *a) { + return a; + // CHECK: nonnull.cpp:[[@LINE+1]]:1: runtime error: null pointer returned from function declared to never return null +} + +int main(int argc, char **argv) { + return foo(argv[1]) == 0; +} |

