Currenly both Clang and GCC support the following set of flags that control code gen of signed overflow: * -fwrapv: overflow is defined as in two-complement * -ftrapv: overflow traps * -fsanitize=signed-integer-overflow: if undefined (no -fwrapv), then overflow behaviour is controlled by UBSan runtime, overrides -ftrapv Howerver, clang ignores these flags for __builtin_abs(int) and its higher-width versions, so passing minimum integer value always causes poison. The same holds for *abs(), which are not handled in frontend at all but folded to llvm.abs.* intrinsics during InstCombinePass. The intrinsics are not instrumented by UBSan, so the functions need special handling as well. This patch does a few things: * Handle *abs() in CGBuiltin the same way as __builtin_*abs() * -fsanitize=signed-integer-overflow now properly instruments abs() with UBSan * -fwrapv and -ftrapv handling for abs() is made consistent with GCC Fixes #45129 and #45794 Reviewed By: efriedma, MaskRay Differential Revision: https://reviews.llvm.org/D156821
29 lines
1.7 KiB
C++
29 lines
1.7 KiB
C++
// RUN: %clangxx -fsanitize=signed-integer-overflow -w %s -O3 -o %t
|
|
// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
|
|
|
|
// RUN: %clangxx -fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow -w %s -O3 -o %t.abort
|
|
// RUN: not %run %t.abort 2>&1 | FileCheck %s --check-prefix=ABORT
|
|
|
|
#include <limits.h>
|
|
#include <stdlib.h>
|
|
|
|
int main() {
|
|
// ABORT: abs.cpp:[[#@LINE+3]]:17: runtime error: negation of -[[#]] cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
|
|
// RECOVER: abs.cpp:[[#@LINE+2]]:17: runtime error: negation of -[[#]] cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
|
|
// RECOVER: abs.cpp:[[#@LINE+2]]:7: runtime error: negation of -[[#]] cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
|
|
__builtin_abs(INT_MIN);
|
|
abs(INT_MIN);
|
|
|
|
// RECOVER: abs.cpp:[[#@LINE+2]]:18: runtime error: negation of -[[#]] cannot be represented in type 'long'; cast to an unsigned type to negate this value to itself
|
|
// RECOVER: abs.cpp:[[#@LINE+2]]:8: runtime error: negation of -[[#]] cannot be represented in type 'long'; cast to an unsigned type to negate this value to itself
|
|
__builtin_labs(LONG_MIN);
|
|
labs(LONG_MIN);
|
|
|
|
// RECOVER: abs.cpp:[[#@LINE+2]]:19: runtime error: negation of -[[#]] cannot be represented in type 'long long'; cast to an unsigned type to negate this value to itself
|
|
// RECOVER: abs.cpp:[[#@LINE+2]]:9: runtime error: negation of -[[#]] cannot be represented in type 'long long'; cast to an unsigned type to negate this value to itself
|
|
__builtin_llabs(LLONG_MIN);
|
|
llabs(LLONG_MIN);
|
|
|
|
return 0;
|
|
}
|