Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / Support / Casting.cpp
bloba128cedaf3988d5895230978199c37e9506dbcd2
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 //===----------------------------------------------------------------------===//
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>
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; }
22 // set up two example classes
23 // with conversion facility
25 struct bar {
26 bar() {}
27 struct foo *baz();
28 struct foo *caz();
29 struct foo *daz();
30 struct foo *naz();
32 private:
33 bar(const bar &);
35 struct foo {
36 foo(const bar &) {}
37 void ext() const;
40 struct base {
41 virtual ~base() {}
44 struct derived : public base {
45 static bool classof(const base *B) { return true; }
48 struct derived_nocast : public base {
49 static bool classof(const base *B) { return false; }
52 template <> struct isa_impl<foo, bar> {
53 static inline bool doit(const bar &Val) {
54 dbgs() << "Classof: " << &Val << "\n";
55 return true;
59 // Note for the future - please don't do this. isa_impl is an internal template
60 // for the implementation of `isa` and should not be exposed this way.
61 // Completely unrelated types *should* result in compiler errors if you try to
62 // cast between them.
63 template <typename T> struct isa_impl<foo, T> {
64 static inline bool doit(const T &Val) { return false; }
67 foo *bar::baz() { return cast<foo>(this); }
69 foo *bar::caz() { return cast_or_null<foo>(this); }
71 foo *bar::daz() { return dyn_cast<foo>(this); }
73 foo *bar::naz() { return dyn_cast_or_null<foo>(this); }
75 bar *fub();
77 template <> struct simplify_type<foo> {
78 typedef int SimpleType;
79 static SimpleType getSimplifiedValue(foo &Val) { return 0; }
82 struct T1 {};
84 struct T2 {
85 T2(const T1 &x) {}
86 static bool classof(const T1 *x) { return true; }
89 template <> struct CastInfo<T2, T1> : public OptionalValueCast<T2, T1> {};
91 struct T3 {
92 T3(const T1 *x) : hasValue(x != nullptr) {}
94 static bool classof(const T1 *x) { return true; }
95 bool hasValue = false;
98 // T3 is convertible from a pointer to T1.
99 template <> struct CastInfo<T3, T1 *> : public ValueFromPointerCast<T3, T1> {};
101 struct T4 {
102 T4() : hasValue(false) {}
103 T4(const T3 &x) : hasValue(true) {}
105 static bool classof(const T3 *x) { return true; }
106 bool hasValue = false;
109 template <> struct ValueIsPresent<T3> {
110 using UnwrappedType = T3;
111 static inline bool isPresent(const T3 &t) { return t.hasValue; }
112 static inline const T3 &unwrapValue(const T3 &t) { return t; }
115 template <> struct CastInfo<T4, T3> {
116 using CastResultType = T4;
117 static inline CastResultType doCast(const T3 &t) { return T4(t); }
118 static inline CastResultType castFailed() { return CastResultType(); }
119 static inline CastResultType doCastIfPossible(const T3 &f) {
120 return doCast(f);
124 } // namespace llvm
126 using namespace llvm;
128 // Test the peculiar behavior of Use in simplify_type.
129 static_assert(std::is_same_v<simplify_type<Use>::SimpleType, Value *>,
130 "Use doesn't simplify correctly!");
131 static_assert(std::is_same_v<simplify_type<Use *>::SimpleType, Value *>,
132 "Use doesn't simplify correctly!");
134 // Test that a regular class behaves as expected.
135 static_assert(std::is_same_v<simplify_type<foo>::SimpleType, int>,
136 "Unexpected simplify_type result!");
137 static_assert(std::is_same_v<simplify_type<foo *>::SimpleType, foo *>,
138 "Unexpected simplify_type result!");
140 namespace {
142 const foo *null_foo = nullptr;
144 bar B;
145 extern bar &B1;
146 bar &B1 = B;
147 extern const bar *B2;
148 // test various configurations of const
149 const bar &B3 = B1;
150 const bar *const B4 = B2;
152 TEST(CastingTest, isa) {
153 EXPECT_TRUE(isa<foo>(B1));
154 EXPECT_TRUE(isa<foo>(B2));
155 EXPECT_TRUE(isa<foo>(B3));
156 EXPECT_TRUE(isa<foo>(B4));
159 TEST(CastingTest, isa_and_nonnull) {
160 EXPECT_TRUE(isa_and_nonnull<foo>(B2));
161 EXPECT_TRUE(isa_and_nonnull<foo>(B4));
162 EXPECT_FALSE(isa_and_nonnull<foo>(fub()));
165 TEST(CastingTest, cast) {
166 foo &F1 = cast<foo>(B1);
167 EXPECT_NE(&F1, null_foo);
168 const foo *F3 = cast<foo>(B2);
169 EXPECT_NE(F3, null_foo);
170 const foo *F4 = cast<foo>(B2);
171 EXPECT_NE(F4, null_foo);
172 const foo &F5 = cast<foo>(B3);
173 EXPECT_NE(&F5, null_foo);
174 const foo *F6 = cast<foo>(B4);
175 EXPECT_NE(F6, null_foo);
176 // Can't pass null pointer to cast<>.
177 // foo *F7 = cast<foo>(fub());
178 // EXPECT_EQ(F7, null_foo);
179 foo *F8 = B1.baz();
180 EXPECT_NE(F8, null_foo);
182 std::unique_ptr<const bar> BP(B2);
183 auto FP = cast<foo>(std::move(BP));
184 static_assert(std::is_same_v<std::unique_ptr<const foo>, decltype(FP)>,
185 "Incorrect deduced return type!");
186 EXPECT_NE(FP.get(), null_foo);
187 FP.release();
190 TEST(CastingTest, cast_or_null) {
191 const foo *F11 = cast_or_null<foo>(B2);
192 EXPECT_NE(F11, null_foo);
193 const foo *F12 = cast_or_null<foo>(B2);
194 EXPECT_NE(F12, null_foo);
195 const foo *F13 = cast_or_null<foo>(B4);
196 EXPECT_NE(F13, null_foo);
197 const foo *F14 = cast_or_null<foo>(fub()); // Shouldn't print.
198 EXPECT_EQ(F14, null_foo);
199 foo *F15 = B1.caz();
200 EXPECT_NE(F15, null_foo);
202 std::unique_ptr<const bar> BP(fub());
203 auto FP = cast_or_null<foo>(std::move(BP));
204 EXPECT_EQ(FP.get(), null_foo);
207 TEST(CastingTest, dyn_cast) {
208 const foo *F1 = dyn_cast<foo>(B2);
209 EXPECT_NE(F1, null_foo);
210 const foo *F2 = dyn_cast<foo>(B2);
211 EXPECT_NE(F2, null_foo);
212 const foo *F3 = dyn_cast<foo>(B4);
213 EXPECT_NE(F3, null_foo);
214 // Can't pass null pointer to dyn_cast<>.
215 // foo *F4 = dyn_cast<foo>(fub());
216 // EXPECT_EQ(F4, null_foo);
217 foo *F5 = B1.daz();
218 EXPECT_NE(F5, null_foo);
220 auto BP = std::make_unique<const bar>();
221 auto FP = dyn_cast<foo>(BP);
222 static_assert(std::is_same_v<std::unique_ptr<const foo>, decltype(FP)>,
223 "Incorrect deduced return type!");
224 EXPECT_NE(FP.get(), nullptr);
225 EXPECT_EQ(BP.get(), nullptr);
227 auto BP2 = std::make_unique<base>();
228 auto DP = dyn_cast<derived_nocast>(BP2);
229 EXPECT_EQ(DP.get(), nullptr);
230 EXPECT_NE(BP2.get(), nullptr);
233 // All these tests forward to dyn_cast_if_present, so they also provde an
234 // effective test for its use cases.
235 TEST(CastingTest, dyn_cast_or_null) {
236 const foo *F1 = dyn_cast_or_null<foo>(B2);
237 EXPECT_NE(F1, null_foo);
238 const foo *F2 = dyn_cast_or_null<foo>(B2);
239 EXPECT_NE(F2, null_foo);
240 const foo *F3 = dyn_cast_or_null<foo>(B4);
241 EXPECT_NE(F3, null_foo);
242 foo *F4 = dyn_cast_or_null<foo>(fub());
243 EXPECT_EQ(F4, null_foo);
244 foo *F5 = B1.naz();
245 EXPECT_NE(F5, null_foo);
246 // dyn_cast_if_present should have exactly the same behavior as
247 // dyn_cast_or_null.
248 const foo *F6 = dyn_cast_if_present<foo>(B2);
249 EXPECT_EQ(F6, F2);
252 TEST(CastingTest, dyn_cast_value_types) {
253 T1 t1;
254 std::optional<T2> t2 = dyn_cast<T2>(t1);
255 EXPECT_TRUE(t2);
257 T2 *t2ptr = dyn_cast<T2>(&t1);
258 EXPECT_TRUE(t2ptr != nullptr);
260 T3 t3 = dyn_cast<T3>(&t1);
261 EXPECT_TRUE(t3.hasValue);
264 TEST(CastingTest, dyn_cast_if_present) {
265 std::optional<T1> empty{};
266 std::optional<T2> F1 = dyn_cast_if_present<T2>(empty);
267 EXPECT_FALSE(F1.has_value());
269 T1 t1;
270 std::optional<T2> F2 = dyn_cast_if_present<T2>(t1);
271 EXPECT_TRUE(F2.has_value());
273 T1 *t1Null = nullptr;
275 // T3 should have hasValue == false because t1Null is nullptr.
276 T3 t3 = dyn_cast_if_present<T3>(t1Null);
277 EXPECT_FALSE(t3.hasValue);
279 // Now because of that, T4 should receive the castFailed implementation of its
280 // FallibleCastTraits, which default-constructs a T4, which has no value.
281 T4 t4 = dyn_cast_if_present<T4>(t3);
282 EXPECT_FALSE(t4.hasValue);
285 TEST(CastingTest, isa_check_predicates) {
286 auto IsaFoo = IsaPred<foo>;
287 EXPECT_TRUE(IsaFoo(B1));
288 EXPECT_TRUE(IsaFoo(B2));
289 EXPECT_TRUE(IsaFoo(B3));
290 EXPECT_TRUE(IsaPred<foo>(B4));
291 EXPECT_TRUE((IsaPred<foo, bar>(B4)));
293 auto IsaAndPresentFoo = IsaAndPresentPred<foo>;
294 EXPECT_TRUE(IsaAndPresentFoo(B2));
295 EXPECT_TRUE(IsaAndPresentFoo(B4));
296 EXPECT_FALSE(IsaAndPresentPred<foo>(fub()));
297 EXPECT_FALSE((IsaAndPresentPred<foo, bar>(fub())));
300 std::unique_ptr<derived> newd() { return std::make_unique<derived>(); }
301 std::unique_ptr<base> newb() { return std::make_unique<derived>(); }
303 TEST(CastingTest, unique_dyn_cast) {
304 derived *OrigD = nullptr;
305 auto D = std::make_unique<derived>();
306 OrigD = D.get();
308 // Converting from D to itself is valid, it should return a new unique_ptr
309 // and the old one should become nullptr.
310 auto NewD = unique_dyn_cast<derived>(D);
311 ASSERT_EQ(OrigD, NewD.get());
312 ASSERT_EQ(nullptr, D);
314 // Converting from D to B is valid, B should have a value and D should be
315 // nullptr.
316 auto B = unique_dyn_cast<base>(NewD);
317 ASSERT_EQ(OrigD, B.get());
318 ASSERT_EQ(nullptr, NewD);
320 // Converting from B to itself is valid, it should return a new unique_ptr
321 // and the old one should become nullptr.
322 auto NewB = unique_dyn_cast<base>(B);
323 ASSERT_EQ(OrigD, NewB.get());
324 ASSERT_EQ(nullptr, B);
326 // Converting from B to D is valid, D should have a value and B should be
327 // nullptr;
328 D = unique_dyn_cast<derived>(NewB);
329 ASSERT_EQ(OrigD, D.get());
330 ASSERT_EQ(nullptr, NewB);
332 // This is a very contrived test, casting between completely unrelated types
333 // should generally fail to compile. See the classof shenanigans we have in
334 // the definition of `foo` above.
335 auto F = unique_dyn_cast<foo>(D);
336 ASSERT_EQ(nullptr, F);
337 ASSERT_EQ(OrigD, D.get());
339 // All of the above should also hold for temporaries.
340 auto D2 = unique_dyn_cast<derived>(newd());
341 EXPECT_NE(nullptr, D2);
343 auto B2 = unique_dyn_cast<derived>(newb());
344 EXPECT_NE(nullptr, B2);
346 auto B3 = unique_dyn_cast<base>(newb());
347 EXPECT_NE(nullptr, B3);
349 // This is a very contrived test, casting between completely unrelated types
350 // should generally fail to compile. See the classof shenanigans we have in
351 // the definition of `foo` above.
352 auto F2 = unique_dyn_cast<foo>(newb());
353 EXPECT_EQ(nullptr, F2);
356 // These lines are errors...
357 // foo *F20 = cast<foo>(B2); // Yields const foo*
358 // foo &F21 = cast<foo>(B3); // Yields const foo&
359 // foo *F22 = cast<foo>(B4); // Yields const foo*
360 // foo &F23 = cast_or_null<foo>(B1);
361 // const foo &F24 = cast_or_null<foo>(B3);
363 const bar *B2 = &B;
364 } // anonymous namespace
366 bar *llvm::fub() { return nullptr; }
368 namespace {
369 namespace inferred_upcasting {
370 // This test case verifies correct behavior of inferred upcasts when the
371 // types are statically known to be OK to upcast. This is the case when,
372 // for example, Derived inherits from Base, and we do `isa<Base>(Derived)`.
374 // Note: This test will actually fail to compile without inferred
375 // upcasting.
377 class Base {
378 public:
379 // No classof. We are testing that the upcast is inferred.
380 Base() {}
383 class Derived : public Base {
384 public:
385 Derived() {}
388 // Even with no explicit classof() in Base, we should still be able to cast
389 // Derived to its base class.
390 TEST(CastingTest, UpcastIsInferred) {
391 Derived D;
392 EXPECT_TRUE(isa<Base>(D));
393 Base *BP = dyn_cast<Base>(&D);
394 EXPECT_NE(BP, nullptr);
397 // This test verifies that the inferred upcast takes precedence over an
398 // explicitly written one. This is important because it verifies that the
399 // dynamic check gets optimized away.
400 class UseInferredUpcast {
401 public:
402 int Dummy;
403 static bool classof(const UseInferredUpcast *) { return false; }
406 TEST(CastingTest, InferredUpcastTakesPrecedence) {
407 UseInferredUpcast UIU;
408 // Since the explicit classof() returns false, this will fail if the
409 // explicit one is used.
410 EXPECT_TRUE(isa<UseInferredUpcast>(&UIU));
413 } // end namespace inferred_upcasting
414 } // end anonymous namespace
416 namespace {
417 namespace pointer_wrappers {
419 struct Base {
420 bool IsDerived;
421 Base(bool IsDerived = false) : IsDerived(IsDerived) {}
424 struct Derived : Base {
425 Derived() : Base(true) {}
426 static bool classof(const Base *B) { return B->IsDerived; }
429 class PTy {
430 Base *B;
432 public:
433 PTy(Base *B) : B(B) {}
434 explicit operator bool() const { return get(); }
435 Base *get() const { return B; }
438 } // end namespace pointer_wrappers
439 } // end namespace
441 namespace llvm {
443 template <> struct ValueIsPresent<pointer_wrappers::PTy> {
444 using UnwrappedType = pointer_wrappers::PTy;
445 static inline bool isPresent(const pointer_wrappers::PTy &P) {
446 return P.get() != nullptr;
448 static UnwrappedType &unwrapValue(pointer_wrappers::PTy &P) { return P; }
451 template <> struct ValueIsPresent<const pointer_wrappers::PTy> {
452 using UnwrappedType = pointer_wrappers::PTy;
453 static inline bool isPresent(const pointer_wrappers::PTy &P) {
454 return P.get() != nullptr;
457 static UnwrappedType &unwrapValue(const pointer_wrappers::PTy &P) {
458 return const_cast<UnwrappedType &>(P);
462 template <> struct simplify_type<pointer_wrappers::PTy> {
463 typedef pointer_wrappers::Base *SimpleType;
464 static SimpleType getSimplifiedValue(pointer_wrappers::PTy &P) {
465 return P.get();
468 template <> struct simplify_type<const pointer_wrappers::PTy> {
469 typedef pointer_wrappers::Base *SimpleType;
470 static SimpleType getSimplifiedValue(const pointer_wrappers::PTy &P) {
471 return P.get();
475 } // end namespace llvm
477 namespace {
478 namespace pointer_wrappers {
480 // Some objects.
481 pointer_wrappers::Base B;
482 pointer_wrappers::Derived D;
484 // Mutable "smart" pointers.
485 pointer_wrappers::PTy MN(nullptr);
486 pointer_wrappers::PTy MB(&B);
487 pointer_wrappers::PTy MD(&D);
489 // Const "smart" pointers.
490 const pointer_wrappers::PTy CN(nullptr);
491 const pointer_wrappers::PTy CB(&B);
492 const pointer_wrappers::PTy CD(&D);
494 TEST(CastingTest, smart_isa) {
495 EXPECT_TRUE(!isa<pointer_wrappers::Derived>(MB));
496 EXPECT_TRUE(!isa<pointer_wrappers::Derived>(CB));
497 EXPECT_TRUE(isa<pointer_wrappers::Derived>(MD));
498 EXPECT_TRUE(isa<pointer_wrappers::Derived>(CD));
501 TEST(CastingTest, smart_cast) {
502 EXPECT_EQ(cast<pointer_wrappers::Derived>(MD), &D);
503 EXPECT_EQ(cast<pointer_wrappers::Derived>(CD), &D);
506 TEST(CastingTest, smart_cast_or_null) {
507 EXPECT_EQ(cast_or_null<pointer_wrappers::Derived>(MN), nullptr);
508 EXPECT_EQ(cast_or_null<pointer_wrappers::Derived>(CN), nullptr);
509 EXPECT_EQ(cast_or_null<pointer_wrappers::Derived>(MD), &D);
510 EXPECT_EQ(cast_or_null<pointer_wrappers::Derived>(CD), &D);
513 TEST(CastingTest, smart_dyn_cast) {
514 EXPECT_EQ(dyn_cast<pointer_wrappers::Derived>(MB), nullptr);
515 EXPECT_EQ(dyn_cast<pointer_wrappers::Derived>(CB), nullptr);
516 EXPECT_EQ(dyn_cast<pointer_wrappers::Derived>(MD), &D);
517 EXPECT_EQ(dyn_cast<pointer_wrappers::Derived>(CD), &D);
520 TEST(CastingTest, smart_dyn_cast_or_null) {
521 EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(MN), nullptr);
522 EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(CN), nullptr);
523 EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(MB), nullptr);
524 EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(CB), nullptr);
525 EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(MD), &D);
526 EXPECT_EQ(dyn_cast_or_null<pointer_wrappers::Derived>(CD), &D);
529 } // end namespace pointer_wrappers
531 #ifndef NDEBUG
532 namespace assertion_checks {
533 struct Base {
534 virtual ~Base() {}
537 struct Derived : public Base {
538 static bool classof(const Base *B) { return false; }
541 TEST(CastingTest, assertion_check_const_ref) {
542 const Base B;
543 EXPECT_DEATH((void)cast<Derived>(B), "argument of incompatible type")
544 << "Invalid cast of const ref did not cause an abort()";
547 TEST(CastingTest, assertion_check_ref) {
548 Base B;
549 EXPECT_DEATH((void)cast<Derived>(B), "argument of incompatible type")
550 << "Invalid cast of const ref did not cause an abort()";
553 TEST(CastingTest, assertion_check_ptr) {
554 Base B;
555 EXPECT_DEATH((void)cast<Derived>(&B), "argument of incompatible type")
556 << "Invalid cast of const ref did not cause an abort()";
559 TEST(CastingTest, assertion_check_unique_ptr) {
560 auto B = std::make_unique<Base>();
561 EXPECT_DEATH((void)cast<Derived>(std::move(B)),
562 "argument of incompatible type")
563 << "Invalid cast of const ref did not cause an abort()";
566 } // end namespace assertion_checks
567 #endif
568 } // end namespace