1// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - -w | FileCheck %s -check-prefixes=SHARED,OBJC
2// RUN: %clang_cc1 -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - -w | FileCheck %s -check-prefixes=SHARED,OBJC
3// RUN: %clang_cc1 -x c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check-prefixes=SHARED,C
4
5typedef signed char BOOL;
6
7// SHARED-LABEL: f1
8BOOL f1() {
9  // OBJC: call void @__ubsan_handle_load_invalid_value
10  // C-NOT: call void @__ubsan_handle_load_invalid_value
11  BOOL a = 2;
12  return a + 1;
13  // SHARED: ret i8
14}
15
16struct S1 {
17  BOOL b1 : 1;
18};
19
20// SHARED-LABEL: f2
21BOOL f2(struct S1 *s) {
22  // OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}}
23  // OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7
24  // OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7
25  // OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize
26  // OBJC: call void @__ubsan_handle_load_invalid_value
27
28  // C-NOT: call void @__ubsan_handle_load_invalid_value
29  return s->b1;
30  // SHARED: ret i8
31}
32
33#ifdef __OBJC__
34@interface I1 {
35@public
36  BOOL b1 : 1;
37}
38@property (nonatomic) BOOL b1;
39@end
40@implementation I1
41@synthesize b1;
42@end
43
44// Check the synthesized getter.
45// OBJC-LABEL: define internal signext i8 @"\01-[I1 b1]"
46// OBJC: [[IVAR:%.*]] = load i64, i64* @"OBJC_IVAR_$_I1.b1"
47// OBJC: [[ADDR:%.*]] = getelementptr inbounds i8, i8* {{.*}}, i64 [[IVAR]]
48// OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}}
49// OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7
50// OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7
51// OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize
52// OBJC: call void @__ubsan_handle_load_invalid_value
53
54// Also check direct accesses to the ivar.
55// OBJC-LABEL: f3
56BOOL f3(I1 *i) {
57  // OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}}
58  // OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7
59  // OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7
60  // OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize
61  // OBJC: call void @__ubsan_handle_load_invalid_value
62
63  return i->b1;
64  // OBJC: ret i8
65}
66#endif /* __OBJC__ */
67