blob: 3a3536beace8c5885a1e5ddd673008c7098579b4 [file] [log] [blame]
Richard Smith463b48b2012-12-13 07:11:50 +00001// RUN: %clang_cc1 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
Richard Smith2c9f87c2012-08-24 00:54:33 +00002
Richard Smith073fec92012-12-18 00:22:45 +00003struct S {
4 double d;
5 int a, b;
6 virtual int f();
7};
8
Richard Smith2c9f87c2012-08-24 00:54:33 +00009// CHECK: @_Z17reference_binding
Richard Smith073fec92012-12-18 00:22:45 +000010void reference_binding(int *p, S *q) {
Richard Smith2c9f87c2012-08-24 00:54:33 +000011 // C++ core issue 453: If an lvalue to which a reference is directly bound
12 // designates neither an existing object or function of an appropriate type,
13 // nor a region of storage of suitable size and alignment to contain an object
14 // of the reference's type, the behavior is undefined.
15
16 // CHECK: icmp ne {{.*}}, null
17
18 // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
19 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4
20
21 // CHECK: %[[PTRINT:.*]] = ptrtoint
22 // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3
23 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
24 int &r = *p;
Richard Smith2c9f87c2012-08-24 00:54:33 +000025
Richard Smith073fec92012-12-18 00:22:45 +000026 // A reference is not required to refer to an object within its lifetime.
27 // CHECK-NOT: __ubsan_handle_dynamic_type_cache_miss
28 S &r2 = *q;
29}
Richard Smith2c9f87c2012-08-24 00:54:33 +000030
31// CHECK: @_Z13member_access
32void member_access(S *p) {
Richard Smith08483332012-10-25 21:59:45 +000033 // (1a) Check 'p' is appropriately sized and aligned for member access.
Richard Smith2c9f87c2012-08-24 00:54:33 +000034
35 // CHECK: icmp ne {{.*}}, null
36
37 // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
38 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24
39
40 // CHECK: %[[PTRINT:.*]] = ptrtoint
41 // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7
42 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
43
Richard Smith08483332012-10-25 21:59:45 +000044 // (1b) Check that 'p' actually points to an 'S'.
45
46 // CHECK: %[[VPTRADDR:.*]] = bitcast {{.*}} to i64*
47 // CHECK-NEXT: %[[VPTR:.*]] = load i64* %[[VPTRADDR]]
48 //
49 // hash_16_bytes:
50 //
51 // If this number changes, it indicates that either the mangled name of ::S
52 // has changed, or that LLVM's hashing function has changed. The latter case
53 // is OK if the hashing function is still stable.
Richard Smithca530872012-10-25 22:27:30 +000054 //
55 // The two hash values are for 64- and 32-bit Clang binaries, respectively.
56 // FIXME: We should produce a 64-bit value either way.
57 //
58 // CHECK-NEXT: xor i64 {{-4030275160588942838|2562089159}}, %[[VPTR]]
Richard Smith08483332012-10-25 21:59:45 +000059 // CHECK-NEXT: mul i64 {{.*}}, -7070675565921424023
60 // CHECK-NEXT: lshr i64 {{.*}}, 47
61 // CHECK-NEXT: xor i64
62 // CHECK-NEXT: xor i64 %[[VPTR]]
63 // CHECK-NEXT: mul i64 {{.*}}, -7070675565921424023
64 // CHECK-NEXT: lshr i64 {{.*}}, 47
65 // CHECK-NEXT: xor i64
66 // CHECK-NEXT: %[[HASH:.*]] = mul i64 {{.*}}, -7070675565921424023
67 //
68 // Check the hash against the table:
69 //
70 // CHECK-NEXT: %[[IDX:.*]] = and i64 %{{.*}}, 127
71 // CHECK-NEXT: getelementptr inbounds [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 %[[IDX]]
72 // CHECK-NEXT: %[[CACHEVAL:.*]] = load i64*
73 // CHECK-NEXT: icmp eq i64 %[[CACHEVAL]], %[[HASH]]
74 // CHECK-NEXT: br i1
75
Will Dietz2d382d12012-12-30 20:53:28 +000076 // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}}, i64 %{{.*}}, i64 %[[HASH]])
Will Dietzad954812012-12-02 19:50:33 +000077 // CHECK-NOT: unreachable
78 // CHECK: {{.*}}:
Richard Smith08483332012-10-25 21:59:45 +000079
Richard Smith2c9f87c2012-08-24 00:54:33 +000080 // (2) Check 'p->b' is appropriately sized and aligned for a load.
81
82 // FIXME: Suppress this in the trivial case of a member access, because we
83 // know we've just checked the member access expression itself.
84
85 // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
86 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4
87
88 // CHECK: %[[PTRINT:.*]] = ptrtoint
89 // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3
90 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
91 int k = p->b;
92
Richard Smith08483332012-10-25 21:59:45 +000093 // (3a) Check 'p' is appropriately sized and aligned for member function call.
Richard Smith2c9f87c2012-08-24 00:54:33 +000094
95 // CHECK: icmp ne {{.*}}, null
96
97 // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
98 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24
99
100 // CHECK: %[[PTRINT:.*]] = ptrtoint
101 // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7
102 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0
Richard Smith08483332012-10-25 21:59:45 +0000103
104 // (3b) Check that 'p' actually points to an 'S'
105
106 // CHECK: load i64*
Richard Smithd6f83302012-10-25 23:05:00 +0000107 // CHECK-NEXT: xor i64 {{-4030275160588942838|2562089159}},
Richard Smith08483332012-10-25 21:59:45 +0000108 // [...]
109 // CHECK: getelementptr inbounds [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 %
110 // CHECK: br i1
Will Dietz2d382d12012-12-30 20:53:28 +0000111 // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}}, i64 %{{.*}}, i64 %{{.*}})
Will Dietzad954812012-12-02 19:50:33 +0000112 // CHECK-NOT: unreachable
113 // CHECK: {{.*}}:
Richard Smith08483332012-10-25 21:59:45 +0000114
Richard Smith2c9f87c2012-08-24 00:54:33 +0000115 k = p->f();
116}
Richard Smith9d3e2262012-08-25 00:32:28 +0000117
118// CHECK: @_Z12lsh_overflow
119int lsh_overflow(int a, int b) {
120 // CHECK: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
121 // CHECK-NEXT: br i1 %[[INBOUNDS]]
122
123 // CHECK: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]]
124 // CHECK-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]]
125
126 // This is present for C++11 but not for C: C++ core issue 1457 allows a '1'
127 // to be shifted into the sign bit, but not out of it.
128 // CHECK-NEXT: %[[SHIFTED_OUT_NOT_SIGN:.*]] = lshr i32 %[[SHIFTED_OUT]], 1
129
130 // CHECK-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT_NOT_SIGN]], 0
131 // CHECK-NEXT: br i1 %[[NO_OVERFLOW]]
132
133 // CHECK: %[[RET:.*]] = shl i32 %[[LHS]], %[[RHS]]
134 // CHECK-NEXT: ret i32 %[[RET]]
135 return a << b;
136}
Richard Smith36ef0d52012-10-04 23:52:29 +0000137
138// CHECK: @_Z9no_return
139int no_return() {
Richard Smith4def70d2012-10-09 19:52:38 +0000140 // CHECK: call void @__ubsan_handle_missing_return(i8* bitcast ({{.*}}* @{{.*}} to i8*)) noreturn nounwind
141 // CHECK-NEXT: unreachable
Richard Smith36ef0d52012-10-04 23:52:29 +0000142}
Richard Smith463b48b2012-12-13 07:11:50 +0000143
144// CHECK: @_Z9sour_bool
145bool sour_bool(bool *p) {
146 // CHECK: %[[OK:.*]] = icmp ule i8 {{.*}}, 1
147 // CHECK: br i1 %[[OK]]
Will Dietz2d382d12012-12-30 20:53:28 +0000148 // CHECK: call void @__ubsan_handle_load_invalid_value(i8* bitcast ({{.*}}), i64 {{.*}})
Richard Smith463b48b2012-12-13 07:11:50 +0000149 return *p;
150}
151
152enum E1 { e1a = 0, e1b = 127 } e1;
153enum E2 { e2a = -1, e2b = 64 } e2;
154enum E3 { e3a = (1u << 31) - 1 } e3;
155
156// CHECK: @_Z14bad_enum_value
157int bad_enum_value() {
158 // CHECK: %[[E1:.*]] = icmp ule i32 {{.*}}, 127
159 // CHECK: br i1 %[[E1]]
Will Dietz2d382d12012-12-30 20:53:28 +0000160 // CHECK: call void @__ubsan_handle_load_invalid_value(
Richard Smith463b48b2012-12-13 07:11:50 +0000161 int a = e1;
162
163 // CHECK: %[[E2HI:.*]] = icmp sle i32 {{.*}}, 127
164 // CHECK: %[[E2LO:.*]] = icmp sge i32 {{.*}}, -128
165 // CHECK: %[[E2:.*]] = and i1 %[[E2HI]], %[[E2LO]]
166 // CHECK: br i1 %[[E2]]
Will Dietz2d382d12012-12-30 20:53:28 +0000167 // CHECK: call void @__ubsan_handle_load_invalid_value(
Richard Smith463b48b2012-12-13 07:11:50 +0000168 int b = e2;
169
170 // CHECK: %[[E3:.*]] = icmp ule i32 {{.*}}, 2147483647
171 // CHECK: br i1 %[[E3]]
Will Dietz2d382d12012-12-30 20:53:28 +0000172 // CHECK: call void @__ubsan_handle_load_invalid_value(
Richard Smith463b48b2012-12-13 07:11:50 +0000173 int c = e3;
174 return a + b + c;
175}