forked from OSchip/llvm-project
[libc] Add support for 128 bit ints in limits.h
Also, this adds unit tests to check that limits.h complies with the C standard. Reviewed By: sivachandra Differential Revision: https://reviews.llvm.org/D110643
This commit is contained in:
parent
5cf0606140
commit
b62d72f3c5
|
@ -20,6 +20,16 @@ add_libc_unittest(
|
|||
libc.utils.CPP.standalone_cpp
|
||||
)
|
||||
|
||||
add_libc_unittest(
|
||||
limits_test
|
||||
SUITE
|
||||
libc_cpp_utils_unittests
|
||||
SRCS
|
||||
limits_test.cpp
|
||||
DEPENDS
|
||||
libc.utils.CPP.standalone_cpp
|
||||
)
|
||||
|
||||
add_libc_unittest(
|
||||
arrayref_test
|
||||
SUITE
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
//===-- Unittests for Limits ----------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "utils/CPP/Limits.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
// This just checks against the C spec, almost all implementations will surpass
|
||||
// this.
|
||||
TEST(LlvmLibcLimitsTest, LimitsFollowSpec) {
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<int>::max(), INT_MAX);
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<int>::min(), INT_MIN);
|
||||
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<unsigned int>::max(), UINT_MAX);
|
||||
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<long>::max(), LONG_MAX);
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<long>::min(), LONG_MIN);
|
||||
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<unsigned long>::max(), ULONG_MAX);
|
||||
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<long long>::max(), LLONG_MAX);
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<long long>::min(), LLONG_MIN);
|
||||
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<unsigned long long>::max(),
|
||||
ULLONG_MAX);
|
||||
}
|
||||
|
||||
// This checks that the current environment supports 128 bit integers.
|
||||
TEST(LlvmLibcLimitsTest, Int128Works) {
|
||||
__int128_t max128 = ~__uint128_t(0) >> 1;
|
||||
__int128_t min128 = (__int128_t(1) << 127);
|
||||
EXPECT_GT(__llvm_libc::cpp::NumericLimits<__int128_t>::max(),
|
||||
__int128_t(__llvm_libc::cpp::NumericLimits<long long>::max()));
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<__int128_t>::max(), max128);
|
||||
|
||||
EXPECT_LT(__llvm_libc::cpp::NumericLimits<__int128_t>::min(),
|
||||
__int128_t(__llvm_libc::cpp::NumericLimits<long long>::min()));
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<__int128_t>::min(), min128);
|
||||
|
||||
__uint128_t umax128 = ~__uint128_t(0);
|
||||
EXPECT_GT(
|
||||
__llvm_libc::cpp::NumericLimits<__uint128_t>::max(),
|
||||
__uint128_t(__llvm_libc::cpp::NumericLimits<unsigned long long>::max()));
|
||||
ASSERT_EQ(__llvm_libc::cpp::NumericLimits<__uint128_t>::max(), umax128);
|
||||
}
|
|
@ -52,6 +52,16 @@ public:
|
|||
static constexpr unsigned long long max() { return ULLONG_MAX; }
|
||||
static constexpr unsigned long long min() { return 0; }
|
||||
};
|
||||
template <> class NumericLimits<__uint128_t> {
|
||||
public:
|
||||
static constexpr __uint128_t max() { return ~__uint128_t(0); }
|
||||
static constexpr __uint128_t min() { return 0; }
|
||||
};
|
||||
template <> class NumericLimits<__int128_t> {
|
||||
public:
|
||||
static constexpr __int128_t max() { return ~__uint128_t(0) >> 1; }
|
||||
static constexpr __int128_t min() { return __int128_t(1) << 127; }
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace __llvm_libc
|
||||
|
|
|
@ -50,7 +50,7 @@ template <typename Type> struct IsIntegral {
|
|||
IsSameV<unsigned int, TypeNoCV> || IsSameV<long, TypeNoCV> ||
|
||||
IsSameV<unsigned long, TypeNoCV> || IsSameV<long long, TypeNoCV> ||
|
||||
IsSameV<unsigned long long, TypeNoCV> || IsSameV<bool, TypeNoCV> ||
|
||||
IsSameV<__uint128_t, TypeNoCV>;
|
||||
IsSameV<__uint128_t, TypeNoCV> || IsSameV<__int128_t, TypeNoCV>;
|
||||
};
|
||||
|
||||
template <typename T> struct IsPointerTypeNoCV : public FalseValue {};
|
||||
|
|
|
@ -44,7 +44,7 @@ std::string describeValue(std::string Value) { return std::string(Value); }
|
|||
|
||||
// When the value is __uint128_t, also show its hexadecimal digits.
|
||||
// Using template to force exact match, prevent ambiguous promotion.
|
||||
template <> std::string describeValue<__uint128_t>(__uint128_t Value) {
|
||||
std::string describeValue128(__uint128_t Value) {
|
||||
std::string S(sizeof(__uint128_t) * 2, '0');
|
||||
|
||||
for (auto I = S.rbegin(), End = S.rend(); I != End; ++I, Value >>= 4) {
|
||||
|
@ -55,6 +55,13 @@ template <> std::string describeValue<__uint128_t>(__uint128_t Value) {
|
|||
return "0x" + S;
|
||||
}
|
||||
|
||||
template <> std::string describeValue<__int128_t>(__int128_t Value) {
|
||||
return describeValue128(Value);
|
||||
}
|
||||
template <> std::string describeValue<__uint128_t>(__uint128_t Value) {
|
||||
return describeValue128(Value);
|
||||
}
|
||||
|
||||
template <typename ValType>
|
||||
void explainDifference(ValType LHS, ValType RHS, const char *LHSStr,
|
||||
const char *RHSStr, const char *File, unsigned long Line,
|
||||
|
@ -209,6 +216,11 @@ template bool Test::test<long long, 0>(TestCondition Cond, long long LHS,
|
|||
const char *RHSStr, const char *File,
|
||||
unsigned long Line);
|
||||
|
||||
template bool Test::test<__int128_t, 0>(TestCondition Cond, __int128_t LHS,
|
||||
__int128_t RHS, const char *LHSStr,
|
||||
const char *RHSStr, const char *File,
|
||||
unsigned long Line);
|
||||
|
||||
template bool Test::test<unsigned char, 0>(TestCondition Cond,
|
||||
unsigned char LHS, unsigned char RHS,
|
||||
const char *LHSStr,
|
||||
|
|
Loading…
Reference in New Issue