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 
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 
16 namespace llvm {
17 // Used to test illegal cast. If a cast doesn't match any of the "real" ones,
18 // it will match this one.
19 struct IllegalCast;
20 template <typename T> IllegalCast *cast(...) { return nullptr; }
21 
22 // set up two example classes
23 // with conversion facility
24 //
25 struct bar {
26   bar() {}
27   struct foo *baz();
28   struct foo *caz();
29   struct foo *daz();
30   struct foo *naz();
31 
32 private:
33   bar(const bar &);
34 };
35 struct foo {
36   foo(const bar &) {}
37   void ext() const;
38 };
39 
40 struct base {
41   virtual ~base() {}
42 };
43 
44 struct derived : public base {
45   static bool classof(const base *B) { return true; }
46 };
47 
48 template <> struct isa_impl<foo, bar> {
49   static inline bool doit(const bar &Val) {
50     dbgs() << "Classof: " << &Val << "\n";
51     return true;
52   }
53 };
54 
55 // Note for the future - please don't do this. isa_impl is an internal template
56 // for the implementation of `isa` and should not be exposed this way.
57 // Completely unrelated types *should* result in compiler errors if you try to
58 // cast between them.
59 template <typename T> struct isa_impl<foo, T> {
60   static inline bool doit(const T &Val) { return false; }
61 };
62 
63 foo *bar::baz() { return cast<foo>(this); }
64 
65 foo *bar::caz() { return cast_or_null<foo>(this); }
66 
67 foo *bar::daz() { return dyn_cast<foo>(this); }
68 
69 foo *bar::naz() { return dyn_cast_or_null<foo>(this); }
70 
71 bar *fub();
72 
73 template <> struct simplify_type<foo> {
74   typedef int SimpleType;
75   static SimpleType getSimplifiedValue(foo &Val) { return 0; }
76 };
77 
78 struct T1 {};
79 
80 struct T2 {
81   T2(const T1 &x) {}
82   static bool classof(const T1 *x) { return true; }
83 };
84 
85 template <> struct CastInfo<T2, T1> : public OptionalValueCast<T2, T1> {};
86 
87 struct T3 {
88   T3(const T1 *x) : hasValue(x != nullptr) {}
89 
90   static bool classof(const T1 *x) { return true; }
91   bool hasValue = false;
92 };
93 
94 // T3 is convertible from a pointer to T1.
95 template <> struct CastInfo<T3, T1 *> : public ValueFromPointerCast<T3, T1> {};
96 
97 struct T4 {
98   T4() : hasValue(false) {}
99   T4(const T3 &x) : hasValue(true) {}
100 
101   static bool classof(const T3 *x) { return true; }
102   bool hasValue = false;
103 };
104 
105 template <> struct ValueIsPresent<T3> {
106   using UnwrappedType = T3;
107   static inline bool isPresent(const T3 &t) { return t.hasValue; }
108   static inline const T3 &unwrapValue(const T3 &t) { return t; }
109 };
110 
111 template <> struct CastInfo<T4, T3> {
112   using CastResultType = T4;
113   static inline CastResultType doCast(const T3 &t) { return T4(t); }
114   static inline CastResultType castFailed() { return CastResultType(); }
115   static inline CastResultType doCastIfPossible(const T3 &f) {
116     return doCast(f);
117   }
118 };
119 
120 } // namespace llvm
121 
122 using namespace llvm;
123 
124 // Test the peculiar behavior of Use in simplify_type.
125 static_assert(std::is_same<simplify_type<Use>::SimpleType, Value *>::value,
126               "Use doesn't simplify correctly!");
127 static_assert(std::is_same<simplify_type<Use *>::SimpleType, Value *>::value,
128               "Use doesn't simplify correctly!");
129 
130 // Test that a regular class behaves as expected.
131 static_assert(std::is_same<simplify_type<foo>::SimpleType, int>::value,
132               "Unexpected simplify_type result!");
133 static_assert(std::is_same<simplify_type<foo *>::SimpleType, foo *>::value,
134               "Unexpected simplify_type result!");
135 
136 namespace {
137 
138 const foo *null_foo = nullptr;
139 
140 bar B;
141 extern bar &B1;
142 bar &B1 = B;
143 extern const bar *B2;
144 // test various configurations of const
145 const bar &B3 = B1;
146 const bar *const B4 = B2;
147 bar *B5 = &B;
148 
149 TEST(CastingTest, isa) {
150   EXPECT_TRUE(isa<foo>(B1));
151   EXPECT_TRUE(isa<foo>(B2));
152   EXPECT_TRUE(isa<foo>(B3));
153   EXPECT_TRUE(isa<foo>(B4));
154 }
155 
156 TEST(CastingTest, isa_and_nonnull) {
157   EXPECT_TRUE(isa_and_nonnull<foo>(B2));
158   EXPECT_TRUE(isa_and_nonnull<foo>(B4));
159   EXPECT_FALSE(isa_and_nonnull<foo>(fub()));
160 }
161 
162 TEST(CastingTest, cast) {
163   foo &F1 = cast<foo>(B1);
164   EXPECT_NE(&F1, null_foo);
165   const foo *F3 = cast<foo>(B2);
166   EXPECT_NE(F3, null_foo);
167   const foo *F4 = cast<foo>(B2);
168   EXPECT_NE(F4, null_foo);
169   const foo &F5 = cast<foo>(B3);
170   EXPECT_NE(&F5, null_foo);
171   const foo *F6 = cast<foo>(B4);
172   EXPECT_NE(F6, null_foo);
173   // Can't pass null pointer to cast<>.
174   // foo *F7 = cast<foo>(fub());
175   // EXPECT_EQ(F7, null_foo);
176   foo *F8 = B1.baz();
177   EXPECT_NE(F8, null_foo);
178 
179   // Ensure cast-to-self works (with the type in the template verbatim
180   // equivalent to the type in the input).
181   auto B9 = cast<bar *>(B5);
182   static_assert(std::is_same<bar *, decltype(B9)>::value,
183                 "Inccorrect return type!");
184   EXPECT_EQ(B9, B5);
185   auto B10 = cast<const bar *>(B2);
186   static_assert(std::is_same<const bar *, decltype(B10)>::value,
187                 "Inccorrect return type!");
188   EXPECT_EQ(B10, B2);
189 
190   std::unique_ptr<const bar> BP(B2);
191   auto FP = cast<foo>(std::move(BP));
192   static_assert(std::is_same<std::unique_ptr<const foo>, decltype(FP)>::value,
193                 "Incorrect deduced return type!");
194   EXPECT_NE(FP.get(), null_foo);
195   FP.release();
196 }
197 
198 TEST(CastingTest, cast_or_null) {
199   const foo *F11 = cast_or_null<foo>(B2);
200   EXPECT_NE(F11, null_foo);
201   const foo *F12 = cast_or_null<foo>(B2);
202   EXPECT_NE(F12, null_foo);
203   const foo *F13 = cast_or_null<foo>(B4);
204   EXPECT_NE(F13, null_foo);
205   const foo *F14 = cast_or_null<foo>(fub()); // Shouldn't print.
206   EXPECT_EQ(F14, null_foo);
207   foo *F15 = B1.caz();
208   EXPECT_NE(F15, null_foo);
209 
210   std::unique_ptr<const bar> BP(fub());
211   auto FP = cast_or_null<foo>(std::move(BP));
212   EXPECT_EQ(FP.get(), null_foo);
213 }
214 
215 TEST(CastingTest, dyn_cast) {
216   const foo *F1 = dyn_cast<foo>(B2);
217   EXPECT_NE(F1, null_foo);
218   const foo *F2 = dyn_cast<foo>(B2);
219   EXPECT_NE(F2, null_foo);
220   const foo *F3 = dyn_cast<foo>(B4);
221   EXPECT_NE(F3, null_foo);
222   // Can't pass null pointer to dyn_cast<>.
223   // foo *F4 = dyn_cast<foo>(fub());
224   // EXPECT_EQ(F4, null_foo);
225   foo *F5 = B1.daz();
226   EXPECT_NE(F5, null_foo);
227 
228   // Ensure cast-to-self works (with the type in the template verbatim
229   // equivalent to the type in the input).
230   auto B9 = dyn_cast<bar *>(B5);
231   static_assert(std::is_same<bar *, decltype(B9)>::value,
232                 "Inccorrect return type!");
233   EXPECT_EQ(B9, B5);
234   auto B10 = dyn_cast<const bar *>(B2);
235   static_assert(std::is_same<const bar *, decltype(B10)>::value,
236                 "Inccorrect return type!");
237   EXPECT_EQ(B10, B2);
238 }
239 
240 // All these tests forward to dyn_cast_if_present, so they also provde an
241 // effective test for its use cases.
242 TEST(CastingTest, dyn_cast_or_null) {
243   const foo *F1 = dyn_cast_or_null<foo>(B2);
244   EXPECT_NE(F1, null_foo);
245   const foo *F2 = dyn_cast_or_null<foo>(B2);
246   EXPECT_NE(F2, null_foo);
247   const foo *F3 = dyn_cast_or_null<foo>(B4);
248   EXPECT_NE(F3, null_foo);
249   foo *F4 = dyn_cast_or_null<foo>(fub());
250   EXPECT_EQ(F4, null_foo);
251   foo *F5 = B1.naz();
252   EXPECT_NE(F5, null_foo);
253   // dyn_cast_if_present should have exactly the same behavior as
254   // dyn_cast_or_null.
255   const foo *F6 = dyn_cast_if_present<foo>(B2);
256   EXPECT_EQ(F6, F2);
257 }
258 
259 TEST(CastingTest, dyn_cast_value_types) {
260   T1 t1;
261   Optional<T2> t2 = dyn_cast<T2>(t1);
262   EXPECT_TRUE(t2.hasValue());
263 
264   T2 *t2ptr = dyn_cast<T2>(&t1);
265   EXPECT_TRUE(t2ptr != nullptr);
266 
267   T3 t3 = dyn_cast<T3>(&t1);
268   EXPECT_TRUE(t3.hasValue);
269 }
270 
271 TEST(CastingTest, dyn_cast_if_present) {
272   Optional<T1> empty{};
273   Optional<T2> F1 = dyn_cast_if_present<T2>(empty);
274   EXPECT_FALSE(F1.hasValue());
275 
276   T1 t1;
277   Optional<T2> F2 = dyn_cast_if_present<T2>(t1);
278   EXPECT_TRUE(F2.hasValue());
279 
280   T1 *t1Null = nullptr;
281 
282   // T3 should have hasValue == false because t1Null is nullptr.
283   T3 t3 = dyn_cast_if_present<T3>(t1Null);
284   EXPECT_FALSE(t3.hasValue);
285 
286   // Now because of that, T4 should receive the castFailed implementation of its
287   // FallibleCastTraits, which default-constructs a T4, which has no value.
288   T4 t4 = dyn_cast_if_present<T4>(t3);
289   EXPECT_FALSE(t4.hasValue);
290 }
291 
292 std::unique_ptr<derived> newd() { return std::make_unique<derived>(); }
293 std::unique_ptr<base> newb() { return std::make_unique<derived>(); }
294 
295 TEST(CastingTest, unique_dyn_cast) {
296   derived *OrigD = nullptr;
297   auto D = std::make_unique<derived>();
298   OrigD = D.get();
299 
300   // Converting from D to itself is valid, it should return a new unique_ptr
301   // and the old one should become nullptr.
302   auto NewD = unique_dyn_cast<derived>(D);
303   ASSERT_EQ(OrigD, NewD.get());
304   ASSERT_EQ(nullptr, D);
305 
306   // Converting from D to B is valid, B should have a value and D should be
307   // nullptr.
308   auto B = unique_dyn_cast<base>(NewD);
309   ASSERT_EQ(OrigD, B.get());
310   ASSERT_EQ(nullptr, NewD);
311 
312   // Converting from B to itself is valid, it should return a new unique_ptr
313   // and the old one should become nullptr.
314   auto NewB = unique_dyn_cast<base>(B);
315   ASSERT_EQ(OrigD, NewB.get());
316   ASSERT_EQ(nullptr, B);
317 
318   // Converting from B to D is valid, D should have a value and B should be
319   // nullptr;
320   D = unique_dyn_cast<derived>(NewB);
321   ASSERT_EQ(OrigD, D.get());
322   ASSERT_EQ(nullptr, NewB);
323 
324   // This is a very contrived test, casting between completely unrelated types
325   // should generally fail to compile. See the classof shenanigans we have in
326   // the definition of `foo` above.
327   auto F = unique_dyn_cast<foo>(D);
328   ASSERT_EQ(nullptr, F);
329   ASSERT_EQ(OrigD, D.get());
330 
331   // All of the above should also hold for temporaries.
332   auto D2 = unique_dyn_cast<derived>(newd());
333   EXPECT_NE(nullptr, D2);
334 
335   auto B2 = unique_dyn_cast<derived>(newb());
336   EXPECT_NE(nullptr, B2);
337 
338   auto B3 = unique_dyn_cast<base>(newb());
339   EXPECT_NE(nullptr, B3);
340 
341   // This is a very contrived test, casting between completely unrelated types
342   // should generally fail to compile. See the classof shenanigans we have in
343   // the definition of `foo` above.
344   auto F2 = unique_dyn_cast<foo>(newb());
345   EXPECT_EQ(nullptr, F2);
346 }
347 
348 // These lines are errors...
349 // foo *F20 = cast<foo>(B2);  // Yields const foo*
350 // foo &F21 = cast<foo>(B3);  // Yields const foo&
351 // foo *F22 = cast<foo>(B4);  // Yields const foo*
352 // foo &F23 = cast_or_null<foo>(B1);
353 // const foo &F24 = cast_or_null<foo>(B3);
354 
355 const bar *B2 = &B;
356 } // anonymous namespace
357 
358 bar *llvm::fub() { return nullptr; }
359 
360 namespace {
361 namespace inferred_upcasting {
362 // This test case verifies correct behavior of inferred upcasts when the
363 // types are statically known to be OK to upcast. This is the case when,
364 // for example, Derived inherits from Base, and we do `isa<Base>(Derived)`.
365 
366 // Note: This test will actually fail to compile without inferred
367 // upcasting.
368 
369 class Base {
370 public:
371   // No classof. We are testing that the upcast is inferred.
372   Base() {}
373 };
374 
375 class Derived : public Base {
376 public:
377   Derived() {}
378 };
379 
380 // Even with no explicit classof() in Base, we should still be able to cast
381 // Derived to its base class.
382 TEST(CastingTest, UpcastIsInferred) {
383   Derived D;
384   EXPECT_TRUE(isa<Base>(D));
385   Base *BP = dyn_cast<Base>(&D);
386   EXPECT_NE(BP, nullptr);
387 }
388 
389 // This test verifies that the inferred upcast takes precedence over an
390 // explicitly written one. This is important because it verifies that the
391 // dynamic check gets optimized away.
392 class UseInferredUpcast {
393 public:
394   int Dummy;
395   static bool classof(const UseInferredUpcast *) { return false; }
396 };
397 
398 TEST(CastingTest, InferredUpcastTakesPrecedence) {
399   UseInferredUpcast UIU;
400   // Since the explicit classof() returns false, this will fail if the
401   // explicit one is used.
402   EXPECT_TRUE(isa<UseInferredUpcast>(&UIU));
403 }
404 
405 } // end namespace inferred_upcasting
406 } // end anonymous namespace
407 
408 namespace {
409 namespace pointer_wrappers {
410 
411 struct Base {
412   bool IsDerived;
413   Base(bool IsDerived = false) : IsDerived(IsDerived) {}
414 };
415 
416 struct Derived : Base {
417   Derived() : Base(true) {}
418   static bool classof(const Base *B) { return B->IsDerived; }
419 };
420 
421 class PTy {
422   Base *B;
423 
424 public:
425   PTy(Base *B) : B(B) {}
426   explicit operator bool() const { return get(); }
427   Base *get() const { return B; }
428 };
429 
430 } // end namespace pointer_wrappers
431 } // end namespace
432 
433 namespace llvm {
434 
435 template <> struct ValueIsPresent<pointer_wrappers::PTy> {
436   using UnwrappedType = pointer_wrappers::PTy;
437   static inline bool isPresent(const pointer_wrappers::PTy &P) {
438     return P.get() != nullptr;
439   }
440   static UnwrappedType &unwrapValue(pointer_wrappers::PTy &P) { return P; }
441 };
442 
443 template <> struct ValueIsPresent<const pointer_wrappers::PTy> {
444   using UnwrappedType = pointer_wrappers::PTy;
445   static inline bool isPresent(const pointer_wrappers::PTy &P) {
446     return P.get() != nullptr;
447   }
448 
449   static UnwrappedType &unwrapValue(const pointer_wrappers::PTy &P) {
450     return const_cast<UnwrappedType &>(P);
451   }
452 };
453 
454 template <> struct simplify_type<pointer_wrappers::PTy> {
455   typedef pointer_wrappers::Base *SimpleType;
456   static SimpleType getSimplifiedValue(pointer_wrappers::PTy &P) {
457     return P.get();
458   }
459 };
460 template <> struct simplify_type<const pointer_wrappers::PTy> {
461   typedef pointer_wrappers::Base *SimpleType;
462   static SimpleType getSimplifiedValue(const pointer_wrappers::PTy &P) {
463     return P.get();
464   }
465 };
466 
467 } // end namespace llvm
468 
469 namespace {
470 namespace pointer_wrappers {
471 
472 // Some objects.
473 pointer_wrappers::Base B;
474 pointer_wrappers::Derived D;
475 
476 // Mutable "smart" pointers.
477 pointer_wrappers::PTy MN(nullptr);
478 pointer_wrappers::PTy MB(&B);
479 pointer_wrappers::PTy MD(&D);
480 
481 // Const "smart" pointers.
482 const pointer_wrappers::PTy CN(nullptr);
483 const pointer_wrappers::PTy CB(&B);
484 const pointer_wrappers::PTy CD(&D);
485 
486 TEST(CastingTest, smart_isa) {
487   EXPECT_TRUE(!isa<pointer_wrappers::Derived>(MB));
488   EXPECT_TRUE(!isa<pointer_wrappers::Derived>(CB));
489   EXPECT_TRUE(isa<pointer_wrappers::Derived>(MD));
490   EXPECT_TRUE(isa<pointer_wrappers::Derived>(CD));
491 }
492 
493 TEST(CastingTest, smart_cast) {
494   EXPECT_EQ(cast<pointer_wrappers::Derived>(MD), &D);
495   EXPECT_EQ(cast<pointer_wrappers::Derived>(CD), &D);
496 }
497 
498 TEST(CastingTest, smart_cast_or_null) {
499   EXPECT_EQ(cast_or_null<pointer_wrappers::Derived>(MN), nullptr);
500   EXPECT_EQ(cast_or_null<pointer_wrappers::Derived>(CN), nullptr);
501   EXPECT_EQ(cast_or_null<pointer_wrappers::Derived>(MD), &D);
502   EXPECT_EQ(cast_or_null<pointer_wrappers::Derived>(CD), &D);
503 }
504 
505 TEST(CastingTest, smart_dyn_cast) {
506   EXPECT_EQ(dyn_cast<pointer_wrappers::Derived>(MB), nullptr);
507   EXPECT_EQ(dyn_cast<pointer_wrappers::Derived>(CB), nullptr);
508   EXPECT_EQ(dyn_cast<pointer_wrappers::Derived>(MD), &D);
509   EXPECT_EQ(dyn_cast<pointer_wrappers::Derived>(CD), &D);
510 }
511 
512 TEST(CastingTest, smart_dyn_cast_or_null) {
513   EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(MN), nullptr);
514   EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(CN), nullptr);
515   EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(MB), nullptr);
516   EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(CB), nullptr);
517   EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(MD), &D);
518   EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(CD), &D);
519 }
520 
521 } // end namespace pointer_wrappers
522 } // end namespace
523