PointerIntPairTest.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. //===- llvm/unittest/ADT/PointerIntPairTest.cpp - Unit tests --------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/ADT/PointerIntPair.h"
  9. #include "gtest/gtest.h"
  10. #include <limits>
  11. using namespace llvm;
  12. namespace {
  13. TEST(PointerIntPairTest, GetSet) {
  14. struct S {
  15. int i;
  16. };
  17. S s;
  18. PointerIntPair<S *, 2> Pair(&s, 1U);
  19. EXPECT_EQ(&s, Pair.getPointer());
  20. EXPECT_EQ(1U, Pair.getInt());
  21. Pair.setInt(2);
  22. EXPECT_EQ(&s, Pair.getPointer());
  23. EXPECT_EQ(2U, Pair.getInt());
  24. Pair.setPointer(nullptr);
  25. EXPECT_EQ(nullptr, Pair.getPointer());
  26. EXPECT_EQ(2U, Pair.getInt());
  27. Pair.setPointerAndInt(&s, 3U);
  28. EXPECT_EQ(&s, Pair.getPointer());
  29. EXPECT_EQ(3U, Pair.getInt());
  30. // Make sure that we can perform all of our operations on enum classes.
  31. //
  32. // The concern is that enum classes are only explicitly convertible to
  33. // integers. This means that if we assume in PointerIntPair this, a
  34. // compilation error will result. This group of tests exercises the enum class
  35. // code to make sure that we do not run into such issues in the future.
  36. enum class E : unsigned {
  37. Case1,
  38. Case2,
  39. Case3,
  40. };
  41. PointerIntPair<S *, 2, E> Pair2(&s, E::Case1);
  42. EXPECT_EQ(&s, Pair2.getPointer());
  43. EXPECT_EQ(E::Case1, Pair2.getInt());
  44. Pair2.setInt(E::Case2);
  45. EXPECT_EQ(&s, Pair2.getPointer());
  46. EXPECT_EQ(E::Case2, Pair2.getInt());
  47. Pair2.setPointer(nullptr);
  48. EXPECT_EQ(nullptr, Pair2.getPointer());
  49. EXPECT_EQ(E::Case2, Pair2.getInt());
  50. Pair2.setPointerAndInt(&s, E::Case3);
  51. EXPECT_EQ(&s, Pair2.getPointer());
  52. EXPECT_EQ(E::Case3, Pair2.getInt());
  53. static_assert(is_trivially_copyable<PointerIntPair<S *, 2, E>>::value,
  54. "trivially copyable");
  55. }
  56. TEST(PointerIntPairTest, DefaultInitialize) {
  57. PointerIntPair<float *, 2> Pair;
  58. EXPECT_EQ(nullptr, Pair.getPointer());
  59. EXPECT_EQ(0U, Pair.getInt());
  60. }
  61. TEST(PointerIntPairTest, ManyUnusedBits) {
  62. // In real code this would be a word-sized integer limited to 31 bits.
  63. struct Fixnum31 {
  64. uintptr_t Value;
  65. };
  66. class FixnumPointerTraits {
  67. public:
  68. static inline void *getAsVoidPointer(Fixnum31 Num) {
  69. return reinterpret_cast<void *>(Num.Value << NumLowBitsAvailable);
  70. }
  71. static inline Fixnum31 getFromVoidPointer(void *P) {
  72. // In real code this would assert that the value is in range.
  73. return { reinterpret_cast<uintptr_t>(P) >> NumLowBitsAvailable };
  74. }
  75. enum { NumLowBitsAvailable = std::numeric_limits<uintptr_t>::digits - 31 };
  76. };
  77. PointerIntPair<Fixnum31, 1, bool, FixnumPointerTraits> pair;
  78. EXPECT_EQ((uintptr_t)0, pair.getPointer().Value);
  79. EXPECT_FALSE(pair.getInt());
  80. pair.setPointerAndInt({ 0x7FFFFFFF }, true );
  81. EXPECT_EQ((uintptr_t)0x7FFFFFFF, pair.getPointer().Value);
  82. EXPECT_TRUE(pair.getInt());
  83. EXPECT_EQ(FixnumPointerTraits::NumLowBitsAvailable - 1,
  84. PointerLikeTypeTraits<decltype(pair)>::NumLowBitsAvailable);
  85. static_assert(
  86. is_trivially_copyable<
  87. PointerIntPair<Fixnum31, 1, bool, FixnumPointerTraits>>::value,
  88. "trivially copyable");
  89. }
  90. } // end anonymous namespace