[llvm] 0809f63 - [LLVM][Casting.h] Add trivial self-cast
via llvm-commits
llvm-commits at lists.llvm.org
Sun May 15 22:22:22 PDT 2022
Author: bzcheeseman
Date: 2022-05-15T22:22:16-07:00
New Revision: 0809f63826d36c89574d6ac056ebf46a4b6f29ff
URL: https://github.com/llvm/llvm-project/commit/0809f63826d36c89574d6ac056ebf46a4b6f29ff
DIFF: https://github.com/llvm/llvm-project/commit/0809f63826d36c89574d6ac056ebf46a4b6f29ff.diff
LOG: [LLVM][Casting.h] Add trivial self-cast
Casting from a type to itself should always be possible. Make this simple for all users, and add tests to ensure we keep being able to do this. Ref: https://reviews.llvm.org/D125543
Reviewed By: rriddle
Differential Revision: https://reviews.llvm.org/D125590
Added:
Modified:
llvm/include/llvm/Support/Casting.h
llvm/unittests/Support/Casting.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/Casting.h b/llvm/include/llvm/Support/Casting.h
index 37f85da868b2d..4f2f64e865332 100644
--- a/llvm/include/llvm/Support/Casting.h
+++ b/llvm/include/llvm/Support/Casting.h
@@ -192,6 +192,12 @@ template <class To, class From> struct cast_retty {
To, From, typename simplify_type<From>::SimpleType>::ret_type;
};
+template <class T> struct cast_retty<T, T> {
+ // Casting T to itself, but have to use a ref if so we don't get a copy if
+ // it's not a pointer.
+ using ret_type = std::conditional_t<std::is_pointer<T>::value, T, T &>;
+};
+
//===----------------------------------------------------------------------===//
// cast_convert_val
//===----------------------------------------------------------------------===//
@@ -276,7 +282,8 @@ struct CastIsPossible<To, Optional<From>> {
/// always be possible.
template <typename To, typename From>
struct CastIsPossible<To, From,
- std::enable_if_t<std::is_base_of<To, From>::value>> {
+ std::enable_if_t<std::is_same<To, From>::value ||
+ std::is_base_of<To, From>::value>> {
static inline bool isPossible(const From &f) { return true; }
};
diff --git a/llvm/unittests/Support/Casting.cpp b/llvm/unittests/Support/Casting.cpp
index 086548f1e2128..925e9eed47d40 100644
--- a/llvm/unittests/Support/Casting.cpp
+++ b/llvm/unittests/Support/Casting.cpp
@@ -144,6 +144,7 @@ extern const bar *B2;
// test various configurations of const
const bar &B3 = B1;
const bar *const B4 = B2;
+bar *B5 = &B;
TEST(CastingTest, isa) {
EXPECT_TRUE(isa<foo>(B1));
@@ -175,6 +176,17 @@ TEST(CastingTest, cast) {
foo *F8 = B1.baz();
EXPECT_NE(F8, null_foo);
+ // Ensure cast-to-self works (with the type in the template verbatim
+ // equivalent to the type in the input).
+ auto B9 = cast<bar *>(B5);
+ static_assert(std::is_same<bar *, decltype(B9)>::value,
+ "Inccorrect return type!");
+ EXPECT_EQ(B9, B5);
+ auto B10 = cast<const bar *>(B2);
+ static_assert(std::is_same<const bar *, decltype(B10)>::value,
+ "Inccorrect return type!");
+ EXPECT_EQ(B10, B2);
+
std::unique_ptr<const bar> BP(B2);
auto FP = cast<foo>(std::move(BP));
static_assert(std::is_same<std::unique_ptr<const foo>, decltype(FP)>::value,
@@ -212,6 +224,17 @@ TEST(CastingTest, dyn_cast) {
// EXPECT_EQ(F4, null_foo);
foo *F5 = B1.daz();
EXPECT_NE(F5, null_foo);
+
+ // Ensure cast-to-self works (with the type in the template verbatim
+ // equivalent to the type in the input).
+ auto B9 = dyn_cast<bar *>(B5);
+ static_assert(std::is_same<bar *, decltype(B9)>::value,
+ "Inccorrect return type!");
+ EXPECT_EQ(B9, B5);
+ auto B10 = dyn_cast<const bar *>(B2);
+ static_assert(std::is_same<const bar *, decltype(B10)>::value,
+ "Inccorrect return type!");
+ EXPECT_EQ(B10, B2);
}
// All these tests forward to dyn_cast_if_present, so they also provde an
More information about the llvm-commits
mailing list