[libc-commits] [libc] b62d72f - [libc] Add support for 128 bit ints in limits.h
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Tue Sep 28 16:50:20 PDT 2021
Author: Michael Jones
Date: 2021-09-28T23:50:16Z
New Revision: b62d72f3c542729349633c5f77697fe24921251d
URL: https://github.com/llvm/llvm-project/commit/b62d72f3c542729349633c5f77697fe24921251d
DIFF: https://github.com/llvm/llvm-project/commit/b62d72f3c542729349633c5f77697fe24921251d.diff
LOG: [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
Added:
libc/test/utils/CPP/limits_test.cpp
Modified:
libc/test/utils/CPP/CMakeLists.txt
libc/utils/CPP/Limits.h
libc/utils/CPP/TypeTraits.h
libc/utils/UnitTest/LibcTest.cpp
Removed:
################################################################################
diff --git a/libc/test/utils/CPP/CMakeLists.txt b/libc/test/utils/CPP/CMakeLists.txt
index 580fed5923e89..09c43d64ce938 100644
--- a/libc/test/utils/CPP/CMakeLists.txt
+++ b/libc/test/utils/CPP/CMakeLists.txt
@@ -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
diff --git a/libc/test/utils/CPP/limits_test.cpp b/libc/test/utils/CPP/limits_test.cpp
new file mode 100644
index 0000000000000..6904a728c4cb1
--- /dev/null
+++ b/libc/test/utils/CPP/limits_test.cpp
@@ -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);
+}
diff --git a/libc/utils/CPP/Limits.h b/libc/utils/CPP/Limits.h
index ac327b30ee71c..393c3b6a031a1 100644
--- a/libc/utils/CPP/Limits.h
+++ b/libc/utils/CPP/Limits.h
@@ -52,6 +52,16 @@ template <> class NumericLimits<unsigned long long> {
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
diff --git a/libc/utils/CPP/TypeTraits.h b/libc/utils/CPP/TypeTraits.h
index 1f2c85af3a1cb..060d36e4e00e8 100644
--- a/libc/utils/CPP/TypeTraits.h
+++ b/libc/utils/CPP/TypeTraits.h
@@ -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 {};
diff --git a/libc/utils/UnitTest/LibcTest.cpp b/libc/utils/UnitTest/LibcTest.cpp
index dc5c0dd651ea4..710ee15bba3f9 100644
--- a/libc/utils/UnitTest/LibcTest.cpp
+++ b/libc/utils/UnitTest/LibcTest.cpp
@@ -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,
More information about the libc-commits
mailing list