summaryrefslogtreecommitdiff
path: root/test/ubsan
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2018-07-30 18:58:30 +0000
committerRoman Lebedev <lebedev.ri@gmail.com>2018-07-30 18:58:30 +0000
commit5f775cc5e961dbe81b655e79247234cfb8295a3d (patch)
tree469a3cc78861cfdfd0272f5f25169fcb1ce30c62 /test/ubsan
parent1c06b114805c7b7a5468a501ab874bf3fe5202f1 (diff)
downloadcompiler-rt-5f775cc5e961dbe81b655e79247234cfb8295a3d.tar.gz
[compiler-rt][ubsan] Implicit Conversion Sanitizer - integer truncation - compiler-rt part
Summary: This is a compiler-rt part. The clang part is D48958. See [[ https://bugs.llvm.org/show_bug.cgi?id=21530 | PR21530 ]], https://github.com/google/sanitizers/issues/940. Reviewers: #sanitizers, samsonov, vsk, rsmith, pcc, eugenis, kcc, filcab Reviewed By: #sanitizers, vsk, filcab Subscribers: llvm-commits, eugenis, filcab, kubamracek, dberris, #sanitizers, regehr Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D48959 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@338287 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/ubsan')
-rw-r--r--test/ubsan/TestCases/ImplicitCast/integer-truncation-blacklist.c15
-rw-r--r--test/ubsan/TestCases/ImplicitCast/integer-truncation-summary.cpp13
-rw-r--r--test/ubsan/TestCases/ImplicitCast/integer-truncation.c63
3 files changed, 91 insertions, 0 deletions
diff --git a/test/ubsan/TestCases/ImplicitCast/integer-truncation-blacklist.c b/test/ubsan/TestCases/ImplicitCast/integer-truncation-blacklist.c
new file mode 100644
index 000000000..221c04b60
--- /dev/null
+++ b/test/ubsan/TestCases/ImplicitCast/integer-truncation-blacklist.c
@@ -0,0 +1,15 @@
+// RUN: rm -f %tmp
+// RUN: echo "[implicit-integer-truncation]" >> %tmp
+// RUN: echo "fun:*implicitTruncation*" >> %tmp
+// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1
+// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1
+// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1
+// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1
+
+unsigned char implicitTruncation(unsigned int argc) {
+ return argc; // BOOM
+}
+
+int main(int argc, char **argv) {
+ return implicitTruncation(~0U);
+}
diff --git a/test/ubsan/TestCases/ImplicitCast/integer-truncation-summary.cpp b/test/ubsan/TestCases/ImplicitCast/integer-truncation-summary.cpp
new file mode 100644
index 000000000..a92e01fb4
--- /dev/null
+++ b/test/ubsan/TestCases/ImplicitCast/integer-truncation-summary.cpp
@@ -0,0 +1,13 @@
+// RUN: %clangxx -fsanitize=implicit-integer-truncation %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOTYPE
+// RUN: %env_ubsan_opts=report_error_type=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TYPE
+// REQUIRES: !ubsan-standalone && !ubsan-standalone-static
+
+#include <stdint.h>
+
+int main() {
+ uint8_t t0 = (~(uint32_t(0)));
+ // CHECK-NOTYPE: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior {{.*}}summary.cpp:[[@LINE-1]]:16
+ // CHECK-TYPE: SUMMARY: UndefinedBehaviorSanitizer: implicit-integer-truncation {{.*}}summary.cpp:[[@LINE-2]]:16
+ return 0;
+}
diff --git a/test/ubsan/TestCases/ImplicitCast/integer-truncation.c b/test/ubsan/TestCases/ImplicitCast/integer-truncation.c
new file mode 100644
index 000000000..995eb7d0f
--- /dev/null
+++ b/test/ubsan/TestCases/ImplicitCast/integer-truncation.c
@@ -0,0 +1,63 @@
+// RUN: %clang -x c -fsanitize=implicit-integer-truncation %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+// RUN: %clangxx -x c++ -fsanitize=implicit-integer-truncation %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+
+#include <stdint.h>
+
+#if !defined(__cplusplus)
+#define bool _Bool
+#endif
+
+int main() {
+// CHECK-NOT: integer-truncation.c
+
+ // Negative tests. Even if they produce unexpected results, this sanitizer does not care.
+ int8_t n0 = (~((uint32_t)0)); // ~0 -> -1, but do not warn.
+ uint8_t n2 = 128;
+ uint8_t n3 = 255;
+ // Bools do not count
+ bool b0 = (~((uint32_t)0));
+ bool b1 = 255;
+
+ // Explicit and-ing of bits will silence it.
+ uint8_t nc0 = (~((uint32_t)0)) & 255;
+
+ // Explicit casts
+ uint8_t i0 = (uint8_t)(~((uint32_t)0));
+
+#if defined(__cplusplus)
+ uint8_t i1 = uint8_t(~(uint32_t(0)));
+ uint8_t i2 = static_cast<uint8_t>(~(uint32_t(0)));
+#endif
+
+ // Positive tests.
+
+ uint8_t t_b0 = (~((uint16_t)(0)));
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:18: runtime error: implicit conversion from type 'int' of value -1 (32-bit, signed) to type 'uint8_t' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned)
+
+ uint8_t t_b1 = (~((uint32_t)0));
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:18: runtime error: implicit conversion from type 'uint32_t' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type 'uint8_t' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned)
+ uint16_t t_b2 = (~((uint32_t)0));
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:19: runtime error: implicit conversion from type 'uint32_t' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type 'uint16_t' (aka 'unsigned short') changed the value to 65535 (16-bit, unsigned)
+
+ uint8_t t_b3 = ~((uint64_t)0);
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:18: runtime error: implicit conversion from type 'uint64_t' (aka 'unsigned long{{[^']*}}') of value 18446744073709551615 (64-bit, unsigned) to type 'uint8_t' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned)
+ uint16_t t_b4 = ~((uint64_t)0);
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:19: runtime error: implicit conversion from type 'uint64_t' (aka 'unsigned long{{[^']*}}') of value 18446744073709551615 (64-bit, unsigned) to type 'uint16_t' (aka 'unsigned short') changed the value to 65535 (16-bit, unsigned)
+ uint32_t t_b5 = ~((uint64_t)0);
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:19: runtime error: implicit conversion from type 'uint64_t' (aka 'unsigned long{{[^']*}}') of value 18446744073709551615 (64-bit, unsigned) to type 'uint32_t' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned)
+
+ int8_t t1 = 255;
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 255 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to -1 (8-bit, signed)
+ uint8_t t2 = 256;
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:16: runtime error: implicit conversion from type 'int' of value 256 (32-bit, signed) to type 'uint8_t' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned)
+ int8_t t3 = 256;
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 256 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to 0 (8-bit, signed)
+ uint8_t t4 = 257;
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:16: runtime error: implicit conversion from type 'int' of value 257 (32-bit, signed) to type 'uint8_t' (aka 'unsigned char') changed the value to 1 (8-bit, unsigned)
+ int8_t t5 = 257;
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 257 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to 1 (8-bit, signed)
+ int8_t t6 = 128;
+// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 128 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to -128 (8-bit, signed)
+
+ return 0;
+}