xref: /llvm-project/clang/test/CodeGenCXX/ubsan-bitfield-conversion.cpp (revision 3009228a09dbfe04e0911fc19813ec72d389bc45)
1 // RUN: %clang -x c++ -fsanitize=implicit-bitfield-conversion -target x86_64-linux -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-BITFIELD-CONVERSION
2 // RUN: %clang -x c++ -fsanitize=implicit-integer-conversion -target x86_64-linux -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK
3 // RUN: %clang -x c++ -fsanitize=implicit-conversion -target x86_64-linux -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-BITFIELD-CONVERSION
4 
5 struct S {
6   int a:3;
7   char b:2;
8 };
9 
10 class C : public S {
11   public:
12     short c:3;
13 };
14 
15 S s;
16 C c;
17 
18 // CHECK-LABEL: define{{.*}} void @{{.*foo1.*}}
foo1(int x)19 void foo1(int x) {
20   s.a = x;
21   // CHECK: store i8 %{{.*}}
22   // CHECK-BITFIELD-CONVERSION: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 5
23   // CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
24   // CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
25   // CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
26   // CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
27   c.a = x;
28   // CHECK: store i8 %{{.*}}
29   // CHECK-BITFIELD-CONVERSION: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 5
30   // CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
31   // CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
32   // CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
33   // CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
34   // CHECK-BITFIELD-CONVERSION: [[CONT]]:
35   // CHECK-NEXT: ret void
36 }
37 
38 // CHECK-LABEL: define{{.*}} void @{{.*foo2.*}}
foo2(int x)39 void foo2(int x) {
40   s.b = x;
41   // CHECK: store i8 %{{.*}}
42   // CHECK-BITFIELD-CONVERSION: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 6
43   // CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 6
44   // CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
45   // CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
46   c.b = x;
47   // CHECK: store i8 %{{.*}}
48   // CHECK-BITFIELD-CONVERSION: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 6
49   // CHECK-BITFIELD-CONVERSION-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 6
50   // CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
51   // CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
52   // CHECK-BITFIELD-CONVERSION: [[CONT]]:
53   // CHECK-NEXT: ret void
54 }
55 
56 // CHECK-LABEL: define{{.*}} void @{{.*foo3.*}}
foo3()57 void foo3() {
58   s.a++;
59   // CHECK: store i8 %{{.*}}
60   // CHECK-NEXT: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 5
61   // CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
62   // CHECK-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
63   // CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
64   // CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
65   c.a++;
66   // CHECK: store i8 %{{.*}}
67   // CHECK-NEXT: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 5
68   // CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
69   // CHECK-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
70   // CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
71   // CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
72   // CHECK-BITFIELD-CONVERSION: [[CONT]]:
73   // CHECK-NEXT: ret void
74 }
75 
76 // CHECK-LABEL: define{{.*}} void @{{.*foo4.*}}
foo4(int x)77 void foo4(int x) {
78   s.a += x;
79   // CHECK: store i8 %{{.*}}
80   // CHECK-NEXT: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 5
81   // CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
82   // CHECK-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
83   // CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
84   // CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
85   c.a += x;
86   // CHECK: store i8 %{{.*}}
87   // CHECK-NEXT: [[BFRESULTSHL:%.*]] = shl i8 {{.*}}, 5
88   // CHECK-NEXT: [[BFRESULTASHR:%.*]] = ashr i8 [[BFRESULTSHL]], 5
89   // CHECK-NEXT: [[BFRESULTCAST:%.*]] = sext i8 [[BFRESULTASHR]] to i32
90   // CHECK-BITFIELD-CONVERSION: call void @__ubsan_handle_implicit_conversion
91   // CHECK-BITFIELD-CONVERSION-NEXT: br label %[[CONT:.*]], !nosanitize
92   // CHECK-BITFIELD-CONVERSION: [[CONT]]:
93   // CHECK-NEXT: ret void
94 }