summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/ubsan-bitfields.cpp
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2017-03-08 17:38:57 +0000
committerVedant Kumar <vsk@apple.com>2017-03-08 17:38:57 +0000
commita9ded305be0c0e5c0e703de987dd13286a2d971b (patch)
tree9a6ea0e8f1af2cfe0ade5e34968f780646b65587 /test/CodeGenCXX/ubsan-bitfields.cpp
parenta40b07abcf4f782398ff0d86852ede6e86e8612a (diff)
[ubsan] Detect UB loads from bitfields
It's possible to load out-of-range values from bitfields backed by a boolean or an enum. Check for UB loads from bitfields. This is the motivating example: struct S { BOOL b : 1; // Signed ObjC BOOL. }; S s; s.b = 1; // This is actually stored as -1. if (s.b == 1) // Evaluates to false, -1 != 1. ... Differential Revision: https://reviews.llvm.org/D30423 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@297298 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/ubsan-bitfields.cpp')
-rw-r--r--test/CodeGenCXX/ubsan-bitfields.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/test/CodeGenCXX/ubsan-bitfields.cpp b/test/CodeGenCXX/ubsan-bitfields.cpp
new file mode 100644
index 0000000000..c8e9d9be09
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-bitfields.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=enum | FileCheck %s
+
+enum E {
+ a = 1,
+ b = 2,
+ c = 3
+};
+
+struct S {
+ E e1 : 10;
+};
+
+// CHECK-LABEL: define i32 @_Z4loadP1S
+E load(S *s) {
+ // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}}
+ // CHECK: [[CLEAR:%.*]] = and i16 [[LOAD]], 1023
+ // CHECK: [[CAST:%.*]] = zext i16 [[CLEAR]] to i32
+ // CHECK: icmp ule i32 [[CAST]], 3, !nosanitize
+ // CHECK: call void @__ubsan_handle_load_invalid_value
+ return s->e1;
+}