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(ptr @[[LINE_900_SIGN_CHANGE]]
#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(ptr @[[LINE_1000_SIGN_CHANGE]]
#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(ptr @[[LINE_1100_SIGN_CHANGE]]
#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(ptr @[[LINE_1200_SIGN_CHANGE]]
#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(ptr @[[LINE_1300_SIGN_CHANGE]]
#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(ptr @[[LINE_1400_SIGN_CHANGE]]
#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(ptr @[[LINE_1500_SIGN_CHANGE]]
#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(ptr @[[LINE_1600_SIGN_CHANGE]]
#line 1600
return x;
}
|