summaryrefslogtreecommitdiff
path: root/test/CodeGen/catch-implicit-integer-sign-changes-basics.c
blob: 71533a9b924a089243d3fe774e65918bee7cc610 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// RUN: %clang_cc1 -fsanitize=implicit-integer-sign-change -fsanitize-recover=implicit-integer-sign-change -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_implicit_conversion" --check-prefixes=CHECK

// Test plan:
//  * Two types - int and char
//  * Two signs - signed and unsigned
//  * Square that - we have input and output types.
// Thus, there are total of (2*2)^2 == 16 tests.
// These are all the possible variations/combinations of casts.
// However, not all of them should result in the check.
// So here, we *only* check which should and which should not result in checks.

// CHECK-DAG: @[[LINE_900_SIGN_CHANGE:.*]] = {{.*}}, i32 900, i32 10 }, {{.*}}, {{.*}}, i8 3 }
// CHECK-DAG: @[[LINE_1000_SIGN_CHANGE:.*]] = {{.*}}, i32 1000, i32 10 }, {{.*}}, {{.*}}, i8 3 }
// CHECK-DAG: @[[LINE_1100_SIGN_CHANGE:.*]] = {{.*}}, i32 1100, i32 10 }, {{.*}}, {{.*}}, i8 3 }
// CHECK-DAG: @[[LINE_1200_SIGN_CHANGE:.*]] = {{.*}}, i32 1200, i32 10 }, {{.*}}, {{.*}}, i8 3 }
// CHECK-DAG: @[[LINE_1300_SIGN_CHANGE:.*]] = {{.*}}, i32 1300, i32 10 }, {{.*}}, {{.*}}, i8 3 }
// CHECK-DAG: @[[LINE_1400_SIGN_CHANGE:.*]] = {{.*}}, i32 1400, i32 10 }, {{.*}}, {{.*}}, i8 3 }
// CHECK-DAG: @[[LINE_1500_SIGN_CHANGE:.*]] = {{.*}}, i32 1500, i32 10 }, {{.*}}, {{.*}}, i8 3 }
// CHECK-DAG: @[[LINE_1600_SIGN_CHANGE:.*]] = {{.*}}, i32 1600, i32 10 }, {{.*}}, {{.*}}, i8 3 }

//============================================================================//
// Half of the cases do not need the check.                                   //
//============================================================================//

//----------------------------------------------------------------------------//
// No cast happens at all. No check needed.
//----------------------------------------------------------------------------//

// CHECK-LABEL: @convert_unsigned_int_to_unsigned_int
unsigned int convert_unsigned_int_to_unsigned_int(unsigned int x) {
#line 100
  return x;
}

// CHECK-LABEL: @convert_unsigned_char_to_unsigned_char
unsigned char convert_unsigned_char_to_unsigned_char(unsigned char x) {
#line 200
  return x;
}

// CHECK-LABEL: @convert_signed_int_to_signed_int
signed int convert_signed_int_to_signed_int(signed int x) {
#line 300
  return x;
}

// CHECK-LABEL: @convert_signed_char_to_signed_char
signed char convert_signed_char_to_signed_char(signed char x) {
#line 400
  return x;
}

//----------------------------------------------------------------------------//
// Both types are unsigned. No check needed.
//----------------------------------------------------------------------------//

// CHECK-LABEL: @convert_unsigned_int_to_unsigned_char
unsigned char convert_unsigned_int_to_unsigned_char(unsigned int x) {
#line 500
  return x;
}

// CHECK-LABEL: @convert_unsigned_char_to_unsigned_int
unsigned int convert_unsigned_char_to_unsigned_int(unsigned char x) {
#line 600
  return x;
}

//----------------------------------------------------------------------------//
// Source type was unsigned, destination type is signed, but non-negative.
// Because zero-extension happens - the sign bit will be 0. No check needed.
//----------------------------------------------------------------------------//

// CHECK-LABEL: @convert_unsigned_char_to_signed_int
signed int convert_unsigned_char_to_signed_int(unsigned char x) {
#line 700
  return x;
}

//----------------------------------------------------------------------------//
// Both types are signed, and have the same sign, since sign-extension happens,
// i.e. the sign bit will be propagated. No check needed.
//----------------------------------------------------------------------------//

// CHECK-LABEL: @convert_signed_char_to_signed_int
signed int convert_signed_char_to_signed_int(signed char x) {
#line 800
  return x;
}

//============================================================================//
// The remaining 8 cases *do* need the check.                                 //
//============================================================================//

// These 3 result in simple 'icmp sge i32 %x, 0'

// CHECK-LABEL: @convert_unsigned_int_to_signed_int
signed int convert_unsigned_int_to_signed_int(unsigned int x) {
  // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_900_SIGN_CHANGE]] to i8*)
#line 900
  return x;
}

// CHECK-LABEL: @convert_signed_int_to_unsigned_int
unsigned int convert_signed_int_to_unsigned_int(signed int x) {
  // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1000_SIGN_CHANGE]] to i8*)
#line 1000
  return x;
}

// CHECK-LABEL: @convert_signed_int_to_unsigned_char
unsigned char convert_signed_int_to_unsigned_char(signed int x) {
  // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1100_SIGN_CHANGE]] to i8*)
#line 1100
  return x;
}

// These 3 result in simple 'icmp sge i8 %x, 0'

// CHECK-LABEL: @convert_signed_char_to_unsigned_char
unsigned char convert_signed_char_to_unsigned_char(signed char x) {
  // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1200_SIGN_CHANGE]] to i8*)
#line 1200
  return x;
}

// CHECK-LABEL: @convert_unsigned_char_to_signed_char
signed char convert_unsigned_char_to_signed_char(unsigned char x) {
  // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1300_SIGN_CHANGE]] to i8*)
#line 1300
  return x;
}

// CHECK-LABEL: @convert_signed_char_to_unsigned_int
unsigned int convert_signed_char_to_unsigned_int(signed char x) {
  // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1400_SIGN_CHANGE]] to i8*)
#line 1400
  return x;
}

// 'icmp sge i8 (trunc i32 %x), 0'

// CHECK-LABEL: @convert_unsigned_int_to_signed_char
signed char convert_unsigned_int_to_signed_char(unsigned int x) {
  // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1500_SIGN_CHANGE]] to i8*)
#line 1500
  return x;
}

// 'xor i1 (icmp sge i8 (trunc i32 %x), 0), (icmp sge i32 %x, 0)'

// CHECK-LABEL: @convert_signed_int_to_signed_char
signed char convert_signed_int_to_signed_char(signed int x) {
  // CHECK: call void @__ubsan_handle_implicit_conversion(i8* bitcast ({ {{{.*}}}, {{{.*}}}*, {{{.*}}}*, i8 }* @[[LINE_1600_SIGN_CHANGE]] to i8*)
#line 1600
  return x;
}