Casting.cpp 8.7 KB

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