Casting.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. //===---------- llvm/unittest/Support/Casting.cpp - Casting 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/Support/Casting.h"
  9. #include "llvm/IR/User.h"
  10. #include "llvm/Support/Debug.h"
  11. #include "llvm/Support/raw_ostream.h"
  12. #include "gtest/gtest.h"
  13. #include <cstdlib>
  14. namespace llvm {
  15. // Used to test illegal cast. If a cast doesn't match any of the "real" ones,
  16. // it will match this one.
  17. struct IllegalCast;
  18. template <typename T> IllegalCast *cast(...) { return nullptr; }
  19. // set up two example classes
  20. // with conversion facility
  21. //
  22. struct bar {
  23. bar() {}
  24. struct foo *baz();
  25. struct foo *caz();
  26. struct foo *daz();
  27. struct foo *naz();
  28. private:
  29. bar(const bar &);
  30. };
  31. struct foo {
  32. void ext() const;
  33. /* static bool classof(const bar *X) {
  34. cerr << "Classof: " << X << "\n";
  35. return true;
  36. }*/
  37. };
  38. struct base {
  39. virtual ~base() {}
  40. };
  41. struct derived : public base {
  42. static bool classof(const base *B) { return true; }
  43. };
  44. template <> struct isa_impl<foo, bar> {
  45. static inline bool doit(const bar &Val) {
  46. dbgs() << "Classof: " << &Val << "\n";
  47. return true;
  48. }
  49. };
  50. template <typename T> struct isa_impl<foo, T> {
  51. static inline bool doit(const T &Val) { return false; }
  52. };
  53. foo *bar::baz() {
  54. return cast<foo>(this);
  55. }
  56. foo *bar::caz() {
  57. return cast_or_null<foo>(this);
  58. }
  59. foo *bar::daz() {
  60. return dyn_cast<foo>(this);
  61. }
  62. foo *bar::naz() {
  63. return dyn_cast_or_null<foo>(this);
  64. }
  65. bar *fub();
  66. template <> struct simplify_type<foo> {
  67. typedef int SimpleType;
  68. static SimpleType getSimplifiedValue(foo &Val) { return 0; }
  69. };
  70. } // End llvm namespace
  71. using namespace llvm;
  72. // Test the peculiar behavior of Use in simplify_type.
  73. static_assert(std::is_same<simplify_type<Use>::SimpleType, Value *>::value,
  74. "Use doesn't simplify correctly!");
  75. static_assert(std::is_same<simplify_type<Use *>::SimpleType, Value *>::value,
  76. "Use doesn't simplify correctly!");
  77. // Test that a regular class behaves as expected.
  78. static_assert(std::is_same<simplify_type<foo>::SimpleType, int>::value,
  79. "Unexpected simplify_type result!");
  80. static_assert(std::is_same<simplify_type<foo *>::SimpleType, foo *>::value,
  81. "Unexpected simplify_type result!");
  82. namespace {
  83. const foo *null_foo = nullptr;
  84. bar B;
  85. extern bar &B1;
  86. bar &B1 = B;
  87. extern const bar *B2;
  88. // test various configurations of const
  89. const bar &B3 = B1;
  90. const bar *const B4 = B2;
  91. TEST(CastingTest, isa) {
  92. EXPECT_TRUE(isa<foo>(B1));
  93. EXPECT_TRUE(isa<foo>(B2));
  94. EXPECT_TRUE(isa<foo>(B3));
  95. EXPECT_TRUE(isa<foo>(B4));
  96. }
  97. TEST(CastingTest, isa_and_nonnull) {
  98. EXPECT_TRUE(isa_and_nonnull<foo>(B2));
  99. EXPECT_TRUE(isa_and_nonnull<foo>(B4));
  100. EXPECT_FALSE(isa_and_nonnull<foo>(fub()));
  101. }
  102. TEST(CastingTest, cast) {
  103. foo &F1 = cast<foo>(B1);
  104. EXPECT_NE(&F1, null_foo);
  105. const foo *F3 = cast<foo>(B2);
  106. EXPECT_NE(F3, null_foo);
  107. const foo *F4 = cast<foo>(B2);
  108. EXPECT_NE(F4, null_foo);
  109. const foo &F5 = cast<foo>(B3);
  110. EXPECT_NE(&F5, null_foo);
  111. const foo *F6 = cast<foo>(B4);
  112. EXPECT_NE(F6, null_foo);
  113. // Can't pass null pointer to cast<>.
  114. // foo *F7 = cast<foo>(fub());
  115. // EXPECT_EQ(F7, null_foo);
  116. foo *F8 = B1.baz();
  117. EXPECT_NE(F8, null_foo);
  118. std::unique_ptr<const bar> BP(B2);
  119. auto FP = cast<foo>(std::move(BP));
  120. static_assert(std::is_same<std::unique_ptr<const foo>, decltype(FP)>::value,
  121. "Incorrect deduced return type!");
  122. EXPECT_NE(FP.get(), null_foo);
  123. FP.release();
  124. }
  125. TEST(CastingTest, cast_or_null) {
  126. const foo *F11 = cast_or_null<foo>(B2);
  127. EXPECT_NE(F11, null_foo);
  128. const foo *F12 = cast_or_null<foo>(B2);
  129. EXPECT_NE(F12, null_foo);
  130. const foo *F13 = cast_or_null<foo>(B4);
  131. EXPECT_NE(F13, null_foo);
  132. const foo *F14 = cast_or_null<foo>(fub()); // Shouldn't print.
  133. EXPECT_EQ(F14, null_foo);
  134. foo *F15 = B1.caz();
  135. EXPECT_NE(F15, null_foo);
  136. std::unique_ptr<const bar> BP(fub());
  137. auto FP = cast_or_null<foo>(std::move(BP));
  138. EXPECT_EQ(FP.get(), null_foo);
  139. }
  140. TEST(CastingTest, dyn_cast) {
  141. const foo *F1 = dyn_cast<foo>(B2);
  142. EXPECT_NE(F1, null_foo);
  143. const foo *F2 = dyn_cast<foo>(B2);
  144. EXPECT_NE(F2, null_foo);
  145. const foo *F3 = dyn_cast<foo>(B4);
  146. EXPECT_NE(F3, null_foo);
  147. // Can't pass null pointer to dyn_cast<>.
  148. // foo *F4 = dyn_cast<foo>(fub());
  149. // EXPECT_EQ(F4, null_foo);
  150. foo *F5 = B1.daz();
  151. EXPECT_NE(F5, null_foo);
  152. }
  153. TEST(CastingTest, dyn_cast_or_null) {
  154. const foo *F1 = dyn_cast_or_null<foo>(B2);
  155. EXPECT_NE(F1, null_foo);
  156. const foo *F2 = dyn_cast_or_null<foo>(B2);
  157. EXPECT_NE(F2, null_foo);
  158. const foo *F3 = dyn_cast_or_null<foo>(B4);
  159. EXPECT_NE(F3, null_foo);
  160. foo *F4 = dyn_cast_or_null<foo>(fub());
  161. EXPECT_EQ(F4, null_foo);
  162. foo *F5 = B1.naz();
  163. EXPECT_NE(F5, null_foo);
  164. }
  165. std::unique_ptr<derived> newd() { return std::make_unique<derived>(); }
  166. std::unique_ptr<base> newb() { return std::make_unique<derived>(); }
  167. TEST(CastingTest, unique_dyn_cast) {
  168. derived *OrigD = nullptr;
  169. auto D = std::make_unique<derived>();
  170. OrigD = D.get();
  171. // Converting from D to itself is valid, it should return a new unique_ptr
  172. // and the old one should become nullptr.
  173. auto NewD = unique_dyn_cast<derived>(D);
  174. ASSERT_EQ(OrigD, NewD.get());
  175. ASSERT_EQ(nullptr, D);
  176. // Converting from D to B is valid, B should have a value and D should be
  177. // nullptr.
  178. auto B = unique_dyn_cast<base>(NewD);
  179. ASSERT_EQ(OrigD, B.get());
  180. ASSERT_EQ(nullptr, NewD);
  181. // Converting from B to itself is valid, it should return a new unique_ptr
  182. // and the old one should become nullptr.
  183. auto NewB = unique_dyn_cast<base>(B);
  184. ASSERT_EQ(OrigD, NewB.get());
  185. ASSERT_EQ(nullptr, B);
  186. // Converting from B to D is valid, D should have a value and B should be
  187. // nullptr;
  188. D = unique_dyn_cast<derived>(NewB);
  189. ASSERT_EQ(OrigD, D.get());
  190. ASSERT_EQ(nullptr, NewB);
  191. // Converting between unrelated types should fail. The original value should
  192. // remain unchanged and it should return nullptr.
  193. auto F = unique_dyn_cast<foo>(D);
  194. ASSERT_EQ(nullptr, F);
  195. ASSERT_EQ(OrigD, D.get());
  196. // All of the above should also hold for temporaries.
  197. auto D2 = unique_dyn_cast<derived>(newd());
  198. EXPECT_NE(nullptr, D2);
  199. auto B2 = unique_dyn_cast<derived>(newb());
  200. EXPECT_NE(nullptr, B2);
  201. auto B3 = unique_dyn_cast<base>(newb());
  202. EXPECT_NE(nullptr, B3);
  203. auto F2 = unique_dyn_cast<foo>(newb());
  204. EXPECT_EQ(nullptr, F2);
  205. }
  206. // These lines are errors...
  207. //foo *F20 = cast<foo>(B2); // Yields const foo*
  208. //foo &F21 = cast<foo>(B3); // Yields const foo&
  209. //foo *F22 = cast<foo>(B4); // Yields const foo*
  210. //foo &F23 = cast_or_null<foo>(B1);
  211. //const foo &F24 = cast_or_null<foo>(B3);
  212. const bar *B2 = &B;
  213. } // anonymous namespace
  214. bar *llvm::fub() { return nullptr; }
  215. namespace {
  216. namespace inferred_upcasting {
  217. // This test case verifies correct behavior of inferred upcasts when the
  218. // types are statically known to be OK to upcast. This is the case when,
  219. // for example, Derived inherits from Base, and we do `isa<Base>(Derived)`.
  220. // Note: This test will actually fail to compile without inferred
  221. // upcasting.
  222. class Base {
  223. public:
  224. // No classof. We are testing that the upcast is inferred.
  225. Base() {}
  226. };
  227. class Derived : public Base {
  228. public:
  229. Derived() {}
  230. };
  231. // Even with no explicit classof() in Base, we should still be able to cast
  232. // Derived to its base class.
  233. TEST(CastingTest, UpcastIsInferred) {
  234. Derived D;
  235. EXPECT_TRUE(isa<Base>(D));
  236. Base *BP = dyn_cast<Base>(&D);
  237. EXPECT_TRUE(BP != nullptr);
  238. }
  239. // This test verifies that the inferred upcast takes precedence over an
  240. // explicitly written one. This is important because it verifies that the
  241. // dynamic check gets optimized away.
  242. class UseInferredUpcast {
  243. public:
  244. int Dummy;
  245. static bool classof(const UseInferredUpcast *) {
  246. return false;
  247. }
  248. };
  249. TEST(CastingTest, InferredUpcastTakesPrecedence) {
  250. UseInferredUpcast UIU;
  251. // Since the explicit classof() returns false, this will fail if the
  252. // explicit one is used.
  253. EXPECT_TRUE(isa<UseInferredUpcast>(&UIU));
  254. }
  255. } // end namespace inferred_upcasting
  256. } // end anonymous namespace
  257. // Test that we reject casts of temporaries (and so the illegal cast gets used).
  258. namespace TemporaryCast {
  259. struct pod {};
  260. IllegalCast *testIllegalCast() { return cast<foo>(pod()); }
  261. }
  262. namespace {
  263. namespace pointer_wrappers {
  264. struct Base {
  265. bool IsDerived;
  266. Base(bool IsDerived = false) : IsDerived(IsDerived) {}
  267. };
  268. struct Derived : Base {
  269. Derived() : Base(true) {}
  270. static bool classof(const Base *B) { return B->IsDerived; }
  271. };
  272. class PTy {
  273. Base *B;
  274. public:
  275. PTy(Base *B) : B(B) {}
  276. explicit operator bool() const { return get(); }
  277. Base *get() const { return B; }
  278. };
  279. } // end namespace pointer_wrappers
  280. } // end namespace
  281. namespace llvm {
  282. template <> struct simplify_type<pointer_wrappers::PTy> {
  283. typedef pointer_wrappers::Base *SimpleType;
  284. static SimpleType getSimplifiedValue(pointer_wrappers::PTy &P) {
  285. return P.get();
  286. }
  287. };
  288. template <> struct simplify_type<const pointer_wrappers::PTy> {
  289. typedef pointer_wrappers::Base *SimpleType;
  290. static SimpleType getSimplifiedValue(const pointer_wrappers::PTy &P) {
  291. return P.get();
  292. }
  293. };
  294. } // end namespace llvm
  295. namespace {
  296. namespace pointer_wrappers {
  297. // Some objects.
  298. pointer_wrappers::Base B;
  299. pointer_wrappers::Derived D;
  300. // Mutable "smart" pointers.
  301. pointer_wrappers::PTy MN(nullptr);
  302. pointer_wrappers::PTy MB(&B);
  303. pointer_wrappers::PTy MD(&D);
  304. // Const "smart" pointers.
  305. const pointer_wrappers::PTy CN(nullptr);
  306. const pointer_wrappers::PTy CB(&B);
  307. const pointer_wrappers::PTy CD(&D);
  308. TEST(CastingTest, smart_isa) {
  309. EXPECT_TRUE(!isa<pointer_wrappers::Derived>(MB));
  310. EXPECT_TRUE(!isa<pointer_wrappers::Derived>(CB));
  311. EXPECT_TRUE(isa<pointer_wrappers::Derived>(MD));
  312. EXPECT_TRUE(isa<pointer_wrappers::Derived>(CD));
  313. }
  314. TEST(CastingTest, smart_cast) {
  315. EXPECT_TRUE(cast<pointer_wrappers::Derived>(MD) == &D);
  316. EXPECT_TRUE(cast<pointer_wrappers::Derived>(CD) == &D);
  317. }
  318. TEST(CastingTest, smart_cast_or_null) {
  319. EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(MN) == nullptr);
  320. EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(CN) == nullptr);
  321. EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(MD) == &D);
  322. EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(CD) == &D);
  323. }
  324. TEST(CastingTest, smart_dyn_cast) {
  325. EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(MB) == nullptr);
  326. EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(CB) == nullptr);
  327. EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(MD) == &D);
  328. EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(CD) == &D);
  329. }
  330. TEST(CastingTest, smart_dyn_cast_or_null) {
  331. EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MN) == nullptr);
  332. EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CN) == nullptr);
  333. EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MB) == nullptr);
  334. EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CB) == nullptr);
  335. EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MD) == &D);
  336. EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CD) == &D);
  337. }
  338. } // end namespace pointer_wrappers
  339. } // end namespace