summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/ubsan-unreachable.cpp
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2017-12-21 00:10:25 +0000
committerVedant Kumar <vsk@apple.com>2017-12-21 00:10:25 +0000
commit09b5bfdd85fa23a331ee565bda289b3c27c00fdf (patch)
treea5adff5e6bd5871fe32873bd2e3da642ba0f6247 /clang/test/CodeGenCXX/ubsan-unreachable.cpp
parentfae4f7c6818343acc9ad54cacaadaf9fc6fcf52d (diff)
downloadbcm5719-llvm-09b5bfdd85fa23a331ee565bda289b3c27c00fdf.tar.gz
bcm5719-llvm-09b5bfdd85fa23a331ee565bda289b3c27c00fdf.zip
[ubsan] Diagnose noreturn functions which return
Diagnose 'unreachable' UB when a noreturn function returns. 1. Insert a check at the end of functions marked noreturn. 2. A decl may be marked noreturn in the caller TU, but not marked in the TU where it's defined. To diagnose this scenario, strip away the noreturn attribute on the callee and insert check after calls to it. Testing: check-clang, check-ubsan, check-ubsan-minimal, D40700 rdar://33660464 Differential Revision: https://reviews.llvm.org/D40698 llvm-svn: 321231
Diffstat (limited to 'clang/test/CodeGenCXX/ubsan-unreachable.cpp')
-rw-r--r--clang/test/CodeGenCXX/ubsan-unreachable.cpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/ubsan-unreachable.cpp b/clang/test/CodeGenCXX/ubsan-unreachable.cpp
new file mode 100644
index 00000000000..32a78048cfd
--- /dev/null
+++ b/clang/test/CodeGenCXX/ubsan-unreachable.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=unreachable | FileCheck %s
+
+extern void __attribute__((noreturn)) abort();
+
+// CHECK-LABEL: define void @_Z14calls_noreturnv
+void calls_noreturn() {
+ abort();
+
+ // Check that there are no attributes on the call site.
+ // CHECK-NOT: call void @_Z5abortv{{.*}}#
+
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+}
+
+struct A {
+ // CHECK: declare void @_Z5abortv{{.*}} [[ABORT_ATTR:#[0-9]+]]
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A5call1Ev
+ void call1() {
+ // CHECK-NOT: call void @_ZN1A16does_not_return2Ev{{.*}}#
+ does_not_return2();
+
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+ }
+
+ // Test static members.
+ static void __attribute__((noreturn)) does_not_return1() {
+ // CHECK-NOT: call void @_Z5abortv{{.*}}#
+ abort();
+ }
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A5call2Ev
+ void call2() {
+ // CHECK-NOT: call void @_ZN1A16does_not_return1Ev{{.*}}#
+ does_not_return1();
+
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+ }
+
+ // Test calls through pointers to non-static member functions.
+ typedef void __attribute__((noreturn)) (A::*MemFn)();
+
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A5call3Ev
+ void call3() {
+ MemFn MF = &A::does_not_return2;
+ (this->*MF)();
+
+ // CHECK-NOT: call void %{{.*}}#
+ // CHECK: __ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+ }
+
+ // Test regular members.
+ // CHECK-LABEL: define linkonce_odr void @_ZN1A16does_not_return2Ev({{.*}})
+ // CHECK-SAME: [[DOES_NOT_RETURN_ATTR:#[0-9]+]]
+ void __attribute__((noreturn)) does_not_return2() {
+ // CHECK-NOT: call void @_Z5abortv(){{.*}}#
+ abort();
+
+ // CHECK: call void @__ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+
+ // CHECK: call void @__ubsan_handle_builtin_unreachable
+ // CHECK: unreachable
+ }
+};
+
+// CHECK: define linkonce_odr void @_ZN1A16does_not_return1Ev() [[DOES_NOT_RETURN_ATTR]]
+
+void force_irgen() {
+ A a;
+ a.call1();
+ a.call2();
+ a.call3();
+}
+
+// CHECK-NOT: [[ABORT_ATTR]] = {{[^}]+}}noreturn
+// CHECK-NOT: [[DOES_NOT_RETURN_ATTR]] = {{[^}]+}}noreturn
OpenPOWER on IntegriCloud