diff options
7 files changed, 103 insertions, 14 deletions
diff --git a/compiler-rt/lib/ubsan/lit_tests/Integer/div-zero.cpp b/compiler-rt/lib/ubsan/lit_tests/Integer/div-zero.cpp index 7d7171135e1..f024835ff83 100644 --- a/compiler-rt/lib/ubsan/lit_tests/Integer/div-zero.cpp +++ b/compiler-rt/lib/ubsan/lit_tests/Integer/div-zero.cpp @@ -1,7 +1,7 @@ -// RUN: %clang -fsanitize=divide-by-zero -DDIVIDEND=0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clang -fsanitize=divide-by-zero -DDIVIDEND=1U %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clang -fsanitize=divide-by-zero -DDIVIDEND=1.5 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clang -fsanitize=divide-by-zero -DDIVIDEND='__int128(123)' %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang -fsanitize=integer-divide-by-zero -DDIVIDEND=0 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang -fsanitize=integer-divide-by-zero -DDIVIDEND=1U %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang -fsanitize=float-divide-by-zero -DDIVIDEND=1.5 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clang -fsanitize=integer-divide-by-zero -DDIVIDEND='__int128(123)' %s -o %t && %t 2>&1 | FileCheck %s int main() { // CHECK: div-zero.cpp:8:12: fatal error: division by zero diff --git a/compiler-rt/lib/ubsan/lit_tests/Integer/uadd-overflow.cpp b/compiler-rt/lib/ubsan/lit_tests/Integer/uadd-overflow.cpp new file mode 100644 index 00000000000..bd25bd72130 --- /dev/null +++ b/compiler-rt/lib/ubsan/lit_tests/Integer/uadd-overflow.cpp @@ -0,0 +1,27 @@ +// RUN: %clang -DADD_I32 -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck %s --check-prefix=ADD_I32 +// RUN: %clang -DADD_I64 -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck %s --check-prefix=ADD_I64 +// RUN: %clang -DADD_I128 -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck %s --check-prefix=ADD_I128 + +#include <stdint.h> + +int main() { + // These promote to 'int'. + (void)(uint8_t(0xff) + uint8_t(0xff)); + (void)(uint16_t(0xf0fff) + uint16_t(0x0fff)); + +#ifdef ADD_I32 + uint32_t k = 0x87654321; + k += 0xedcba987; + // CHECK-ADD_I32: uadd-overflow.cpp:14:5: fatal error: unsigned integer overflow: 2271560481 + 3989547399 cannot be represented in type 'uint32_t' (aka 'unsigned int') +#endif + +#ifdef ADD_I64 + (void)(uint64_t(10000000000000000000ull) + uint64_t(9000000000000000000ull)); + // CHECK-ADD_I64: 10000000000000000000 + 9000000000000000000 cannot be represented in type 'unsigned long' +#endif + +#ifdef ADD_I128 + (void)((__uint128_t(1) << 127) + (__uint128_t(1) << 127)); + // CHECK-ADD_I128: 0x80000000000000000000000000000000 + 0x80000000000000000000000000000000 cannot be represented in type 'unsigned __int128' +#endif +} diff --git a/compiler-rt/lib/ubsan/lit_tests/Integer/uincdec-overflow.cpp b/compiler-rt/lib/ubsan/lit_tests/Integer/uincdec-overflow.cpp new file mode 100644 index 00000000000..45df7088312 --- /dev/null +++ b/compiler-rt/lib/ubsan/lit_tests/Integer/uincdec-overflow.cpp @@ -0,0 +1,16 @@ +// RUN: %clang -DOP=n++ -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck --check-prefix=INC %s +// RUN: %clang -DOP=++n -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck --check-prefix=INC %s +// RUN: %clang -DOP=m-- -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck --check-prefix=DEC %s +// RUN: %clang -DOP=--m -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck --check-prefix=DEC %s + +#include <stdint.h> + +int main() { + unsigned n = 0xfffffffd; + n++; + n++; + unsigned m = 0; + // CHECK-INC: uincdec-overflow.cpp:15:3: fatal error: unsigned integer overflow: 4294967295 + 1 cannot be represented in type 'unsigned int' + // CHECK-DEC: uincdec-overflow.cpp:15:3: fatal error: unsigned integer overflow: 0 - 1 cannot be represented in type 'unsigned int' + OP; +} diff --git a/compiler-rt/lib/ubsan/lit_tests/Integer/umul-overflow.cpp b/compiler-rt/lib/ubsan/lit_tests/Integer/umul-overflow.cpp new file mode 100644 index 00000000000..6b15e1bdbcb --- /dev/null +++ b/compiler-rt/lib/ubsan/lit_tests/Integer/umul-overflow.cpp @@ -0,0 +1,19 @@ +// RUN: %clang -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck %s + +#include <stdint.h> + +int main() { + // These promote to 'int'. + (void)(int8_t(-2) * int8_t(0x7f)); + (void)(int16_t(0x7fff) * int16_t(0x7fff)); + (void)(uint16_t(0xffff) * int16_t(0x7fff)); + (void)(uint16_t(0xffff) * uint16_t(0x8000)); + + // Not an unsigned overflow + (void)(uint16_t(0xffff) * uint16_t(0x8001)); + + (void)(uint32_t(0xffffffff) * uint32_t(0x2)); + // CHECK: umul-overflow.cpp:15:31: fatal error: unsigned integer overflow: 4294967295 * 2 cannot be represented in type 'unsigned int' + + return 0; +} diff --git a/compiler-rt/lib/ubsan/lit_tests/Integer/usub-overflow.cpp b/compiler-rt/lib/ubsan/lit_tests/Integer/usub-overflow.cpp new file mode 100644 index 00000000000..e91810b4b8e --- /dev/null +++ b/compiler-rt/lib/ubsan/lit_tests/Integer/usub-overflow.cpp @@ -0,0 +1,26 @@ +// RUN: %clang -DSUB_I32 -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck %s --check-prefix=SUB_I32 +// RUN: %clang -DSUB_I64 -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck %s --check-prefix=SUB_I64 +// RUN: %clang -DSUB_I128 -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck %s --check-prefix=SUB_I128 + +#include <stdint.h> + +int main() { + // These promote to 'int'. + (void)(uint8_t(0) - uint8_t(0x7f)); + (void)(uint16_t(0) - uint16_t(0x7fff)); + +#ifdef SUB_I32 + (void)(uint32_t(1) - uint32_t(2)); + // CHECK-SUB_I32: usub-overflow.cpp:13:22: fatal error: unsigned integer overflow: 1 - 2 cannot be represented in type 'unsigned int' +#endif + +#ifdef SUB_I64 + (void)(uint64_t(8000000000000000000ll) - uint64_t(9000000000000000000ll)); + // CHECK-SUB_I64: 8000000000000000000 - 9000000000000000000 cannot be represented in type 'unsigned long' +#endif + +#ifdef SUB_I128 + (void)((__uint128_t(1) << 126) - (__uint128_t(1) << 127)); + // CHECK-SUB_I128: 0x40000000000000000000000000000000 - 0x80000000000000000000000000000000 cannot be represented in type 'unsigned __int128' +#endif +} diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.cc b/compiler-rt/lib/ubsan/ubsan_handlers.cc index a8df7831d69..6f5a8219868 100644 --- a/compiler-rt/lib/ubsan/ubsan_handlers.cc +++ b/compiler-rt/lib/ubsan/ubsan_handlers.cc @@ -43,30 +43,31 @@ void __ubsan::__ubsan_handle_type_mismatch(TypeMismatchData *Data, Die(); } -/// \brief Common diagnostic emission for various forms of signed overflow. -template<typename T> static void HandleSignedOverflow(OverflowData *Data, +/// \brief Common diagnostic emission for various forms of integer overflow. +template<typename T> static void HandleIntegerOverflow(OverflowData *Data, ValueHandle LHS, const char *Operator, T RHS) { - Diag(Data->Loc, "signed integer overflow: " - "%0 %1 %2 cannot be represented in type %3") + Diag(Data->Loc, "%0 integer overflow: " + "%1 %2 %3 cannot be represented in type %4") + << (Data->Type.isSignedIntegerTy() ? "signed" : "unsigned") << Value(Data->Type, LHS) << Operator << RHS << Data->Type; Die(); } void __ubsan::__ubsan_handle_add_overflow(OverflowData *Data, ValueHandle LHS, ValueHandle RHS) { - HandleSignedOverflow(Data, LHS, "+", Value(Data->Type, RHS)); + HandleIntegerOverflow(Data, LHS, "+", Value(Data->Type, RHS)); } void __ubsan::__ubsan_handle_sub_overflow(OverflowData *Data, ValueHandle LHS, ValueHandle RHS) { - HandleSignedOverflow(Data, LHS, "-", Value(Data->Type, RHS)); + HandleIntegerOverflow(Data, LHS, "-", Value(Data->Type, RHS)); } void __ubsan::__ubsan_handle_mul_overflow(OverflowData *Data, ValueHandle LHS, ValueHandle RHS) { - HandleSignedOverflow(Data, LHS, "*", Value(Data->Type, RHS)); + HandleIntegerOverflow(Data, LHS, "*", Value(Data->Type, RHS)); } void __ubsan::__ubsan_handle_negate_overflow(OverflowData *Data, diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.h b/compiler-rt/lib/ubsan/ubsan_handlers.h index dc61fd3e426..f7bd56c0663 100644 --- a/compiler-rt/lib/ubsan/ubsan_handlers.h +++ b/compiler-rt/lib/ubsan/ubsan_handlers.h @@ -35,15 +35,15 @@ struct OverflowData { const TypeDescriptor &Type; }; -/// \brief Handle a signed integer addition overflow. +/// \brief Handle an integer addition overflow. extern "C" void __ubsan_handle_add_overflow(OverflowData *Data, ValueHandle LHS, ValueHandle RHS); -/// \brief Handle a signed integer subtraction overflow. +/// \brief Handle an integer subtraction overflow. extern "C" void __ubsan_handle_sub_overflow(OverflowData *Data, ValueHandle LHS, ValueHandle RHS); -/// \brief Handle a signed integer multiplication overflow. +/// \brief Handle an integer multiplication overflow. extern "C" void __ubsan_handle_mul_overflow(OverflowData *Data, ValueHandle LHS, ValueHandle RHS); |

