ubsan: Support unsigned overflows, and divide-by-zero int/float split.
llvm-svn: 168700
This commit is contained in:
parent
b7029398f3
commit
2631aaf939
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue