257 lines · cpp
1// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK2// 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-SANITIZE3// 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-SANITIZE4// 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-SANITIZE5 6extern "C" { // Disable name mangling.7 8// ========================================================================== //9// Check that explicit cast does not interfere with implicit conversion10// ========================================================================== //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_interference016unsigned char explicit_cast_interference0(unsigned int c) {17 // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i8 %[[DST:.*]] to i16, !nosanitize18 // CHECK-SANITIZE: call19 // CHECK-SANITIZE-NOT: call20 // CHECK: }21 return (unsigned short)c;22}23 24// Implicit truncation before explicit truncation.25// CHECK-LABEL: @explicit_cast_interference126unsigned char explicit_cast_interference1(unsigned int c) {27 // CHECK-SANITIZE: %[[ANYEXT:.*]] = zext i16 %[[DST:.*]] to i32, !nosanitize28 // CHECK-SANITIZE: call29 // CHECK-SANITIZE-NOT: call30 // 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_char43unsigned char explicit_unsigned_int_to_unsigned_char(unsigned int src) {44 // CHECK-SANITIZE-NOT: call45 // CHECK: }46 return (unsigned char)src;47}48 49// CHECK-LABEL: @explicit_signed_int_to_unsigned_char50unsigned char explicit_signed_int_to_unsigned_char(signed int src) {51 // CHECK-SANITIZE-NOT: call52 // CHECK: }53 return (unsigned char)src;54}55 56// CHECK-LABEL: @explicit_unsigned_int_to_signed_char57signed char explicit_unsigned_int_to_signed_char(unsigned int src) {58 // CHECK-SANITIZE-NOT: call59 // CHECK: }60 return (signed char)src;61}62 63// CHECK-LABEL: @explicit_signed_int_to_signed_char64signed char explicit_signed_int_to_signed_char(signed int src) {65 // CHECK-SANITIZE-NOT: call66 // CHECK: }67 return (signed char)src;68}69 70// Explicit NOP casts.71// ========================================================================== //72 73// CHECK-LABEL: @explicit_unsigned_int_to_unsigned_int74unsigned int explicit_unsigned_int_to_unsigned_int(unsigned int src) {75 // CHECK-SANITIZE-NOT: call76 // CHECK: }77 return (unsigned int)src;78}79 80// CHECK-LABEL: @explicit_signed_int_to_signed_int81signed int explicit_signed_int_to_signed_int(signed int src) {82 // CHECK-SANITIZE-NOT: call83 // CHECK: }84 return (signed int)src;85}86 87// CHECK-LABEL: @explicit_unsigned_char_to_signed_char88unsigned char explicit_unsigned_char_to_signed_char(unsigned char src) {89 // CHECK-SANITIZE-NOT: call90 // CHECK: }91 return (unsigned char)src;92}93 94// CHECK-LABEL: @explicit_signed_char_to_signed_char95signed char explicit_signed_char_to_signed_char(signed char src) {96 // CHECK-SANITIZE-NOT: call97 // CHECK: }98 return (signed char)src;99}100 101// Explicit functional truncating casts.102// ========================================================================== //103 104using UnsignedChar = unsigned char;105using SignedChar = signed char;106using UnsignedInt = unsigned int;107using SignedInt = signed int;108 109// CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_char110unsigned char explicit_functional_unsigned_int_to_unsigned_char(unsigned int src) {111 // CHECK-SANITIZE-NOT: call112 // CHECK: }113 return UnsignedChar(src);114}115 116// CHECK-LABEL: @explicit_functional_signed_int_to_unsigned_char117unsigned char explicit_functional_signed_int_to_unsigned_char(signed int src) {118 // CHECK-SANITIZE-NOT: call119 // CHECK: }120 return UnsignedChar(src);121}122 123// CHECK-LABEL: @explicit_functional_unsigned_int_to_signed_char124signed char explicit_functional_unsigned_int_to_signed_char(unsigned int src) {125 // CHECK-SANITIZE-NOT: call126 // CHECK: }127 return SignedChar(src);128}129 130// CHECK-LABEL: @explicit_functional_signed_int_to_signed_char131signed char explicit_functional_signed_int_to_signed_char(signed int src) {132 // CHECK-SANITIZE-NOT: call133 // CHECK: }134 return SignedChar(src);135}136 137// Explicit functional NOP casts.138// ========================================================================== //139 140// CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_int141unsigned int explicit_functional_unsigned_int_to_unsigned_int(unsigned int src) {142 // CHECK-SANITIZE-NOT: call143 // CHECK: }144 return UnsignedInt(src);145}146 147// CHECK-LABEL: @explicit_functional_signed_int_to_signed_int148signed int explicit_functional_signed_int_to_signed_int(signed int src) {149 // CHECK-SANITIZE-NOT: call150 // CHECK: }151 return SignedInt(src);152}153 154// CHECK-LABEL: @explicit_functional_unsigned_char_to_signed_char155unsigned char explicit_functional_unsigned_char_to_signed_char(unsigned char src) {156 // CHECK-SANITIZE-NOT: call157 // CHECK: }158 return UnsignedChar(src);159}160 161// CHECK-LABEL: @explicit_functional_signed_char_to_signed_char162signed char explicit_functional_signed_char_to_signed_char(signed char src) {163 // CHECK-SANITIZE-NOT: call164 // CHECK: }165 return SignedChar(src);166}167 168// Explicit C++-style casts truncating casts.169// ========================================================================== //170 171// CHECK-LABEL: @explicit_cppstyleunsigned_int_to_unsigned_char172unsigned char explicit_cppstyleunsigned_int_to_unsigned_char(unsigned int src) {173 // CHECK-SANITIZE-NOT: call174 // CHECK: }175 return static_cast<unsigned char>(src);176}177 178// CHECK-LABEL: @explicit_cppstylesigned_int_to_unsigned_char179unsigned char explicit_cppstylesigned_int_to_unsigned_char(signed int src) {180 // CHECK-SANITIZE-NOT: call181 // CHECK: }182 return static_cast<unsigned char>(src);183}184 185// CHECK-LABEL: @explicit_cppstyleunsigned_int_to_signed_char186signed char explicit_cppstyleunsigned_int_to_signed_char(unsigned int src) {187 // CHECK-SANITIZE-NOT: call188 // CHECK: }189 return static_cast<signed char>(src);190}191 192// CHECK-LABEL: @explicit_cppstylesigned_int_to_signed_char193signed char explicit_cppstylesigned_int_to_signed_char(signed int src) {194 // CHECK-SANITIZE-NOT: call195 // 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_int203unsigned int explicit_cppstyleunsigned_int_to_unsigned_int(unsigned int src) {204 // CHECK-SANITIZE-NOT: call205 // CHECK: }206 return static_cast<unsigned int>(src);207}208 209// CHECK-LABEL: @explicit_cppstylesigned_int_to_signed_int210signed int explicit_cppstylesigned_int_to_signed_int(signed int src) {211 // CHECK-SANITIZE-NOT: call212 // CHECK: }213 return static_cast<signed int>(src);214}215 216// CHECK-LABEL: @explicit_cppstyleunsigned_char_to_signed_char217unsigned char explicit_cppstyleunsigned_char_to_signed_char(unsigned char src) {218 // CHECK-SANITIZE-NOT: call219 // CHECK: }220 return static_cast<unsigned char>(src);221}222 223// CHECK-LABEL: @explicit_cppstylesigned_char_to_signed_char224signed char explicit_cppstylesigned_char_to_signed_char(signed char src) {225 // CHECK-SANITIZE-NOT: call226 // 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#1161345237template <typename a>238a b(a c, const a &d) {239 if (d)240 ;241 return c;242}243 244extern "C" { // Disable name mangling.245 246// CHECK-LABEL: @false_positive_with_MaterializeTemporaryExpr247int false_positive_with_MaterializeTemporaryExpr() {248 // CHECK-SANITIZE-NOT: call{{.*}}ubsan249 // CHECK: }250 int e = b<unsigned>(4, static_cast<unsigned>(4294967296));251 return e;252}253 254// ---------------------------------------------------------------------------//255 256} // extern "C"257