1 // RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK 2 // RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fno-sanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE 3 // RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-recover=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE 4 // RUN: %clang_cc1 -fsanitize=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -fsanitize-trap=implicit-unsigned-integer-truncation,implicit-signed-integer-truncation -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,CHECK-SANITIZE 5 6 extern "C" { // Disable name mangling. 7 8 // ========================================================================== // 9 // Check that explicit cast does not interfere with implicit conversion 10 // ========================================================================== // 11 // These contain one implicit truncating conversion, and one explicit truncating cast. 12 // We want to make sure that we still diagnose the implicit conversion. 13 14 // Implicit truncation after explicit truncation. 15 // CHECK-LABEL: @explicit_cast_interference0 16 unsigned char explicit_cast_interference0(unsigned int c) { 17 // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i8 %[[DST:.*]] to i16, !nosanitize 18 // CHECK-SANITIZE: call 19 // CHECK-SANITIZE-NOT: call 20 // CHECK: } 21 return (unsigned short)c; 22 } 23 24 // Implicit truncation before explicit truncation. 25 // CHECK-LABEL: @explicit_cast_interference1 26 unsigned char explicit_cast_interference1(unsigned int c) { 27 // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i16 %[[DST:.*]] to i32, !nosanitize 28 // CHECK-SANITIZE: call 29 // CHECK-SANITIZE-NOT: call 30 // CHECK: } 31 unsigned short b; 32 return (unsigned char)(b = c); 33 } 34 35 // ========================================================================== // 36 // The expected true-negatives. 37 // ========================================================================== // 38 39 // Explicit truncating casts. 40 // ========================================================================== // 41 42 // CHECK-LABEL: @explicit_unsigned_int_to_unsigned_char 43 unsigned char explicit_unsigned_int_to_unsigned_char(unsigned int src) { 44 // CHECK-SANITIZE-NOT: call 45 // CHECK: } 46 return (unsigned char)src; 47 } 48 49 // CHECK-LABEL: @explicit_signed_int_to_unsigned_char 50 unsigned char explicit_signed_int_to_unsigned_char(signed int src) { 51 // CHECK-SANITIZE-NOT: call 52 // CHECK: } 53 return (unsigned char)src; 54 } 55 56 // CHECK-LABEL: @explicit_unsigned_int_to_signed_char 57 signed char explicit_unsigned_int_to_signed_char(unsigned int src) { 58 // CHECK-SANITIZE-NOT: call 59 // CHECK: } 60 return (signed char)src; 61 } 62 63 // CHECK-LABEL: @explicit_signed_int_to_signed_char 64 signed char explicit_signed_int_to_signed_char(signed int src) { 65 // CHECK-SANITIZE-NOT: call 66 // CHECK: } 67 return (signed char)src; 68 } 69 70 // Explicit NOP casts. 71 // ========================================================================== // 72 73 // CHECK-LABEL: @explicit_unsigned_int_to_unsigned_int 74 unsigned int explicit_unsigned_int_to_unsigned_int(unsigned int src) { 75 // CHECK-SANITIZE-NOT: call 76 // CHECK: } 77 return (unsigned int)src; 78 } 79 80 // CHECK-LABEL: @explicit_signed_int_to_signed_int 81 signed int explicit_signed_int_to_signed_int(signed int src) { 82 // CHECK-SANITIZE-NOT: call 83 // CHECK: } 84 return (signed int)src; 85 } 86 87 // CHECK-LABEL: @explicit_unsigned_char_to_signed_char 88 unsigned char explicit_unsigned_char_to_signed_char(unsigned char src) { 89 // CHECK-SANITIZE-NOT: call 90 // CHECK: } 91 return (unsigned char)src; 92 } 93 94 // CHECK-LABEL: @explicit_signed_char_to_signed_char 95 signed char explicit_signed_char_to_signed_char(signed char src) { 96 // CHECK-SANITIZE-NOT: call 97 // CHECK: } 98 return (signed char)src; 99 } 100 101 // Explicit functional truncating casts. 102 // ========================================================================== // 103 104 using UnsignedChar = unsigned char; 105 using SignedChar = signed char; 106 using UnsignedInt = unsigned int; 107 using SignedInt = signed int; 108 109 // CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_char 110 unsigned char explicit_functional_unsigned_int_to_unsigned_char(unsigned int src) { 111 // CHECK-SANITIZE-NOT: call 112 // CHECK: } 113 return UnsignedChar(src); 114 } 115 116 // CHECK-LABEL: @explicit_functional_signed_int_to_unsigned_char 117 unsigned char explicit_functional_signed_int_to_unsigned_char(signed int src) { 118 // CHECK-SANITIZE-NOT: call 119 // CHECK: } 120 return UnsignedChar(src); 121 } 122 123 // CHECK-LABEL: @explicit_functional_unsigned_int_to_signed_char 124 signed char explicit_functional_unsigned_int_to_signed_char(unsigned int src) { 125 // CHECK-SANITIZE-NOT: call 126 // CHECK: } 127 return SignedChar(src); 128 } 129 130 // CHECK-LABEL: @explicit_functional_signed_int_to_signed_char 131 signed char explicit_functional_signed_int_to_signed_char(signed int src) { 132 // CHECK-SANITIZE-NOT: call 133 // CHECK: } 134 return SignedChar(src); 135 } 136 137 // Explicit functional NOP casts. 138 // ========================================================================== // 139 140 // CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_int 141 unsigned int explicit_functional_unsigned_int_to_unsigned_int(unsigned int src) { 142 // CHECK-SANITIZE-NOT: call 143 // CHECK: } 144 return UnsignedInt(src); 145 } 146 147 // CHECK-LABEL: @explicit_functional_signed_int_to_signed_int 148 signed int explicit_functional_signed_int_to_signed_int(signed int src) { 149 // CHECK-SANITIZE-NOT: call 150 // CHECK: } 151 return SignedInt(src); 152 } 153 154 // CHECK-LABEL: @explicit_functional_unsigned_char_to_signed_char 155 unsigned char explicit_functional_unsigned_char_to_signed_char(unsigned char src) { 156 // CHECK-SANITIZE-NOT: call 157 // CHECK: } 158 return UnsignedChar(src); 159 } 160 161 // CHECK-LABEL: @explicit_functional_signed_char_to_signed_char 162 signed char explicit_functional_signed_char_to_signed_char(signed char src) { 163 // CHECK-SANITIZE-NOT: call 164 // CHECK: } 165 return SignedChar(src); 166 } 167 168 // Explicit C++-style casts truncating casts. 169 // ========================================================================== // 170 171 // CHECK-LABEL: @explicit_cppstyleunsigned_int_to_unsigned_char 172 unsigned char explicit_cppstyleunsigned_int_to_unsigned_char(unsigned int src) { 173 // CHECK-SANITIZE-NOT: call 174 // CHECK: } 175 return static_cast<unsigned char>(src); 176 } 177 178 // CHECK-LABEL: @explicit_cppstylesigned_int_to_unsigned_char 179 unsigned char explicit_cppstylesigned_int_to_unsigned_char(signed int src) { 180 // CHECK-SANITIZE-NOT: call 181 // CHECK: } 182 return static_cast<unsigned char>(src); 183 } 184 185 // CHECK-LABEL: @explicit_cppstyleunsigned_int_to_signed_char 186 signed char explicit_cppstyleunsigned_int_to_signed_char(unsigned int src) { 187 // CHECK-SANITIZE-NOT: call 188 // CHECK: } 189 return static_cast<signed char>(src); 190 } 191 192 // CHECK-LABEL: @explicit_cppstylesigned_int_to_signed_char 193 signed char explicit_cppstylesigned_int_to_signed_char(signed int src) { 194 // CHECK-SANITIZE-NOT: call 195 // CHECK: } 196 return static_cast<signed char>(src); 197 } 198 199 // Explicit C++-style casts NOP casts. 200 // ========================================================================== // 201 202 // CHECK-LABEL: @explicit_cppstyleunsigned_int_to_unsigned_int 203 unsigned int explicit_cppstyleunsigned_int_to_unsigned_int(unsigned int src) { 204 // CHECK-SANITIZE-NOT: call 205 // CHECK: } 206 return static_cast<unsigned int>(src); 207 } 208 209 // CHECK-LABEL: @explicit_cppstylesigned_int_to_signed_int 210 signed int explicit_cppstylesigned_int_to_signed_int(signed int src) { 211 // CHECK-SANITIZE-NOT: call 212 // CHECK: } 213 return static_cast<signed int>(src); 214 } 215 216 // CHECK-LABEL: @explicit_cppstyleunsigned_char_to_signed_char 217 unsigned char explicit_cppstyleunsigned_char_to_signed_char(unsigned char src) { 218 // CHECK-SANITIZE-NOT: call 219 // CHECK: } 220 return static_cast<unsigned char>(src); 221 } 222 223 // CHECK-LABEL: @explicit_cppstylesigned_char_to_signed_char 224 signed char explicit_cppstylesigned_char_to_signed_char(signed char src) { 225 // CHECK-SANITIZE-NOT: call 226 // CHECK: } 227 return static_cast<signed char>(src); 228 } 229 230 } // extern "C" 231 232 // ---------------------------------------------------------------------------// 233 // A problematic true-negative involving simple C++ code. 234 // The problem is tha the NoOp ExplicitCast is directly within MaterializeTemporaryExpr(), 235 // so a special care is neeeded. 236 // See https://reviews.llvm.org/D48958#1161345 237 template <typename a> 238 a b(a c, const a &d) { 239 if (d) 240 ; 241 return c; 242 } 243 244 extern "C" { // Disable name mangling. 245 246 // CHECK-LABEL: @false_positive_with_MaterializeTemporaryExpr 247 int false_positive_with_MaterializeTemporaryExpr() { 248 // CHECK-SANITIZE-NOT: call{{.*}}ubsan 249 // CHECK: } 250 int e = b<unsigned>(4, static_cast<unsigned>(4294967296)); 251 return e; 252 } 253 254 // ---------------------------------------------------------------------------// 255 256 } // extern "C" 257