summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2014-08-13 00:26:40 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2014-08-13 00:26:40 +0000
commitde443c500203d262c87a27e3f9272b520ff15d9f (patch)
tree82f296d2aa3af79c5ce4f8f6059b00312ac63e4d /compiler-rt
parentcfe8fc3e2840845bd159b1eb9ec1f8f2a6a31446 (diff)
downloadbcm5719-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.cc19
-rw-r--r--compiler-rt/lib/ubsan/ubsan_handlers.h7
-rw-r--r--compiler-rt/test/ubsan/TestCases/Misc/nonnull.cpp13
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;
+}
OpenPOWER on IntegriCloud